Browse Source

Merge branch 'dev' into auto-merge/rel-5-0/760

pull/11169/head
maliming 4 years ago
committed by GitHub
parent
commit
fdaa3609c1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 137
      .editorconfig
  2. 2
      .gitignore
  3. 6
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en-GB.json
  4. 7
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  5. 6
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
  6. 11
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
  7. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
  8. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de-DE.json
  9. 8
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json
  10. 32
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  11. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
  12. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
  13. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
  14. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
  15. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
  16. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
  17. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
  18. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
  19. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
  20. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
  21. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
  22. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ru.json
  23. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
  24. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
  25. 19
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  26. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
  27. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
  28. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
  29. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
  30. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json
  31. 5
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
  32. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
  33. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
  34. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
  35. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
  36. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
  37. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
  38. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
  39. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
  40. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
  41. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
  42. 4
      codecov.yml
  43. 2
      common.props
  44. 18
      docs/en/Blog-Posts/2021-11-18 v5_0_Preview/POST.md
  45. BIN
      docs/en/Blog-Posts/2021-11-18 v5_0_Preview/community-talks.png
  46. BIN
      docs/en/Blog-Posts/2021-11-18 v5_0_Preview/cover-50.png
  47. 47
      docs/en/Blog-Posts/2021-12-15 v5_0_Release_Stable/POST.md
  48. BIN
      docs/en/Blog-Posts/2021-12-15 v5_0_Release_Stable/community-talks.png
  49. 12
      docs/en/CLI.md
  50. 17
      docs/en/Community-Articles/2021-06-17-Using-Elsa-Workflow-with-ABP-Framework/POST.md
  51. 1671
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md
  52. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-contracts-folder-structure.png
  53. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-final-demo.gif
  54. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-folder-structure.png
  55. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-create.gif
  56. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-creation-modal.png
  57. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-update-modal.png
  58. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/demo.png
  59. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-file-structure.png
  60. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-shared-file-structure.png
  61. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/er-diagram.png
  62. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/web-folder-structure.png
  63. 321
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/POST.md
  64. BIN
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/calendar-component.png
  65. BIN
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/component-folder-structure.png
  66. BIN
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/copy-license-key.png
  67. BIN
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/manage-trial-1.png
  68. BIN
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/manage-trial-2.png
  69. BIN
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/syncfusion-libs.png
  70. BIN
      docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/syncfusion-package.png
  71. 2
      docs/en/Customizing-Application-Modules-Extending-Entities.md
  72. 2
      docs/en/Getting-Started-Running-Solution.md
  73. 2
      docs/en/Getting-Started.md
  74. 45
      docs/en/Tutorials/Part-1.md
  75. 106
      docs/en/Tutorials/Part-2.md
  76. 4
      docs/en/Tutorials/Part-5.md
  77. 74
      docs/en/Tutorials/Todo/Index.md
  78. 2
      docs/en/Virtual-File-System.md
  79. 1
      docs/zh-Hans/Background-Workers.md
  80. 11
      docs/zh-Hans/CLI.md
  81. 98
      docs/zh-Hans/Getting-Started-AspNetCore-Application.md
  82. 73
      docs/zh-Hans/Getting-Started-Create-Solution.md
  83. 199
      docs/zh-Hans/Getting-Started-Running-Solution.md
  84. 53
      docs/zh-Hans/Getting-Started-Setup-Environment.md
  85. 370
      docs/zh-Hans/Getting-Started.md
  86. 310
      docs/zh-Hans/Modules/Identity.md
  87. 174
      docs/zh-Hans/Modules/IdentityServer.md
  88. 123
      docs/zh-Hans/Tutorials/Part-1.md
  89. 254
      docs/zh-Hans/Tutorials/Part-2.md
  90. 600
      docs/zh-Hans/Tutorials/Part-3.md
  91. 60
      docs/zh-Hans/Tutorials/Part-4.md
  92. 636
      docs/zh-Hans/Tutorials/Part-5.md
  93. 279
      docs/zh-Hans/Tutorials/Part-6.md
  94. 239
      docs/zh-Hans/Tutorials/Part-7.md
  95. BIN
      docs/zh-Hans/Tutorials/images/blazor-add-book-button.png
  96. BIN
      docs/zh-Hans/Tutorials/images/blazor-add-books-component.png
  97. BIN
      docs/zh-Hans/Tutorials/images/blazor-bookstore-book-list.png
  98. BIN
      docs/zh-Hans/Tutorials/images/blazor-delete-book-action.png
  99. BIN
      docs/zh-Hans/Tutorials/images/blazor-edit-book-action-2.png
  100. BIN
      docs/zh-Hans/Tutorials/images/blazor-edit-book-modal.png

137
.editorconfig

@ -0,0 +1,137 @@
# EditorConfig is awesome: https://EditorConfig.org
# Please feel free to update it (by considering the code style of ABP Team).
# top-most EditorConfig file
root = true
[*.cs]
#Namespace settings
csharp_style_namespace_declarations = file_scoped
dotnet_diagnostic.IDE0161.severity = warning
#Core editorconfig formatting - indentation
#use tabs for indentation
indent_style = tabs
#Formatting - indentation options
#indent switch case contents.
csharp_indent_case_contents = true
#indent switch labels
csharp_indent_switch_labels = true
#Formatting - new line options
#place catch statements on a new line
csharp_new_line_before_catch = true
#place else statements on a new line
csharp_new_line_before_else = true
#require members of object intializers to be on separate lines
csharp_new_line_before_members_in_object_initializers = true
#require braces to be on a new line for object_collection_array_initializers, methods, control_blocks, types, and lambdas (also known as "Allman" style)
csharp_new_line_before_open_brace = object_collection_array_initializers, methods, control_blocks, types, lambdas
#Formatting - organize using options
#sort System.* using directives alphabetically, and place them before other usings
dotnet_sort_system_directives_first = true
#Formatting - spacing options
#require NO space between a cast and the value
csharp_space_after_cast = false
#require a space before the colon for bases or interfaces in a type declaration
csharp_space_after_colon_in_inheritance_clause = true
#require a space after a keyword in a control flow statement such as a for loop
csharp_space_after_keywords_in_control_flow_statements = true
#require a space before the colon for bases or interfaces in a type declaration
csharp_space_before_colon_in_inheritance_clause = true
#remove space within empty argument list parentheses
csharp_space_between_method_call_empty_parameter_list_parentheses = false
#remove space between method call name and opening parenthesis
csharp_space_between_method_call_name_and_opening_parenthesis = false
#do not place space characters after the opening parenthesis and before the closing parenthesis of a method call
csharp_space_between_method_call_parameter_list_parentheses = false
#remove space within empty parameter list parentheses for a method declaration
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list.
csharp_space_between_method_declaration_parameter_list_parentheses = false
#Formatting - wrapping options
#leave code block on single line
csharp_preserve_single_line_blocks = true
#Style - Code block preferences
#prefer curly braces even for one line of code
csharp_prefer_braces = true:suggestion
#Style - expression bodied member options
#prefer block bodies for constructors
csharp_style_expression_bodied_constructors = false:suggestion
#prefer block bodies for methods
csharp_style_expression_bodied_methods = false:suggestion
#prefer expression-bodied members for properties
csharp_style_expression_bodied_properties = true:suggestion
#Style - expression level options
#prefer out variables to be declared inline in the argument list of a method call when possible
csharp_style_inlined_variable_declaration = true:suggestion
#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_member_access = true:suggestion
#Style - Expression-level preferences
#prefer default over default(T)
csharp_prefer_simple_default_expression = true:suggestion
#prefer objects to be initialized using object initializers when possible
dotnet_style_object_initializer = true:suggestion
#prefer inferred tuple element names
dotnet_style_prefer_inferred_tuple_names = true:suggestion
#Style - implicit and explicit types
#prefer var over explicit type in all cases, unless overridden by another code style rule
csharp_style_var_elsewhere = true:suggestion
#prefer var is used to declare variables with built-in system types such as int
csharp_style_var_for_built_in_types = true:suggestion
#prefer var when the type is already mentioned on the right-hand side of a declaration expression
csharp_style_var_when_type_is_apparent = true:suggestion
#Style - language keyword and framework type options
#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
#Style - Miscellaneous preferences
#prefer local functions over anonymous functions
csharp_style_pattern_local_over_anonymous_function = true:suggestion
#Style - modifier options
#prefer accessibility modifiers to be declared except for public interface members. This will currently not differ from always and will act as future proofing for if C# adds default interface methods.
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
#Style - Modifier preferences
#when this rule is set to a list of modifiers, prefer the specified ordering.
csharp_preferred_modifier_order = public,protected,private,virtual,async,readonly,static,override,abstract:suggestion
#Style - Pattern matching
#prefer pattern matching instead of is expression with type casts
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
#Style - qualification options
#prefer fields not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_field = false:suggestion
#prefer methods not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_method = false:suggestion
#prefer properties not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_property = false:suggestion

2
.gitignore

@ -6,7 +6,7 @@
*.user
*.userosscache
*.sln.docstates
*.editorconfig
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

6
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en-GB.json

@ -210,6 +210,10 @@
"Completed": "Completed",
"Failed": "Failed",
"PaymentRequestDeletionWarningMessage": "This payment request will be deleted. Do you confirm that?",
"Payment": "Payment"
"Payment": "Payment",
"Permission:SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmailWarningMessage": "Are you sure you want to send welcome email to the organization members?",
"SendWelcomeEmailSuccessMessage": "Welcome email sent successfully!"
}
}

7
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -352,6 +352,11 @@
"Volo.AbpIo.Commercial:030008": "Purchase date can be set only when status is Purchased!",
"Volo.AbpIo.Commercial:030009": "User not found!",
"Volo.AbpIo.Commercial:030010": "To purchase the trial license, first you need to activate your trial license!",
"Volo.AbpIo.Commercial:030011": "You cannot delete a trial license when it is purchased!"
"Volo.AbpIo.Commercial:030011": "You cannot delete a trial license when it is purchased!",
"Permission:SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmailWarningMessage": "Are you sure you want to send welcome email to the organization members?",
"SendWelcomeEmailSuccessMessage": "Welcome email sent successfully!",
"PaymentRequestId": "Payment Request Id"
}
}

6
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json

@ -348,6 +348,10 @@
"Volo.AbpIo.Commercial:030008": "Satın alma tarihi yalnızca durum Satın Alındı olduğunda ayarlanabilir!",
"Volo.AbpIo.Commercial:030009": "Kullanıcı bulunamadı!",
"Volo.AbpIo.Commercial:030010": "Deneme lisansını satın almak için önce deneme lisansınızı etkinleştirmeniz gerekir!",
"Volo.AbpIo.Commercial:030011": "Satın alındığında bir deneme lisansını silemezsiniz!"
"Volo.AbpIo.Commercial:030011": "Satın alındığında bir deneme lisansını silemezsiniz!",
"Permission:SendWelcomeEmail": "Hoşgeldin Emaili Gönder",
"SendWelcomeEmail": "Hoşgeldin Emaili Gönder",
"SendWelcomeEmailWarningMessage": "Organizasyon üyelerine hoşgeldin emaili göndermek istediğinden emin misin?",
"SendWelcomeEmailSuccessMessage": "Hoşgeldin emaili başarıyla gönderilmiştir!"
}
}

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."
}
}

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

@ -102,6 +102,12 @@
"InvalidFormInputs": "Please, type the valid information specified on the form.",
"DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>.",
"FreeDDDEBook": "Free DDD E-Book",
"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>.",
"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",
"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."
}
}

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

@ -172,15 +172,15 @@
"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.",
"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.",
"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?\"",
"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.<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. 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": "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 available 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.",
"IsSourceCodeIncluded": "Does my license include the source code of the commercial modules and themes?",
@ -191,20 +191,19 @@
"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.",
"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;",
"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 update and support plan out of the box. To continue to get new features, performance enhancements, bug fixes, support and continue to use 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 to develop your existing applications forever.",
"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": "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": "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 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": "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. If you renew your license <strong>1 month</strong> after 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:",
"DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfer.<br />After sending the license fee via bank transfer, email us at accounting@abp.io your receipt and the type of license requested. 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.",
"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.",
@ -390,6 +389,19 @@
"TrialLicenseExpireMessage": "You are using the trial license and your trial license will expire on {0}.",
"TryForFree": "Try For Free",
"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>."
"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> `.",
"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.",
"UserDeveloperDescription": "The 'Developers' can write code in the ABP Commercial projects, download the ABP sample projects, or ask questions on the support website. On the other hand, the 'Developers' cannot manage this organization.",
"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",
"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.",

19
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.",
@ -390,6 +389,10 @@
"TrialLicenseExpireMessage": "Deneme lisansını kullanıyorsunuz ve deneme lisansınızın süresi {0} tarihinde sona erecek.",
"TryForFree": "Ücretsiz deneyin",
"TrialLicenseExpiredInfo": "Deneme lisansınızın süresi doldu!",
"CommercialNewsletterConfirmationMessage": "<a href=\"https://commercial.abp.io/TermsConditions\">Şartlar, Koşullar</a> ve <a href=\"https://commercial.abp.io/Privacy\">Gizlilik politikasını</a> kabul ediyorum."
"CommercialNewsletterConfirmationMessage": "<a href=\"https://commercial.abp.io/TermsConditions\">Şartlar, Koşullar</a> ve <a href=\"https://commercial.abp.io/Privacy\">Gizlilik politikasını</a> kabul ediyorum.",
"RemoveCurrentUserFromOrganizationWarningMessage": "Organizasyondan kendinizi kaldırıyorsunuz. Artık bu organizasyonu yönetemeyeceksiniz, onaylıyor musunuz? ",
"RenewExistingOrganizationOrCreateNewOneMessage": "Aşağıdaki \"Şimdi Uzat\" buton(lar)una tıklayarak organizasyon(lar)ınızın lisansını yenileyebilir ve böylece lisans geçerlilik süresini 1 yıl uzatabilirsiniz. Ödemeye devam ederseniz, yeni bir organizasyonunuz olacak. Yeni bir organizasyonla devam etmek istiyor musunuz? ",
"ExtendNow": "Şimdi Uzat",
"ContinueWithNewOrganization": "Yeni bir organizasyon ile devam et"
}
}

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相關的軟件包.",

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "يجب عليك إدخال 3 أحرف على الأقل!",
"Volo.AbpIo.Domain:060001": "عنوان URL المصدر (\"{ArticleUrl}\") ليس عنوان URL لـ Github",
"Volo.AbpIo.Domain:060002": "محتوى المقالة غير متوفر من مورد Github (\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "لم يتم العثور على محتوى مقال!"
"Volo.AbpIo.Domain:060003": "لم يتم العثور على محتوى مقال!",
"SeeMore": "شاهد المزيد"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Sie müssen mindestens 3 Zeichen eingeben!",
"Volo.AbpIo.Domain:060001": "Quell-URL(\"{ArticleUrl}\") ist keine Github-URL",
"Volo.AbpIo.Domain:060002": "Artikelinhalt ist über die Github(\"{ArticleUrl}\")-Ressource nicht verfügbar.",
"Volo.AbpIo.Domain:060003": "Kein Artikelinhalt gefunden!"
"Volo.AbpIo.Domain:060003": "Kein Artikelinhalt gefunden!",
"SeeMore": "Mehr Sehen"
}
}

5
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json

@ -101,6 +101,7 @@
"ArticleRequestMessageTitle": "<a href=\"https://github.com/abpframework/abp/issues/new\">Open an issue</a> on the GitHub to request an article/tutorial you want to see on this web site.",
"ArticleRequestMessageBody": "Here is the list of the requested articles by the Community. Do you want to write a requested article? Please click on the request and join the discussion.",
"Language": "Language",
"CreateArticleLanguageInfo": "The language in which the article is written"
"CreateArticleLanguageInfo": "Language of the article",
"SeeMore": "See More"
}
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "You must enter at least 3 characters!",
"Volo.AbpIo.Domain:060001": "Source URL(\"{ArticleUrl}\") is not Github URL",
"Volo.AbpIo.Domain:060002": "Article Content is not available from Github(\"{ArticleUrl}\") resource.",
"Volo.AbpIo.Domain:060003": "No article content found!"
"Volo.AbpIo.Domain:060003": "No article content found!",
"SeeMore": "See More"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "¡Debes ingresar al menos 3 caracteres!",
"Volo.AbpIo.Domain:060001": "La URL de origen (\"{ArticleUrl}\") no es la URL de Github",
"Volo.AbpIo.Domain:060002": "El contenido del artículo no está disponible en el recurso de Github (\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "¡No se encontró contenido del artículo!"
"Volo.AbpIo.Domain:060003": "¡No se encontró contenido del artículo!",
"SeeMore": "Ver Más"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Sinun on annettava vähintään 3 merkkiä!",
"Volo.AbpIo.Domain:060001": "Lähteen URL-osoite (\"{ArticleUrl}\") ei ole Githubin URL-osoite",
"Volo.AbpIo.Domain:060002": "Artikkelin sisältö ei ole saatavilla Githubin (\"{ArticleUrl}\") -resurssista.",
"Volo.AbpIo.Domain:060003": "Artikkelin sisältöä ei löytynyt!"
"Volo.AbpIo.Domain:060003": "Artikkelin sisältöä ei löytynyt!",
"SeeMore": "Katso Lisää"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Vous devez saisir au moins 3 caractères!",
"Volo.AbpIo.Domain:060001": "L'URL source (\"{ArticleUrl}\") n'est pas une URL Github",
"Volo.AbpIo.Domain:060002": "Le contenu de l'article n'est pas disponible à partir de la ressource Github(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Aucun contenu d'article trouvé !"
"Volo.AbpIo.Domain:060003": "Aucun contenu d'article trouvé !",
"SeeMore": "Voir Plus"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "आपको कम से कम 3 वर्ण दर्ज करने होंगे!",
"Volo.AbpIo.Domain:060001": "स्रोत URL (\"{ArticleUrl}\") जीथब URL नहीं है",
"Volo.AbpIo.Domain:060002": "लेख सामग्री Github (\"{ArticleUrl}\") संसाधन से उपलब्ध नहीं है।",
"Volo.AbpIo.Domain:060003": "कोई लेख सामग्री नहीं मिली!"
"Volo.AbpIo.Domain:060003": "कोई लेख सामग्री नहीं मिली!",
"SeeMore": "और देखें"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Þú verður að slá inn að minnsta kosti 3 stafi!",
"Volo.AbpIo.Domain:060001": "Upprunaslóð (\"{ArticleUrl} \") er ekki Github slóð",
"Volo.AbpIo.Domain:060002": "Innihald greinar er ekki fáanlegt frá Github (\"{ArticleUrl} \") resoursum.",
"Volo.AbpIo.Domain:060003": "Innihald greinar fannst ekki!"
"Volo.AbpIo.Domain:060003": "Innihald greinar fannst ekki!",
"SeeMore": "Sjá Meira"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Devi inserire almeno 3 caratteri!",
"Volo.AbpIo.Domain:060001": "Source URL(\"{ArticleUrl}\") non è un URL di GitHub",
"Volo.AbpIo.Domain:060002": "Il contenuto dell'articolo non è disponibile dalla risorsa Github(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Nessun contenuto dell'articolo trovato!"
"Volo.AbpIo.Domain:060003": "Nessun contenuto dell'articolo trovato!",
"SeeMore": "Vedi Altro"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Trebuie să introduceţi cel putin 3 caractere!",
"Volo.AbpIo.Domain:060001": "Sursa URL(\"{ArticleUrl}\") nu este URL GitHub",
"Volo.AbpIo.Domain:060002": "Conţinutul articolului nu este disponibil din resursa de pe GitHub(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Nu a fost găsit conţinutul articolului!"
"Volo.AbpIo.Domain:060003": "Nu a fost găsit conţinutul articolului!",
"SeeMore": "Vezi mai mult"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Musíte zadať aspoň 3 znaky!",
"Volo.AbpIo.Domain:060001": "Zdrojová URL(\"{ArticleUrl}\") nie je URL Githubu",
"Volo.AbpIo.Domain:060002": "Obsah článku nie je dostupný v Github zdroji(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Nenašiel sa žiadny obsah článku!"
"Volo.AbpIo.Domain:060003": "Nenašiel sa žiadny obsah článku!",
"SeeMore": "Vidět Víc"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "您必须输入至少 3 个字符!",
"Volo.AbpIo.Domain:060001": "源 URL(\"{ArticleUrl}\") 不是 Github URL",
"Volo.AbpIo.Domain:060002": "文章内容无法从 Github(\"{ArticleUrl}\") 资源中获得。",
"Volo.AbpIo.Domain:060003": "没有找到文章内容!"
"Volo.AbpIo.Domain:060003": "没有找到文章内容!",
"SeeMore": "查看更多"
}
}

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.1</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>

18
docs/en/Blog-Posts/2021-11-18 v5_0_Preview/POST.md

@ -127,13 +127,7 @@ First of all, you need to have EF Core or MongoDB installed into your solution.
#### Install the packages
Install the new [Volo.Abp.EventBus.Boxes](https://www.nuget.org/packages/Volo.Abp.EventBus.Boxes) NuGet package to your database layer (to `EntityFrameworkCore` or `MongoDB` project) or to the host application. Open a command-line terminal at the root directory of your database (or host) project and execute the following command:
````csharp
abp add-package Volo.Abp.EventBus.Boxes
````
This will install the package and setup the ABP module dependency. This package depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations), including Redis, SqlServer and ZooKeeper. You can use the one you like. Here, I will show the Redis provider.
For the outbox & inbox functionality, ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations), including Redis, SqlServer and ZooKeeper. You can use the one you like. Here, I will show the Redis provider.
Add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class:
@ -285,6 +279,16 @@ This can be a breaking change in rare cases (for example, if you create host sid
## Community News
### ABP Community Talks 2021.12
![community-talks](community-talks.png)
As the core ABP development team, we've decided to organize monthly live meetings with the ABP community. The first live meeting will be at **December 16, 2021, 17:00 (UTC)** on YouTube. ABP core team members will present some of the new features coming with ABP 5.0.
**Join this event on the Kommunity platform: https://kommunity.com/volosoft/events/abp-community-talks-4afca9c9**
You can also [subscribe to the Volosoft channel](https://www.youtube.com/channel/UCO3XKlpvq8CA5MQNVS6b3dQ) for reminders for further ABP events and videos.
### ABP was on ASP.NET Community Startup!
It was great for us to be invited to Microsoft's [ASP.NET Community Weekly Standup](https://dotnet.microsoft.com/live/community-standup) show, at September 28. There was a very high attention and that made us very happy. Thanks to the ABP Community and all the watchers :) If you've missed the talk, [you can watch it here](https://www.youtube.com/watch?v=vMWM-_ihjwM).

BIN
docs/en/Blog-Posts/2021-11-18 v5_0_Preview/community-talks.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 KiB

BIN
docs/en/Blog-Posts/2021-11-18 v5_0_Preview/cover-50.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

47
docs/en/Blog-Posts/2021-12-15 v5_0_Release_Stable/POST.md

@ -0,0 +1,47 @@
# ABP.IO Platform 5.0 Final Has Been Released!
[ABP Framework](https://abp.io/) and [ABP Commercial](https://commercial.abp.io/) 5.0 versions have been released today.
## What's new with 5.0?
Since all the new features are already explained in details with the [5.0 RC.1 Announcement Post](https://blog.abp.io/abp/ABP-IO-Platform-5.0-RC-1-Has-Been-Released), I will not repeat all the details again. See the [RC Blog Post](https://blog.abp.io/abp/ABP-IO-Platform-5.0-RC-1-Has-Been-Released) for all the features and enhancements.
## Getting started with 5.0
### Creating new solutions
You can create a new solution with the ABP Framework version 5.0 by either using the `abp new` command or using the **direct download** tab on the [get started page](https://abp.io/get-started).
Type the following command in a command-line terminal to install the ABP CLI version 5.0:
````bash
dotnet tool install -g Volo.Abp.Cli --version 5.0.0
````
To upgrade your existing ABP CLI installation:
````bash
dotnet tool update -g Volo.Abp.Cli --version 5.0.0
````
Then you can create a new solution using the `abp new` command:
````bash
abp new Acme.BookStore
````
> See the [getting started document](https://docs.abp.io/en/abp/latest/Getting-Started) for details.
### Upgrading existing solutions
Check [the migration guide](https://docs.abp.io/en/abp/latest/Migration-Guides/Abp-5_0) for the applications with the version 4.x upgrading to the version 5.0. Also see [the upgrading guide](https://docs.abp.io/en/abp/latest/Upgrading) to understand how to update existing solutions.
## ABP Community Talks 2021.12
![community-talks](community-talks.png)
As the core ABP development team, we've decided to organize monthly live meetings with the ABP community. The first live meeting will be at **December 16, 2021, 17:00 (UTC)** on YouTube. ABP core team members will present some of the new features coming with ABP 5.0.
**Join this event on the Kommunity platform: https://kommunity.com/volosoft/events/abp-community-talks-4afca9c9**
See you in the event!

BIN
docs/en/Blog-Posts/2021-12-15 v5_0_Release_Stable/community-talks.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 KiB

12
docs/en/CLI.md

@ -29,6 +29,7 @@ Here, the list of all available commands before explaining their details:
* **`help`**: Shows help on the usage of the ABP CLI.
* **`new`**: Generates a new solution based on the ABP [startup templates](Startup-Templates/Index.md).
* **`update`**: Automatically updates all ABP related NuGet and NPM packages in a solution.
* **`clean`**: Deletes all `BIN` and `OBJ` folders in the current folder.
* **`add-package`**: Adds an ABP package to a project.
* **`add-module`**: Adds a [multi-package application module](https://docs.abp.io/en/abp/latest/Modules/Index) to a solution.
* **`list-modules`**: Lists names of open-source application modules.
@ -145,6 +146,17 @@ abp update [options]
* `--check-all`: Check the new version of each package separately. Default is `false`.
* `--version` or `-v`: Specifies the version to use for update. If not specified, latest version is used.
### clean
Deletes all `BIN` and `OBJ` folders in the current folder.
Usage:
````bash
abp clean
````
### add-package
Adds an ABP package to a project by,

17
docs/en/Community-Articles/2021-06-17-Using-Elsa-Workflow-with-ABP-Framework/POST.md

@ -241,8 +241,9 @@ private void ConfigureElsa(ServiceConfigurationContext context, IConfiguration c
.WithExposedHeaders("Content-Disposition"))
);
//register controllers inside elsa
context.Services.AddAssemblyOf<Elsa.Server.Api.Endpoints.WorkflowRegistry.Get>();
//Uncomment the below line if your abp version is lower than v4.4 to register controllers of Elsa .
//See https://github.com/abpframework/abp/pull/9299 (we will no longer need to specify this line of code from v4.4)
// context.Services.AddAssemblyOf<Elsa.Server.Api.Endpoints.WorkflowRegistry.Get>();
//Disable antiforgery validation for elsa
Configure<AbpAntiForgeryOptions>(options =>
@ -269,11 +270,7 @@ public override void OnApplicationInitialization(ApplicationInitializationContex
}
```
* In here we've specified the Elsa Server Api's assembly by using the `AddAssemblyOf<>` extension method to register the required services (controllers). These services required for the dashboard (if we create a workflow by using **Elsa Workflow Designer** it calls some services under the hook, therefore we need to be assured about these services get registered).
* With [v4.4](https://github.com/abpframework/abp/pull/9299), we will no longer need to specify this line of code.
> **Note:** `AddAssemblyOf<>` extension method can help you to register all your services by convention. You can check [here](https://docs.abp.io/en/abp/latest/Dependency-Injection#conventional-registration) for more information about conventional registration.
* These services required for the dashboard.
* We don't need to register our workflows one by one anymore. Because now we use `.AddWorkflowsFrom<Startup>()`, and this registers workflows on our behalf.
@ -371,12 +368,14 @@ namespace ElsaDemo.Permissions
<link rel="icon" type="image/png" sizes="32x32" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-16x16.png">
<link rel="stylesheet" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/styles/tailwind.css">
<link rel="stylesheet" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/elsa-workflows-studio.css">
<script src="/_content/Elsa.Designer.Components.Web/monaco-editor/min/vs/loader.js"></script>
<script type="module" src="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/elsa-workflows-studio.esm.js"></script>
</head>
<body class="h-screen" style="background-size: 30px 30px; background-image: url(/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/tile.png); background-color: #FBFBFB;">
<elsa-studio-root server-url="@serverUrl" monaco-lib-path="_content/Elsa.Designer.Components.Web/monaco-editor/min"></elsa-studio-root>
<elsa-studio-root server-url="@serverUrl" monaco-lib-path="_content/Elsa.Designer.Components.Web/monaco-editor/min">
<elsa-studio-dashboard></elsa-studio-dashboard>
</elsa-studio-root>
</body>
</html>
```

1671
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md

File diff suppressed because it is too large

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-contracts-folder-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-final-demo.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-folder-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-create.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-creation-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-update-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/demo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-file-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-shared-file-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/er-diagram.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/web-folder-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

321
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/POST.md

@ -0,0 +1,321 @@
# Integrating the Syncfusion MVC Components to the ABP MVC UI
## Introduction
In this article we will see how we can integrate the Syncfusion MVC Components into our ABP application.
## Source Code
You can find the source code of the application at https://github.com/EngincanV/ABP-Syncfusion-Components-Demo.
## Prerequisites
* [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)
* In this article, we will create a new startup template in v5.0.0-rc.2 and if you follow this article from top to bottom and create a new startup template with me, you need to install the [.NET 6 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) before starting.
**NOTE:** ABP v5.X stable version has been released. You can replace v5.0.0-rc.2 with the latest stable version in your steps.
Also, you need to update your ABP CLI to the v5.0.0-rc.2, you can use the command below to update your CLI version:
```bash
dotnet tool update Volo.Abp.Cli -g --version 5.0.0-rc.2
```
or install it if you haven't installed it before:
```bash
dotnet tool install Volo.Abp.Cli -g --version 5.0.0-rc.2
```
## Creating the Solution
In this article, we will create a new startup template with EF Core as a database provider and MVC for the UI framework. But if you already have a project with MVC UI, you don't need to create a new startup template, you can directly implement the following steps to your existing project.
> If you already have a project with MVC/Razor Pages UI, you can skip this section.
We can create a new startup template by using the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI):
```bash
abp new SyncfusionComponentsDemo -t app --preview
```
Our project boilerplate will be ready after the download is finished. Then, we can open the solution and start developing.
## Starting the Development
### Pre-requisite
> If you've already had a license from Syncfusion, you can skip this section.
* The first thing we need to do is create an account to be able to get a license from Syncfusion.
* So, let's navigate to https://www.syncfusion.com/aspnet-core-ui-controls and click the "Download Free Trial" button.
* Then fill the form and start your 30-day free trial.
* After that, navigate to https://www.syncfusion.com/account/manage-trials/downloads to get our license key that will be used in our application.
![](./manage-trial-1.png)
Click the "Get License Key" link for "ASP.NET Core (Essential JS 2)".
![](./manage-trial-2.png)
Then a modal will be opened like in the above image, select a version and click the "Get License Key" button.
![](./copy-license-key.png)
Lastly, copy the generated license key value.
In order to use the relevant components, Syncfusion needs to check this license key to know that our license is valid.
### Configurations
After providing a license key from Syncfusion, we can start with the configuration that needs to be done in our application.
#### 1-) Install the Syncfusion.EJ2.AspNet.Core package
We need to install the `Syncfusion.EJ2.AspNet.Core` Nuget package to our Web project (*.Web).
We can install it via **Visual Studio's Nuget Package Manager**:
![](./syncfusion-package.png)
or via dotnet cli:
```bash
dotnet add package Syncfusion.EJ2.AspNet.Core --version 19.3.0.57
```
> In this article, I've used the package in version 19.3.0.57.
#### 2-) Register the License Key
* After installing the package, we need to register our license key to be able to use the Syncfusion Components.
* To register the license key, open your web module class and update the `ConfigureServices` method as follows:
```csharp
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
//Register Syncfusion license
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(licenseKey: configuration["Syncfusion:LicenseKey"].ToString());
ConfigureUrls(configuration);
ConfigureBundles();
ConfigureAuthentication(context, configuration);
ConfigureAutoMapper();
ConfigureVirtualFileSystem(hostingEnvironment);
ConfigureLocalizationServices();
ConfigureNavigationServices();
ConfigureAutoApiControllers();
ConfigureSwaggerServices(context.Services);
}
```
Instead of writing the license key directly in here we can define it in the **appsettings.json** file and use it here by using the Configuration system of .NET.
* Open your **appsettings.json** file and add a new section named "Syncfusion" as below:
```json
{
//...
"Syncfusion": {
"LicenseKey": "<your-license-key>"
}
}
```
> Replace the `<your-license-key> part with your license key that we've obtained in the previous section.`
* To be able to use the Syncfusion Components we need to define them in our **_ViewImports.cshtml** file. By doing that we can use the Syncfusion components everywhere in our application.
* Open your **/Pages/_ViewImports.cshtml** file and add a new tag helper:
```cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling
@addTagHelper *, Syncfusion.EJ2 //use Syncfusion components
```
#### 3-) Adding Syncfusion styles and scripts to our application
Firstly, let's install the `@syncfusion/ej2` package from **npm**.
* Open your **package.json** file and add the `@syncfusion/ej2` package with version **19.3.57**:
```json
{
"version": "1.0.0",
"name": "my-app",
"private": true,
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.basic": "^5.0.0-rc.2",
"@syncfusion/ej2": "^19.3.57"
}
}
```
* Then, open the **abp.resourcemapping.js** file and update the **mappings** section:
```js
module.exports = {
aliases: {
},
mappings: {
"@node_modules/@syncfusion/ej2/dist/ej2.min.js": "@libs/syncfusion/",
"@node_modules/@syncfusion/ej2/material.css": "@libs/syncfusion/"
}
};
```
> ABP copies related packages from **node_modules** folder to the **libs** folder by examining this file. You can read this [document](docs.abp.io/en/abp/latest/UI/AspNetCore/Client-Side-Package-Management#mapping-the-library-resources) for more info.
* Then run the `abp install-libs` to install the dependencies and copy them into the libs folder by your mappings configuration. After running this command, in your **libs** folder it should be a folder named **syncfusion** folder.
![](./syncfusion-libs.png)
The last thing we need to do is, add some style and script files provided by Syncfusion, between our head-body tags.
* We can do this by creating two view components (one for Styles and the other for Scripts). Let's do that.
First, create a folder structure as shown below under the **Components** folder.
![](./component-folder-structure.png)
Then open the related files and add the following codes to each of these files.
* **Default.cshtml** (/Components/Syncfusion/Script/Default.cshtml)
```cshtml
@addTagHelper *, Syncfusion.EJ2 //add this line
<!-- Syncfusion Essential JS 2 Scripts -->
<script src="/libs/syncfusion/ej2.min.js"></script>
<!-- Syncfusion Essential JS 2 ScriptManager -->
<ejs-scripts></ejs-scripts>
```
* **SyncfusionScriptComponent.cs**
```csharp
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
namespace SyncfusionComponentsDemo.Web.Components.Syncfusion.Script
{
public class SyncfusionScriptComponent : AbpViewComponent
{
public IViewComponentResult Invoke()
{
return View("~/Components/Syncfusion/Script/Default.cshtml");
}
}
}
```
* **Default.cshtml** (/Components/Syncfusion/Style/Default.cshtml)
```cshtml
<!-- Syncfusion Essential JS 2 Styles -->
<link rel="stylesheet" href="/libs/syncfusion/material.css">
```
* SyncfusionStyleComponent.cs
```csharp
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
namespace SyncfusionComponentsDemo.Web.Components.Syncfusion.Style
{
public class SyncfusionStyleComponent : AbpViewComponent
{
public IViewComponentResult Invoke()
{
return View("~/Components/Syncfusion/Style/Default.cshtml");
}
}
}
```
After creating these two components, we can use the [**Layout Hooks**](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Layout-Hooks) system of ABP to inject these two components between head and script tags.
To do this, open your web module class and update the `ConfigureServices` method as below:
```csharp
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
//Register Syncfusion license
var licenseKey = configuration["Syncfusion:LicenseKey"].ToString();
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(licenseKey: licenseKey);
Configure<AbpLayoutHookOptions>(options =>
{
//Now, the SyncfusionStyleComponent code will be inserted in the head of the page as the last item.
options.Add(LayoutHooks.Head.Last, typeof(SyncfusionStyleComponent));
//the SyncfusionScriptComponent will be inserted in the body of the page as the last item.
options.Add(LayoutHooks.Body.Last, typeof(SyncfusionScriptComponent));
});
ConfigureUrls(configuration);
ConfigureBundles();
ConfigureAuthentication(context, configuration);
ConfigureAutoMapper();
ConfigureVirtualFileSystem(hostingEnvironment);
ConfigureLocalizationServices();
ConfigureNavigationServices();
ConfigureAutoApiControllers();
ConfigureSwaggerServices(context.Services);
}
```
After injecting the Syncfusion style and script into our application, our configurations have been completed. We can try with a simple component to see if it works as we expected.
* Let's try with the [Calendar](https://www.syncfusion.com/aspnet-core-ui-controls/calendar) component. Open your **Index.cshtml** file and update with the below content:
```cshtml
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using SyncfusionComponentsDemo.Localization
@using Volo.Abp.Users
@model SyncfusionComponentsDemo.Web.Pages.IndexModel
@section styles {
<abp-style src="/Pages/Index.css" />
}
@section scripts {
<abp-script src="/Pages/Index.js" />
}
<div class="container">
<h2>Syncfusion - Calendar Component</h2>
<ejs-calendar id="calendar"></ejs-calendar>
</div>
```
* Then when we run the application, we need to see the relevant calendar component as below.
![](./calendar-component.png)
### Conclusion
In this article, we've explained how to integrate the **Syncfusion Components** into our applications. After following this article, you can use the Syncfusion components in your application.
Thanks for reading the article, I hope you've found it useful :)

BIN
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/calendar-component.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/component-folder-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/copy-license-key.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/manage-trial-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/manage-trial-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/syncfusion-libs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/en/Community-Articles/2021-12-13-Integrating-the-Syncfusion-MVC-Components-to-the-ABP-MVC-UI/syncfusion-package.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

2
docs/en/Customizing-Application-Modules-Extending-Entities.md

@ -63,8 +63,6 @@ You can then use the same extra properties system defined in the previous sectio
Another approach can be **creating your own entity** mapped to **the same database table** (or collection for a MongoDB database).
`AppUser` entity in the [application startup template](Startup-Templates/Application.md) already implements this approach. [EF Core Migrations document](Entity-Framework-Core-Migrations.md) describes how to implement it and manage **EF Core database migrations** in such a case. It is also possible for MongoDB, while this time you won't deal with the database migration problems.
## Creating a New Entity with Its Own Database Table/Collection
Mapping your entity to an **existing table** of a depended module has a few disadvantages;

2
docs/en/Getting-Started-Running-Solution.md

@ -139,7 +139,7 @@ Ensure that the `.IdentityServer` project is the startup project. Run the applic
> Use Ctrl+F5 in Visual Studio (instead of F5) to run the application without debugging. If you don't have a debug purpose, this will be faster.
You can login, but you cannot enter to the main application here. This is just the authentication server.
You can login, but you cannot enter to the main application here. This is **just the authentication server**.
Ensure that the `.HttpApi.Host` project is the startup project and run the application which will open a Swagger UI:

2
docs/en/Getting-Started.md

@ -15,6 +15,6 @@
This tutorial explains how to **create and run** a new web application using the ABP Framework. Follow the steps below;
1. [Setup your development environment](Getting-Started-Setup-Environment)
1. [Setup your development environment](Getting-Started-Setup-Environment.md)
2. [Creating a new solution](Getting-Started-Create-Solution.md)
3. [Running the solution](Getting-Started-Running-Solution.md)

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

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

@ -10,10 +10,10 @@
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;
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:
@ -80,19 +80,19 @@ You can see the **book list** returned from the server. You can also check the *
Let's **create a new book** using the `create` function:
````js
acme.bookStore.books.book.create({
name: 'Foundation',
type: 7,
publishDate: '1951-05-24',
price: 21.5
}).then(function (result) {
console.log('successfully created the book with id: ' + result.id);
acme.bookStore.books.book.create({
name: 'Foundation',
type: 7,
publishDate: '1951-05-24',
price: 21.5
}).then(function (result) {
console.log('successfully created the book with id: ' + result.id);
});
````
> 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)
@ -187,7 +187,7 @@ namespace Acme.BookStore.Web.Pages.Books
{
public void OnGet()
{
}
}
}
@ -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.
* `Entities`, `TotalCount`, `PageSize`, `OnDataGridReadAsync` are defined in the base blass.
* 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.

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

2
docs/en/Virtual-File-System.md

@ -119,7 +119,7 @@ The Virtual File System is well integrated to ASP.NET Core:
### Static Virtual File Folders
By default, ASP.NET Core only allows the `wwwroot` folder to contain the static files consumed by the clients. When you use the birtual File System, the following folders also can contain static files:
By default, ASP.NET Core only allows the `wwwroot` folder to contain the static files consumed by the clients. When you use the virtual File System, the following folders also can contain static files:
* Pages
* Views

1
docs/zh-Hans/Background-Workers.md

@ -2,7 +2,6 @@
## 介绍
背景工人在应用简单独立的线程在后台运行.一般来说,他们定期运行,以执行一些任务.例子;
后台工作者在应用程序后台运行的简单的独立线程,一般来说它们定期运行执行一些任务.例如;
* 后台工作者可以定期**删除过时的日志**.

11
docs/zh-Hans/CLI.md

@ -29,6 +29,7 @@ dotnet tool update -g Volo.Abp.Cli
* **`help`**: 展示ABP CLI的用法帮助信息.
* **`new`**:生成基于ABP的[启动模板](Startup-Templates/Index.md).
* **`update`**:自动更新的ABP解决方案ABP相关的NuGet和NPM包.
* **`clean`**: 删除当前目录下所有的 `BIN``OBJ` 子目录.
* **`add-package`**: 添加ABP包到项目.
* **`add-module`**: 添加[应用模块](https://docs.abp.io/en/abp/latest/Modules/Index)到解决方案.
* **`generate-proxy`**: 生成客户端代理以使用HTTP API端点.
@ -129,6 +130,16 @@ abp update [options]
* `--check-all`: 分别检查每个包的新版本. 默认是 `false`.
* `--version` or `-v`: 指定用于升级的版本. 如果没有指定,则使用最新版本.
### clean
删除当前目录下所有的 `BIN``OBJ` 子目录.
用法:
````bash
abp clean
````
### add-package
通过以下方式将ABP包添加到项目中

98
docs/zh-Hans/Getting-Started-AspNetCore-Application.md

@ -1,12 +1,12 @@
# 在AspNet Core MVC Web Application中使用ABP
# 在ASP.NET Core MVC Web 应用程序中使用ABP
本教程将介绍如何开始以最少的依赖关系开始使用ABP开发.
本教程将介绍如何开始以最少的依赖关系开始使用ABP开发.
通常情况下你需要下载一个 **[启动模板](Getting-Started-AspNetCore-MVC-Template.md)**
通常情况下你希望从 **[启动模板](Getting-Started-AspNetCore-MVC-Template.md)** 开始.
## 创建一个新项目
1. 使用Visual Studio 2019 (16.4.0+)创建一个新的AspNet Core Web Application:
1. 使用Visual Studio 2022 (17.0.0+)创建一个新的ASP.NET Core Web应用程序:
![](images/create-new-aspnet-core-application-v2.png)
@ -21,7 +21,7 @@
## 安装 Volo.Abp.AspNetCore.Mvc 包
Volo.Abp.AspNetCore.Mvc是ABP集成AspNet Core MVC的包,请安装它到你项目中:
Volo.Abp.AspNetCore.Mvc是ABP集成ASP.NET Core MVC的包,请安装它到你项目中:
````
Install-Package Volo.Abp.AspNetCore.Mvc
@ -29,7 +29,7 @@ Install-Package Volo.Abp.AspNetCore.Mvc
## 创建ABP模块
ABP是一个模块化框架,它需要一个**启动 (根) 模块**继承自``AbpModule``:
ABP是一个模块化框架,它需要一个**启动(根)模块**继承自 `AbpModule`:
````C#
using Microsoft.AspNetCore.Builder;
@ -43,21 +43,20 @@ namespace BasicAspNetCoreApplication
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
public class AppModule : AbpModule
{
public override void OnApplicationInitialization(
ApplicationInitializationContext context)
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
// Configure the HTTP request pipeline.
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseConfiguredEndpoints();
@ -68,49 +67,44 @@ namespace BasicAspNetCoreApplication
``AppModule`` 是应用程序启动模块的好名称.
ABP的包定义了这个模块类,模块可以依赖其它模块.在上面的代码中 ``AppModule`` 依赖于 ``AbpAspNetCoreMvcModule`` (模块存在于[Volo.Abp.AspNetCore.Mvc](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc)包中). 安装新的ABP的包后添加``DependsOn``是很常见的做法.
ABP的包定义了模块类,模块可以依赖其它模块.在上面的代码中 ``AppModule`` 依赖于 ``AbpAspNetCoreMvcModule`` (由[Volo.Abp.AspNetCore.Mvc](https://www.nuget.org/packages/Volo.Abp.AspNetCore.Mvc)包定义). 安装新的ABP的包后添加``DependsOn``特性是很常见的做法.
我们在此模块类中配置ASP.NET Core管道,而不是Startup类中.
### 启动类
接下来修改启动类集成ABP模块系统:
接下来修改启动类集成ABP模块系统:
````C#
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using BasicAspNetCoreApplication;
namespace BasicAspNetCoreApplication
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplication<AppModule>();
}
var builder = WebApplication.CreateBuilder(args);
public void Configure(IApplicationBuilder app)
{
app.InitializeApplication();
}
}
}
builder.Services.ReplaceConfiguration(builder.Configuration);
builder.Services.AddApplication<AppModule>();
var app = builder.Build();
app.InitializeApplication();
app.Run();
````
``services.AddApplication<AppModule>()``添加了所有``AppModule``模块中定义的全部服务.
``Configure``方法中的``app.InitializeApplication()``完成初始化并启动应用程序.
``services.AddApplication<AppModule>()``添加了从``AppModule``中启动的所有模块中定义的所有服务.
``app.InitializeApplication()`` 初始化并启动应用程序.
## 运行应用程序!
启动该应用它将按预期运行.
启动该应用,它将按预期运行.
## 使用 Autofac 依赖注入框架
虽然AspNet Core的依赖注入(DI)系统适用于基本要求,但[Autofac](https://autofac.org/)提供了属性注入和方法拦截等高级功能,这些功能是ABP执行高级应用程序框架功能所必需的.
虽然ASP.NET Core的依赖注入(DI)系统适用于基本要求,但[Autofac](https://autofac.org/)提供了属性注入和方法拦截等高级功能,这些功能是ABP执行高级应用程序框架功能所必需的.
用Autofac取代AspNet Core的DI系统并集成到ABP非常简单.
用Autofac取代ASP.NET Core的DI系统并集成到ABP非常简单.
1. 安装 [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) 包
@ -132,27 +126,21 @@ public class AppModule : AbpModule
3. 修改``Program.cs``以使用Autofac:
````C#
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using BasicAspNetCoreApplication;
namespace BasicAspNetCoreApplication
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
var builder = WebApplication.CreateBuilder(args);
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseAutofac(); // 添加这一行
}
}
builder.Host.UseAutofac(); //Add this line
builder.Services.ReplaceConfiguration(builder.Configuration);
builder.Services.AddApplication<AppModule>();
var app = builder.Build();
app.InitializeApplication();
app.Run();
````
## 源码

73
docs/zh-Hans/Getting-Started-Create-Solution.md

@ -0,0 +1,73 @@
# 入门教程
````json
//[doc-params]
{
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}
````
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项.
## 创建新项目
我们将使用 ABP CLI 创建一个新的 ABP 项目.
> 或者, 你可以使用[ABP Framework 网站](https://abp.io/get-started)页面上的选项轻松的 **创建并下载** 项目.
使用 ABP CLI 的 `new` 命令创建一个新项目:
````shell
abp new Acme.BookStore{{if UI == "NG"}} -u angular{{else if UI == "Blazor"}} -u blazor{{else if UI == "BlazorServer"}} -u blazor-server{{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes"}}{{if UI == "MVC" || UI == "BlazorServer"}} --tiered{{else}} --separate-identity-server{{end}}{{end}}
````
*你可以使用不同级别的命名空间, 例如: BookStore、Acme.BookStore或 Acme.Retail.BookStore.*
{{ if Tiered == "Yes" }}
{{ if UI == "MVC" || UI == "BlazorServer" }}
* `--tified` 参数用于创建认证服务器、 UI 和 API 实际分隔的 N-层解决方案.
{{ else }}
* `--separate-identity-server` 参数用于将Identity Server应用程序与API主机应用程序分隔开. 如果未指定, 则服务器上将只有一个端点.
{{ end }}
{{ end }}
> [ABP CLI 文档](./CLI.md) 涵盖了所有可用的命令和选项.
## 移动端开发
如果你想要在你的解决方案中包含 [React Native](https://reactnative.dev/) 项目, 将 `-m react-native` (or `--mobile react-native`) 参数添加到项目创建命令. 这是一个基础的 React Native 启动模板, 用于开发基于你的 ABP 后端的移动应用程序.
请参阅 [React Native 入门](Getting-Started-React-Native.md) 文档, 了解如何配置和运行 React Native 应用程序.
### 解决方案结构
该解决方案具有分层结构 (基于 [域驱动设计](Domain-Driven-Design.md)), 并包含单元 & 集成测试项目. 请参阅 [应用程序模板文档](Startup-Templates/Application.md) 以详细了解解决方案结构.
{{ if DB == "Mongo" }}
#### MongoDB 事务
[启动模板](Startup-templates/Index.md) 默认在`.MongoDB`项目中**禁用**事务. 如果你的MongoDB服务器支持事务, 你可以在*YourProjectMongoDbModule*类中的`ConfigureServices`方法开启它:
```csharp
Configure<AbpUnitOfWorkDefaultOptions>(options =>
{
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Auto;
});
```
> 或者你可以删除该代码, 因为 `Auto` 已经是默认行为.
{{ end }}
## 下一步
* [运行解决方案](Getting-Started-Running-Solution.md)

199
docs/zh-Hans/Getting-Started-Running-Solution.md

@ -0,0 +1,199 @@
# 入门教程
````json
//[doc-params]
{
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}
````
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项.
## 创建数据库
### 连接字符串
检查在 {{if Tiered == "Yes"}}`.IdentityServer` 和`.HttpApi.Host` 项目{{else}}{{if UI=="MVC"}}`.Web` 项目{{else if UI=="BlazorServer"}}`.Blazor` 项目{{else}}`.HttpApi.Host` 项目{{end}}{{end}} 中 `appsettings.json` 文件里的**连接字符串**.
{{ if DB == "EF" }}
````json
"ConnectionStrings": {
"Default": "Server=(LocalDb)\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True"
}
````
> **关于连接字符串和数据库管理系统**
>
> 解决方案配置为默认使用 **Entity Framework Core****MS SQL Server**. 但是, 如果在执行ABP CLI 的`new`命令时使用了`-dbms`参数来选择其他DBMS (如`-dbms MySQL`), 那么连接字符串可能不同.
>
> EF Core 支持 [多种](https://docs.microsoft.com/en-us/ef/core/providers/) 据库提供程序, 因此你可以使用任何受支持的DBMS. 你可以需要时候参阅[Entity Framework 集成文档](Entity-Framework-Core.md) 来学习如何[切换到另一个DBMS](Entity-Framework-Core-Other-DBMS.md).
### 数据库迁移
该解决方案使用[Entity Framework Core Code First 迁移](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli). 带有 `.DbMigrator` 的控制台程序用于 **应用迁移****初始化种子数据**. 它在**开发**和**生产**环境中都很有用.
> `.dbMigator` 项目有自己的 `appsettings.json`. 因此, 如果你更改了之前的连接字符串, 那么也应该更改这个连接字符串.
### 初次迁移
`.dbMigator` 应用程序在首次运行时自动**创建初始迁移**.
**如果你使用的是 Visual Studio, 你可以跳到 *运行 dbMigrator* 部分.** 但是, 其他 IDE (例如 Rider) 在首次运行时可能会遇到问题, 因为它会添加初始迁移并编译项目. 在这种情况下, 请在 `.dbMigration` 项目的文件夹中打开命令行终端, 然后运行以下命令:
````bash
dotnet run
````
下次, 你可以像往常一样在 IDE 中运行它.
### 运行迁移
右键单击 `.dbMigration` 项目, 然后选择 **设置为启动项目**
![set-as-startup-project](images/set-as-startup-project.png)
按F5(或Ctrl + F5) 运行应用程序. 它将具有如下所示的输出:
![db-migrator-output](images/db-migrator-output.png)
> 初始的[种子数据](Data-Seeding.md)在数据库中创建了 `admin` 用户(密码为`1q2w3E*`) 用于登录应用程序. 所以, 对于新数据库至少使用 `.DbMigrator` 一次.
{{ else if DB == "Mongo" }}
````json
"ConnectionStrings": {
"Default": "mongodb://localhost:27017/BookStore"
}
````
该解决方案配置为在本地计算机中使用 **MongoDB**, 因此你需要启动并运行 MongoDB 服务器实例, 或者将连接字符串更改为另一台 MongoDB 服务器.
### 种子初始数据
该解决方案带有 `.DbMigrator` 的控制台程序用于 **初始化种子数据**. 它在**开发**和**生产**环境中都很有用.
> `.dbMigator` 项目有自己的 `appsettings.json`. 因此, 如果你更改了之前的连接字符串, 那么也应该更改这个连接字符串.
右键单击 `.dbMigration` 项目, 然后选择 **设置为启动项目**
![set-as-startup-project](images/set-as-startup-project.png)
按F5(或Ctrl + F5) 运行应用程序. 它将具有如下所示的输出:
![db-migrator-output](images/db-migrator-output.png)
> 初始的[种子数据](Data-Seeding.md)在数据库中创建了 `admin` 用户(密码为`1q2w3E*`) 用于登录应用程序. 所以, 对于新数据库至少使用 `.DbMigrator` 一次.
{{ end }}
## 运行应用程序
{{ if UI == "MVC" || UI == "BlazorServer" }}
{{ if Tiered == "Yes" }}
> 分层解决方案使用 **Redis** 作为分布式缓存. 确保它已安装并在本地计算机上运行. 如果你使用的是远程 Redis 服务器, 请修改项目的 ` appsettings.json` 文件中的配置.
1. 确保 `.IdentityServer` 项目是启动项目. 运行此应用程序, 它将在浏览器中打开 **登录** 页面.
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快.
你可以登录, 但不能在这里进入主应用程序. 这 **只是身份验证服务器**.
2. 确保 `.httpapi.Host` 项目是启动项目, 然后运行应用将在浏览器中打开 **Swagger UI**.
![swagger-ui](images/swagger-ui.png)
这是 Web 应用程序使用的 HTTP API.
3. 最后, 确保 {{if UI=="MVC"}}`.Web`{{else}}`.Blazor`{{end}} 项目是启动项目,然后运行应用程序,它将在浏览器中打开 **欢迎** 页面
![mvc-tiered-app-home](images/bookstore-home.png)
单击 **login** 按钮, 它将重定向到 *身份验证服务器* 以登录到应用程序:
![bookstore-login](images/bookstore-login.png)
{{ else # Tiered != "Yes" }}
确保 {{if UI=="MVC"}}`.Web`{{else}}`.Blazor`{{end}} 项目是启动项目. 运行应用程序将会在浏览器中打开 **login** 页面:
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快.
![bookstore-login](images/bookstore-login.png)
{{ end # Tiered }}
{{ else # UI != MVC || BlazorServer }}
### 运行 HTTP API 主机(服务器端)
{{ if Tiered == "Yes" }}
> 分层解决方案使用 Redis 作为分布式缓存. 确保它已安装并在本地计算机上运行. 如果你使用的是远程 Redis 服务器, 请修改项目的 `appsettings.json` 文件中的配置.
确保 `.IdentityServer` 项目是启动项目. 运行此应用程序, 它将在浏览器中打开 **登录** 页面.
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快.
你可以登录, 但不能在这里进入主应用程序. 这 **只是身份验证服务器**.
确保 `.HttpApi.Host` 项目是启动项目, 然后运行应用程序将打开 Swagger UI 的:
{{ else # Tiered == "No" }}
确保 `.HttpApi.Host` 项目是启动项目, 然后运行应用程序将打开 Swagger UI 的:
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快.
{{ end # Tiered }}
![swagger-ui](images/swagger-ui.png)
你可以在这里查看应用程序的API并测试它们. 获取Swagger UI的[更多信息](https://swagger.io/tools/swagger-ui/).
{{ end # UI }}
{{ if UI == "Blazor" }}
### 运行 Blazor 应用程序 (客户端)
确保 `.Blazor` 项目是启动项目并运行应用程序.
> 在 Visual Studio 中使用 Ctrl+F5(而不是F5) 在不进行调试的情况下运行应用程序. 如果你没有调试目的, 这会更快.
应用程序启动后, 单击页头上的 **Login** 链接, 你将重定向到身份验证服务器以输入用户名和密码:
![bookstore-login](images/bookstore-login.png)
{{ else if UI == "NG" }}
### 运行 Angular 应用程序 (客户端)
转到 `Angular` 文件夹, 打开命令行终端, 键入 `yarn` 命令(我们建议使用 [yarn](https://yarnpkg.com/) 软件包管理器, 而 `npm install` 也可以使用)
```bash
yarn
```
当所有node模块加载完毕后, 执行 `yarn start` (或 `npm start`) 命令:
```bash
yarn start
```
初次构建可能需要更长的时间. 完成后, 它会在默认浏览器中使用 [localhost:4200](http://localhost:4200/) 地址打开 Angular UI.
![bookstore-login](images/bookstore-login.png)
{{ end }}
输入用户名 **admin** 和 密码 **1q2w3E*** 登录应用程序. 应用程序已启动并正在运行. 你可以根据此启动模板开始开发应用程序.
## 另请参见
* [Web 应用程序开发教程](Tutorials/Part-1.md)
* [应用程序启动模板](Startup-Templates/Application.md)

53
docs/zh-Hans/Getting-Started-Setup-Environment.md

@ -0,0 +1,53 @@
# 入门教程
````json
//[doc-params]
{
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}
````
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项.
## 设置你的开发环境
第一件事! 在创建项目之前, 让我们先设置你的开发环境.
### 先决条件
开发计算机上应安装以下工具:
* 一个集成开发环境 (比如: [Visual Studio](https://visualstudio.microsoft.com/vs/)) 它需要支持 [.NET 6.0+](https://dotnet.microsoft.com/download/dotnet) 的开发.
{{ if UI != "Blazor" }}
* [Node v12 或 v14](https://nodejs.org/)
* [Yarn v1.20+ (不是v2)](https://classic.yarnpkg.com/en/docs/install) <sup id="a-yarn">[1](#f-yarn)</sup> 或 npm v6+ (已跟随Node一起安装)
{{ end }}
{{ if Tiered == "Yes" }}
* [Redis](https://redis.io/) (启动解决方案使用 Redis 作为 [分布式缓存](Caching.md)).
{{ end }}
{{ if UI != "Blazor" }}
<sup id="f-yarn"><b>1</b></sup> _Yarn v2 工作方式不同, 不被支持._ <sup>[↩](#a-yarn)</sup>
{{ end }}
### 安装 ABP CLI
[ABP CLI](./CLI.md) 是一个命令行界面, 用于自动执行基于 ABP 的解决方案的一些常见任务. 首先, 你需要使用以下命令安装 ABP CLI:
````shell
dotnet tool install -g Volo.Abp.Cli
````
如果已安装, 则可以使用以下命令对其进行更新:
````shell
dotnet tool update -g Volo.Abp.Cli
````
## 下一步
* [创建新的解决方案](Getting-Started-Create-Solution.md)

370
docs/zh-Hans/Getting-Started.md

@ -1,374 +1,20 @@
## 入门
# 入门教程
````json
//[doc-params]
{
"UI": ["MVC","NG"],
"UI": ["MVC", "Blazor", "BlazorServer", "NG"],
"DB": ["EF", "Mongo"],
"Tiered": ["Yes", "No"]
}
````
本教程介绍了如何创建一个新的{{if UI == "MVC"}} ASP.NET Core MVC web {{else if UI == "NG"}} Angular {{end}}. 配置并运行它.
> 本文档假设你更喜欢使用 **{{ UI_Value }}** 作为 UI 框架, 使用 **{{ DB_Value }}** 作为数据库提供程序. 对于其他选项, 请更改本文档顶部的首选项.
## 设置你的开发环境
## 内容
创建第一个项目之前,需要正确的设置你的开发环境.
本教程介绍如何使用 ABP 框架 **创建和运行** 新的 Web 应用程序. 请按照以下步骤操作;
### 预先要求
你需要安装以下工具:
* [Visual Studio 2019 (v16.4+)](https://visualstudio.microsoft.com/vs/) for Windows / [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).<sup id="a-editor">[1](#f-editor)</sup>
* [.NET Core 3.1+](https://www.microsoft.com/net/download/dotnet-core/)
* [Node v12 或 v14](https://nodejs.org/en/)
* [Yarn v1.19+](https://classic.yarnpkg.com/)
* [Yarn v1.20+ (not v2)](https://classic.yarnpkg.com/en/docs/install) <sup id="a-yarn">[2](#f-yarn)</sup> 或 npm v6+ (与Node一起安装)
{{ if Tiered == "Yes" }}
* [Redis](https://redis.io/): 入门解决方案将Redis用作[分布式缓存](Caching.md). 因此你需要安装并运行Redis.
{{ end }}
<sup id="f-editor"><b>1</b></sup> _只要支持.NET Core和ASP.NET Core,就可以使用其他编辑器代替Visual Studio._ <sup>[↩](#a-editor)</sup>
<sup id="f-yarn"><b>2</b></sup> _Yarn v2 的工作方式不同,不受支持._ <sup>[↩](#a-yarn)</sup>
### 安装ABP CLI
[ABP CLI](./CLI.md)是一个命令行页面,用于自动执行一些基于ABP的应用程序的常见任务.
> ABP CLI是ABP框架一个免费开源的工具.
你需要使用以下命令安排ABP CLI:
````shell
dotnet tool install -g Volo.Abp.Cli
````
如果你已经安装,你可以使用以下命令更新到最新版本:
````shell
dotnet tool update -g Volo.Abp.Cli
````
## 创建新项目
> 本文假设你使用 **{{ UI_Value }}** 做为UI框架 **{{ DB_Value }}** 做为数据库提供程序,对于其它选项,你可以更改文档顶部的首选项.
### 使用ABP CLI创建一个新项目
使用ABP CLI的 `new` 命令创建新项目:
````shell
abp new Acme.BookStore{{if UI == "NG"}} -u angular {{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes" && UI != "NG"}} --tiered {{else if Tiered == "Yes" && UI == "NG"}}--separate-identity-server{{end}} --mobile react-native
````
* 此命令还会在解决方案文件夹内创建一个React Native移动应用程序. 如果你不想要它,可以安全地删除它或从`abp new`命令中删除`--mobile react-native`选项, 以使其完全不包含在解决方案中.
{{ if UI == "NG" }}
* `-u` 指定UI框架, 本例中是 `angular`.
{{ if Tiered == "Yes" }}
* `--separate-identity-server` 参数用于将Identity服务器应用程序与API主机应用程序分隔开. 如果未指定,则服务器上将只有一个端点.
{{ end }}
{{ end }}
{{ if DB == "Mongo" }}
* `-d` 指定数据库提供程序, 本例中是 `mongodb`.
{{ end }}
{{ if Tiered == "Yes" && UI != "NG" }}
* `--tiered` 参数用于创建n层解决方案,其中身份验证服务器层,UI层和API层在物理上是分离的.
{{ end }}
> 你可以使用不同级别的命令空间; 例如. BookStore, Acme.BookStore or Acme.Retail.BookStore.
#### ABP CLI 命令 & 选项
[ABP CLI文档](./CLI.md)涵盖了ABP CLI的所有可用命令和选项. 本文档使用[应用程序启动模板](Startup-Templates/Application.md)创建新的Web应用程序. 有关其他模板,请参见[ABP启动模板](Startup-Templates/Index.md)文档.
> 或者,您可以从[ABP Framework网站](https://abp.io/get-started)中选择"直接下载"选项卡创建新的解决方案.
## 解决方案结构
{{ if UI == "MVC" }}
创建项目后你会有以下解决方案目录和文件:
![](images/solution-files-mvc.png)
在Visual Studio中打开 `.sln` 文件时,将看到以下解决方案结构:
{{if DB == "Mongo"}}
![vs-default-app-solution-structure](images/vs-app-solution-structure-mongodb.png)
{{else}}
![vs-default-app-solution-structure](images/vs-app-solution-structure{{if Tiered == "Yes"}}-tiered{{end}}.png)
{{end}}
{{ else if UI == "NG" }}
在创建的解决方案中有三个文件夹:
![](images/solution-files-non-mvc.png)
* `angular` 文件夹包含Angular UI应用程序.
* `aspnet-core` 文件夹包含后端应用程序.
* `react-native` 文件夹包含React Native UI 应用程序.
打开 `aspnet-core` 文件夹下的 `.sln`(`Visual Studio`解决方案)文件:
![vs-angular-app-backend-solution-structure](images/vs-spa-app-backend-structure{{if DB == "Mongo"}}-mongodb{{end}}.png)
{{ end }}
> ###### 关于解决方案中的项目
>
> 根据你的**UI**,**数据库**和其他选项,你的解决方案的结构可能略有不同.
该解决方案具有分层结构(基于[Domain Driven Design](Domain-Driven-Design.md)), 并包含配置好的的单元&集成测试项目.
{{ if DB == "EF" }}
集成测试项目已配置为可与 **EF Core** & **SQLite 内存** database同时使用.
{{ else if DB == "Mongo" }}
集成测试项目已配置为每个测试创建的内存中的**MongoDB**数据库(使用的[Mongo2Go](https://github.com/Mongo2Go/Mongo2Go)库).
{{ end }}
> 请参阅[应用程序模板文档](Startup-Templates/Application.md)详细了解解决方案结构.
{{ if DB == "Mongo" }}
> [启动模板](Startup-templates/Index.md)默认在 `.MongoDB` 项目中**禁用**了工作单元事务. 如果你的MongoDB服务器支持事务,你可以手动启用工作单元的事务:
```csharp
Configure<AbpUnitOfWorkDefaultOptions>(options =>
{
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Enabled;
});
```
{{ end }}
## 创建数据库
### 连接字符串
检查 {{if UI == "MVC"}}{{if Tiered == "Yes"}}`.IdentityServer` 和 `.HttpApi.Host` 项目{{else}}`.Web` 项目{{end}}{{else if UI == "NG" }}`.HttpApi.Host` 项目{{end}}下 `appsettings.json` 文件中的 **链接字符串**:
{{ if DB == "EF" }}
````json
"ConnectionStrings": {
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True"
}
````
该解决方案配置为**Entity Framework Core**与**MS SQL Server**一起使用. EF Core支持[各种](https://docs.microsoft.com/en-us/ef/core/providers/)数据库提供程序,因此你可以使用任何受支持的DBMS. 请参阅[Entity Framework集成文档](https://docs.abp.io/en/abp/latest/Entity-Framework-Core)了解如何切换到另一个DBMS.
### 数据库连接字符串
查看`.Web`项目下`appsettings.json`文件中的 **连接字符串**:
````json
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=BookStore;Trusted_Connection=True"
}
}
````
解决方案使用 **Entity Framework Core****MS SQL Server**. EF Core支持[各种](https://docs.microsoft.com/zh-cn/ef/core/providers/)数据库提供程序,因此你可以根据实际需要使用其他DBMS. 如果需要,请更改连接字符串.
### 应用迁移
该解决方案使用[Entity Framework Core Code First 迁移](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli). 你需要应用迁移来创建数据库,有两种方法迁移数据库.
#### 使用DbMigrator应用程序应用迁移
该解决方案包含一个控制台应用程序(在此示例中名为`Acme.BookStore.DbMigrator`),可以创建数据库,应用迁移和初始化数据. 它对开发和生产环境都很有用.
> `.DbMigrator`项目有自己的`appsettings.json`. 因此,如果你更改了上面的连接字符串,则还应更改此字符串.
右键单击`.DbMigrator`项目并选择 **设置为启动项目**:
![set-as-startup-project](images/set-as-startup-project.png)
按F5(或Ctrl + F5)运行应用程序. 它将具有如下所示的输出:
![set-as-startup-project](images/db-migrator-app.png)
#### 使用EF Core Update-Database命令
Ef Core具有`Update-Database`命令, 可根据需要创建数据库并应用挂起的迁移. 右键单击`.Web`项目并选择**设置为启动项目**:
{{ if UI == "MVC" }}
右键单击{{if Tiered == "Yes"}}`.IdentityServer`{{else}}`.Web`{{end}}项目并选择**设置为启动项目**:
{{ else if UI != "MVC" }}
右键单击`.HttpApi.Host`项目并选择**设置为启动项目**:
{{ end }}
![set-as-startup-project](images/set-as-startup-project.png)
打开**包管理器控制台(Package Manager Console)**, 选择`.EntityFrameworkCore.DbMigrations`项目作为**默认项目**并运行`Update-Database`命令:
![package-manager-console-update-database](images/package-manager-console-update-database.png)
这将基于配置的连接字符串创建新数据库.
> **使用`.DbMigrator`工具是建议的方法**, 因为它能初始化初始数据能够正确运行Web应用程序.
>
> 如果你只是使用 `Update-Database` 命令,你会得到一个空数据库,所以你无法登录到应用程序因为数据库中没有初始管理用户. 不需要种子数据库时,可以在开发期间使用 `Update-Database` 命令. 但是使用 `.DbMigrator` 应用程序会更简单,你始终可以使用它来迁移模式并为数据库添加种子.
{{ else if DB == "Mongo" }}
````json
"ConnectionStrings": {
"Default": "mongodb://localhost:27017/BookStore"
}
````
该解决方案被配置为在你的本地计算机中使用 **MongoDB**,因此你需要启动并运行一个MongoDB服务器实例或者将连接字符串更改为另一个MongoDB服务器.
### 初始化种子数据
该解决方案附带一个 `.DbMigrator` 控制台应用程序,该应用程序为初始数据提供了种子. 它对于开发以及生产环境都很有用.
> `.DbMigrator` 项目有自己的 `appsettings.json`.如果你更改了其他项目的 `appsettings.json`,也应该更改这个.
右键点击 `.DbMigrator` 并选择 **设置为启动项目**.
![set-as-startup-project](images/set-as-startup-project.png)
按F5(或Ctrl+F5)启动应用程序,你会看到以下输出:
![db-migrator-output](images/db-migrator-output.png)
> 数据库创建后会初始化[种子数据](Data-Seeding.md), 其中包含用于登录的 `admin` 用户. 所以你至少使用 `.DbMigrator` 一次.
{{ end }}
### 运行应用程序
{{ if UI == "MVC" }}
{{ if Tiered == "Yes" }}
确保 `.IdentityServer` 是启动项目,运行应用程序后会在你的浏览器打开一个 **login** 页面.
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间.
你可以登录,但是不能在这里进入主应用程序,它仅是验证服务器.
确保 `.HttpApi.Host` 是启动项目,运行应用程序后会在你的浏览器打开一个 **Swagger UI** 页面.
![swagger-ui](images/swagger-ui.png)
这里是Web应用程序使用的API应用程序.
最后确保 `.Web` 是启动项目,运行应用程序后会在你的浏览器打开一个 **welcome** 页面.
![mvc-tiered-app-home](images/bookstore-home.png)
点击 **login** 按钮重定向到 `Identity Server` 来登录应用程序.
![bookstore-login](images/bookstore-login.png)
{{ else }}
最后确保 `.Web` 是启动项目,运行应用程序后会在你的浏览器打开一个 **login** 页面.
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间.
![bookstore-login](images/bookstore-login.png)
{{ end }}
{{ else if UI != "MVC" }}
#### 运行HTTP API Host (服务器端)
{{ if Tiered == "Yes" }}
确保 `.IdentityServer` 是启动项目,运行应用程序后会在你的浏览器打开一个 **login** 页面.
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间.
你可以登录,但是不能在这里进入主应用程序,它仅是验证服务器.
{{ end }}
确保 `.HttpApi.Host` 是启动项目,运行应用程序后会在你的浏览器打开一个 **Swagger UI** 页面.
{{ if Tiered == "No" }}
> 在Visual Studio中使用Ctrl+F5(而不是F5)运行应用,如果你不用于调试,这会减少启动时间.
{{ end }}
![swagger-ui](images/swagger-ui.png)
你可以看到应用程序的API并进行测试. 更多信息,请参阅[Swagger UI](https://swagger.io/tools/swagger-ui/).
> ##### Swagger UI 授权
>
> 大多数的HTTP API都需要身份验证和授权. 如果你要测试授权API, 请手动进入 `/Account/Login` 页面, 输入用户名: `admin` 和密码: `1q2w3E*` 登录到应用程序. 然后你可以访问授权API.
{{ end }}
{{ if UI == "NG" }}
#### 运行 Angular 应用程序 (客户端)
`angular` 下打开命令行终端, 输入 `yarn` 命令(我们推荐使用[yarn](https://yarnpkg.com/)包管理, `npm install` 在大多数情况下也可以工作).
```bash
yarn
```
等到所有node模块加载成功, 执行 `yarn start` (或 `npm start`) 命令:
```bash
yarn start
```
等待 `Angular CLI` 使用 `BrowserSync` 启动 `Webpack` dev-server.
它会负责编译你的 `TypeScript`代码, 并自动重新加载浏览器.
完成后 `Angular Live Development Server` 会监听 localhost:4200.
打开你的浏览器并导航到[localhost:4200](http://localhost:4200/).
![bookstore-login](images/bookstore-login.png)
{{ end }}
输入用户名 **admin**,密码 **1q2w3E*** 登录到应用程序,应用程序已经启动并执行,你可以基于此启动模板开始开发应用程序.
#### 移动开发
当你创建一个新的应用程序时. 可以添加`-m react-native`选项以在解决方案中包含 `react-native`项目. 这是一个基础的[React Native](https://reactnative.dev/)启动模板,用于开发与基于ABP的后端集成的移动应用程序.
请参阅"[React Native入门](Getting-Started-React-Native.md)"文档了解如何配置和运行React Native应用程序.
## 下一步是什么?
[Web应用程序开发教程](Tutorials/Part-1.md)
1. [设置你的开发环境](Getting-Started-Setup-Environment.md)
2. [创建新的解决方案](Getting-Started-Create-Solution.md)
3. [运行解决方案](Getting-Started-Running-Solution.md)

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` 中).

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

@ -1 +1,173 @@
TODO...
# 身份服务器模块
身份服务器模块提供了一个 [IdentityServer](https://github.com/IdentityServer/IdentityServer4) (IDS) 的完全集成, 该框架提供高级身份验证功能, 如单点登录和API访问控制.此模块将客户端,资源以及其他 IDS 相关的对象保存到数据库中.
## 如何安装
当你使用 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/) 许可, 所以你可以免费使用和自定义它.
## 用户界面
此模块使用了领域逻辑和数据库集成, 但没有提供任何 UI.如果你需要动态添加客户端和资源, 管理 UI 是非常有用的.在这种情况下, 你可以自己构建管理 UI, 或者考虑购买为此模块提供了管理 UI 的 [ABP 商业版](https://commercial.abp.io/).
## 与其他模块的关系
此模块基于 [身份模块](Identity.md) 并且[账户模块](Account.md) 有一个 [集成包](https://www.nuget.org/packages/Volo.Abp.Account.Web.IdentityServer).
## 选项
### AbpIdentityServerBuilderOptions
`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...
});
}
````
`AbpIdentityServerBuilderOptions` 属性:
* `UpdateJwtSecurityTokenHandlerDefaultInboundClaimTypeMap` (默认值:true):更新 `JwtSecurityTokenHandler.DefaultInboundClaimTypeMap` 使其与身份服务器声明兼容.
* `UpdateAbpClaimTypes` (默认值:true):更新 `AbpClaimTypes` 与身份服务器声明兼容.
* `IntegrateToAspNetIdentity` (默认值:true):集成到 ASP.NET Identity.
* `AddDeveloperSigningCredential` (默认值:true):设置为 false 禁止调用 IIdentityServerBuilder 中的 `AddDeveloperSigningCredential()`.
`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(...);
});
}
````
## 内部结构
### 领域层
#### 聚合
##### API 资源
需要 API 资源来允许客户端请求访问令牌.
* `ApiResource` (聚合根):表示系统中的 API 资源.
* `ApiSecret` (集合):API 资源的密钥.
* `ApiScope` (集合):API 资源的作用域.
* `ApiResourceClaim` (集合):API 资源的声明.
##### 客户端
客户端表示可以从你的身份服务器请求令牌的应用程序.
* `Client` (聚合根):表示一个身份服务器的客户端应用程序.
* `ClientScope` (集合):客户端的作用域.
* `ClientSecret` (集合):客户端的密钥.
* `ClientGrantType` (集合):客户端的授权类型.
* `ClientCorsOrigin` (集合):客户端的 CORS 源.
* `ClientRedirectUri` (集合):客户端的重定向 URIs.
* `ClientPostLogoutRedirectUri` (集合):客户端的登出重定向 URIs.
* `ClientIdPRestriction` (集合):客户端的提供程序约束.
* `ClientClaim` (集合):客户端的声明.
* `ClientProperty` (集合):客户端的自定义属性.
##### 持续化授权
持续化授权存储了授权码,刷新令牌和用户准许.
* `PersistedGrant` (聚合根):表示为身份服务器持续化授权.
##### 身份资源
身份资源是用户的用户 ID ,名称或邮件地址等数据.
* `IdentityResource` (聚合根):表示与身份服务器的身份资源.
* `IdentityClaim` (集合):身份资源的声明.
#### 仓储
为此模块定义了以下自定义仓储:
* `IApiResourceRepository`
* `IClientRepository`
* `IPersistentGrantRepository`
* `IIdentityResourceRepository`
#### 领域服务
此模块不包含任何领域服务, 但重写了下面的服务;
* `AbpProfileService` (当 `AbpIdentityServerBuilderOptions.IntegrateToAspNetIdentity` 为 true 时使用)
* `AbpClaimsService`
* `AbpCorsPolicyService`
### 设置
此模块未定义任何设置.
### 应用层
#### 应用服务
* `ApiResourceAppService` (实现 `IApiResourceAppService`):实现了 API 资源管理 UI 的用例.
* `IdentityServerClaimTypeAppService` (实现 `IIdentityServerClaimTypeAppService`):用于获取声明列表.
* `ApiResourceAppService` (实现 `IApiResourceAppService`):实现了 API 管理资源 UI 的用例.
* `IdentityResourceAppService` (实现 `IIdentityResourceAppService`):实现了身份资源管理 UI 的用例.
### 数据库提供程序
#### 公共
##### 表/集合 前缀 & 架构
所有表/集合都使用 `IdentityServer` 作为默认前缀.如果你需要改变表的前缀或设置一个架构名称(如果你的数据库提供程序支持), 请设置 `AbpIdentityServerDbProperties` 类的静态属性.
##### 连接字符串
此模块使用 `AbpIdentityServer` 作为连接字符串的名称.如果你没有用这个名称定义连接字符串, 它将回退到 `Default` 连接字符串.
有关详细信息, 请参阅 [连接字符串](https://docs.abp.io/zh-Hans/abp/latest/Connection-Strings) 文档.
#### EF Core
##### 表
* **IdentityServerApiResources**
* IdentityServerApiSecrets
* IdentityServerApiScopes
* IdentityServerApiScopeClaims
* IdentityServerApiClaims
* **IdentityServerClients**
* IdentityServerClientScopes
* IdentityServerClientSecrets
* IdentityServerClientGrantTypes
* IdentityServerClientCorsOrigins
* IdentityServerClientRedirectUris
* IdentityServerClientPostLogoutRedirectUris
* IdentityServerClientIdPRestrictions
* IdentityServerClientClaims
* IdentityServerClientProperties
* **IdentityServerPersistedGrants**
* **IdentityServerIdentityResources**
* IdentityServerIdentityClaims
#### MongoDB
##### 集合
* **IdentityServerApiResources**
* **IdentityServerClients**
* **IdentityServerPersistedGrants**
* **IdentityServerIdentityResources**

123
docs/zh-Hans/Tutorials/Part-1.md

@ -2,32 +2,15 @@
````json
//[doc-params]
{
"UI": ["MVC","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
{{
if UI == "MVC"
UI_Text="mvc"
else if UI == "NG"
UI_Text="angular"
else
UI_Text="?"
end
if DB == "EF"
DB_Text="Entity Framework Core"
else if DB == "Mongo"
DB_Text="MongoDB"
else
DB_Text="?"
end
}}
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
* **{{DB_Text}}** 做为ORM提供程序.
* **{{DB_Text}}** 做为数据库提供程序.
* **{{UI_Value}}** 做为UI框架.
本教程分为以下部分:
@ -40,16 +23,29 @@ end
- [Part 6: 作者: 领域层](Part-6.md)
- [Part 7: 作者: 数据库集成](Part-7.md)
- [Part 8: 作者: 应用服务层](Part-8.md)
- [Part 9: 作者: 用户](Part-9.md)
- [Part 9: 作者: 用户](Part-9.md)
- [Part 10: 图书到作者的关系](Part-10.md)
## 下载源码
本教程根据你的**UI** 和 **Database**偏好有多个版,我们准备了两种可供下载的源码组合:
本教程根据你的**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=cJzyIFfAlp8&list=PLsNclT2aHJcPNaCf7Io3DbMN6yAk_DgWJ&index=1" target="_blank">发布在YouTube</a>**.
{{end}}
## 创建解决方案
在开始开发之前,请按照[入门教程](../Getting-Started.md)创建名为 `Acme.BookStore` 的新解决方案.
@ -58,12 +54,12 @@ end
启动模板中的**领域层**分为两个项目:
- `Acme.BookStore.Domain`包含你的[实体](https://docs.abp.io/zh-Hans/abp/latest/Entities), [领域服务](https://docs.abp.io/zh-Hans/abp/latest/Domain-Services)和其他核心域对象.
- `Acme.BookStore.Domain`包含你的[实体](../Entities.md), [领域服务](../Domain-Services.md)和其他核心域对象.
- `Acme.BookStore.Domain.Shared`包含可与客户共享的常量,枚举或其他域相关对象.
在解决方案的**领域层**(`Acme.BookStore.Domain`项目)中定义你的实体.
在解决方案的**领域层**(`Acme.BookStore.Domain`项目)中定义你的实体.
该应用程序的主要实体是`Book`. 在`Acme.BookStore.Domain`项目中创建一个 `Books` 文件夹并在其中添加一个名为 `Book` 的类,如下所示:
该应用程序的主要实体是`Book`. 在`Acme.BookStore.Domain`项目中创建一个 `Books` 文件夹(命名空间),并在其中添加名为 `Book` 的类,如下所示:
````csharp
using System;
@ -84,15 +80,15 @@ namespace Acme.BookStore.Books
}
````
* ABP为实体提供了两个基本的基类: `AggregateRoot`和`Entity`. **Aggregate Root**是[**领域驱动设计**](./Domain-Driven-Design.md) 概念之一. 可以视为直接查询和处理的根实体(请参阅[实体文档](../Entities.md)).
* `Book`实体继承了`AuditedAggregateRoot`,`AuditedAggregateRoot`类在`AggregateRoot`类的基础上添加了一些审计属性(`CreationTime`, `CreatorId`, `LastModificationTime` 等). ABP框架自动为你管理这些属性.
* `Guid`是`Book`实体的主键类型.
* ABP为实体提供了两个基本的基类: `AggregateRoot`和`Entity`. **Aggregate Root**是[**领域驱动设计**](../Domain-Driven-Design.md) 概念之一. 可以视为直接查询和处理的根实体(请参阅[实体文档](../Entities.md)).
* `Book`实体继承了`AuditedAggregateRoot`,`AuditedAggregateRoot`类在`AggregateRoot`类的基础上添加了一些基础[审计](../Audit-Logging.md)属性(例如`CreationTime`, `CreatorId`, `LastModificationTime` 等). ABP框架自动为你管理这些属性.
* `Guid`是`Book`实体的**主键类型**.
> 为了保持简单,本教程将实体属性保留为 **public get/set** . 如果你想了解关于DDD最佳实践,请参阅[实体文档](../Entities.md).
### BookType枚举
上面所用到了 `BookType` 枚举,在 `Acme.BookStore.Domain.Shared` 项目创建 `BookType`.
`Book`实体使用了`BookType`枚举. 在`Acme.BookStore.Domain.Shared`项目中创建`Books`文件夹(命名空间),并在其中添加`BookType`:
````csharp
namespace Acme.BookStore.Books
@ -150,28 +146,37 @@ public class BookStoreMongoDbContext : AbpMongoDbContext
### 将Book实体映射到数据库表
`Acme.BookStore.EntityFrameworkCore` 项目中打开 `BookStoreDbContextModelCreatingExtensions.cs` 文件,添加 `Book` 实体的映射代码. 最终类应为:
打开`BookStoreDbContext`类的`OnModelCreating`方法,为`Book`实体添加映射代码:
````csharp
using Acme.BookStore.Books;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
...
namespace Acme.BookStore.EntityFrameworkCore
{
public static class BookStoreDbContextModelCreatingExtensions
public class BookStoreDbContext :
AbpDbContext<BookStoreDbContext>,
IIdentityDbContext,
ITenantManagementDbContext
{
public static void ConfigureBookStore(this ModelBuilder builder)
...
protected override void OnModelCreating(ModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
base.OnModelCreating(builder);
/* Include modules to your migration db context */
builder.ConfigurePermissionManagement();
...
/* Configure your own tables/entities inside here */
builder.Entity<Book>(b =>
{
b.ToTable(BookStoreConsts.DbTablePrefix + "Books",
BookStoreConsts.DbSchema);
BookStoreConsts.DbSchema);
b.ConfigureByConvention(); //auto configure for the base class props
b.Property(x => x.Name).IsRequired().HasMaxLength(128);
});
@ -180,14 +185,14 @@ namespace Acme.BookStore.EntityFrameworkCore
}
````
* `BookStoreConsts` 含有用于表的架构和表前缀的常量值. 你不必使用它,但建议在单点控制表前缀.
* `ConfigureByConvention()` 方法优雅的配置/映射继承的属性,应始终所有的实体使用它.
* `BookStoreConsts` 含有用于表的架构和表前缀的常量值. 使用它不是强制的,但建议在统一的地方控制表前缀.
* `ConfigureByConvention()` 方法优雅的配置/映射继承的属性,应对所有的实体使用它.
### 添加数据迁移
启动模板使用[EF Core Code First Migrations](https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/)创建和维护数据库架构. 我们应该创建一个新的迁移并且应用到数据库.
本示例使用[EF Core Code First Migrations](https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/).因为我们修改了数据库映射配置,我们必须创建一个新的迁移并且应用到数据库.
`Acme.BookStore.EntityFrameworkCore.DbMigrations` 目录打开命令行终端输入以下命令:
`Acme.BookStore.EntityFrameworkCore` 目录打开命令行终端输入以下命令:
```bash
dotnet ef migrations add Created_Book_Entity
@ -205,7 +210,7 @@ dotnet ef migrations add Created_Book_Entity
> >在运行应用程序之前最好将初始数据添加到数据库中. 本节介绍ABP框架的[数据种子系统](../Data-Seeding.md). 如果你不想创建种子数据可以跳过本节,但是建议你遵循它来学习这个有用的ABP Framework功能。
`*.Domain` 项目下创建派生 `IDataSeedContributor` 的类,并且拷贝以下代码:
`*.Domain` 项目下创建 `IDataSeedContributor`派生类,并且拷贝以下代码:
```csharp
using System;
@ -258,7 +263,7 @@ namespace Acme.BookStore
}
```
* 如果数据库中当前没有图书,则此代码使用 `IRepository<Book, Guid>`(默认[repository](../Repositories.md))将两本书插入数据库.
* 如果数据库中当前没有图书,则此代码使用 `IRepository<Book, Guid>`(默认[repository](../Repositories.md))将两本书插入数据库.
### 更新数据库
@ -279,7 +284,7 @@ namespace Acme.BookStore
### BookDto
`CrudAppService` 基类需要定义实体的基本DTO. 在 `Acme.BookStore.Application.Contracts` 项目中创建一个名为 `BookDto` 的DTO类:
`CrudAppService` 基类需要定义实体的基本DTO. 在 `Acme.BookStore.Application.Contracts` 项目中创建 `Books` 文件夹(命名空间), 并在其中添加名为 `BookDto` 的DTO类:
````C#
using System;
@ -300,9 +305,9 @@ namespace Acme.BookStore
}
````
* **DTO**类被用来在 **表示层****应用层** **传递数据**.查看[DTO文档](https://docs.abp.io/zh-Hans/abp/latest/Data-Transfer-Objects)查看更多信息.
* 为了在面上展示书籍信息,`BookDto`被用来将书籍数据传递到表示层.
* `BookDto`继承自 `AuditedEntityDto<Guid>`.上面定义的 `Book` 实体一样具有一些审计属性.
* **DTO**类被用来在 **表示层****应用层** **传递数据**.参阅[DTO文档](https://docs.abp.io/zh-Hans/abp/latest/Data-Transfer-Objects).
* 为了在用户界面上展示书籍信息,`BookDto`被用来将书籍数据传递到表示层.
* `BookDto`继承自 `AuditedEntityDto<Guid>`.上面定义的 `Book` 实体一样具有一些审计属性.
在将书籍返回到表示层时,需要将`Book`实体转换为`BookDto`对象. [AutoMapper](https://automapper.org)库可以在定义了正确的映射时自动执行此转换. 启动模板配置了AutoMapper,因此你只需在`Acme.BookStore.Application`项目的`BookStoreApplicationAutoMapperProfile`类中定义映射:
@ -322,12 +327,11 @@ namespace Acme.BookStore
}
````
> 参阅 [对象对象映射](../Object-To-Object-Mapping.md) 文档了解详情.
> 参阅 [对象对象映射](../Object-To-Object-Mapping.md) 文档了解详情.
### CreateUpdateBookDto
在`Acme.BookStore.Application.Contracts`项目中创建一个名为 `CreateUpdateBookDto` 的DTO类:
在`Acme.BookStore.Application.Contracts`项目中创建 `Books` 文件夹(命名空间),并在其中添加名为 `CreateUpdateBookDto` 的DTO类:
````csharp
using System;
using System.ComponentModel.DataAnnotations;
@ -354,7 +358,7 @@ namespace Acme.BookStore.Books
````
* 这个DTO类被用于在创建或更新书籍的时候从用户界面获取图书信息.
* 它定义了数据注释属性(如`[Required]`)来定义属性的验证. DTO由ABP框架[自动验证](https://docs.abp.io/zh-Hans/abp/latest/Validation).
* 它定义了数据注释特性(如`[Required]`)来定义属性的验证规则. DTO由ABP框架[自动验证](https://docs.abp.io/zh-Hans/abp/latest/Validation).
就像上面的`BookDto`一样,创建一个从`CreateUpdateBookDto`对象到`Book`实体的映射,最终映射配置类如下:
@ -378,7 +382,7 @@ namespace Acme.BookStore
### IBookAppService
下一步是为应用程序定义接口,在`Acme.BookStore.Application.Contracts`项目中定义一个名为`IBookAppService`的接口:
下一步是为应用程序定义接口,在`Acme.BookStore.Application.Contracts`项目创建 `Books` 文件夹(命名空间),并在其中添加名为`IBookAppService`的接口:
````csharp
using System;
@ -400,12 +404,12 @@ namespace Acme.BookStore.Books
````
* 框架定义应用程序服务的接口**不是必需的**. 但是,它被建议作为最佳实践.
* `ICrudAppService`定义了常见的**CRUD**方法:`GetAsync`,`GetListAsync`,`CreateAsync`,`UpdateAsync`和`DeleteAsync`. 你可以从空的`IApplicationService`接口继承并手动定义自己的方法(将在下一部分中完成).
* `ICrudAppService`有一些变体, 你可以在每个方法中使用单独的DTO,也可以分别单独指定(例如使用不同的DTO进行创建和更新).
* `ICrudAppService`定义了常见的**CRUD**方法:`GetAsync`,`GetListAsync`,`CreateAsync`,`UpdateAsync`和`DeleteAsync`. 从这个接口扩展不是必需的,你可以从空的`IApplicationService`接口继承并手动定义自己的方法(将在下一部分中完成).
* `ICrudAppService`有一些变体, 你可以在每个方法中使用单独的DTO(例如使用不同的DTO进行创建和更新).
### BookAppService
在`Acme.BookStore.Application`项目中创建名为 `BookAppService``IBookAppService` 实现:
是时候实现`IBookAppService`接口了.在`Acme.BookStore.Application`项目中创建 `Books` 文件夹(命名空间),并在其中添加名为 `BookAppService` 的类:
````csharp
using System;
@ -439,19 +443,20 @@ namespace Acme.BookStore.Books
### 自动生成API Controllers
通常创建**Controller**以将应用程序服务公开为**HTTP API**端点. 因此允许浏览器或第三方客户端通过AJAX调用它们.
在典型的ASP.NET Core应用程序中,你创建**API Controller**以将应用程序服务公开为**HTTP API**端点. 这将允许浏览器或第三方客户端通过HTTP调用它们.
ABP可以[**自动**](../API/Auto-API-Controllers.md)按照惯例将你的应用程序服务配置为MVC API控制器.
ABP可以[**自动**](../API/Auto-API-Controllers.md)按照约定将你的应用程序服务配置为MVC API控制器.
### Swagger UI
启动模板配置为使用[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)运行[swagger UI](https://swagger.io/tools/swagger-ui/). 运行应用程序并在浏览器中输入`https://localhost:XXXX/swagger/`(用你自己的端口替换XXXX)作为URL.
使用`CTRL+F5`运行应用程序 ({{if UI=="MVC"}}`Acme.BookStore.Web`{{else}}`Acme.BookStore.HttpApi.Host`{{end}})并使用浏览器访问`https://localhost:<port>/swagger/` on your browser. 使用你自己的端口号替换 `<port>`.
你会看到一些内置的接口和`Book`的接口,它们都是REST风格的:
你会看到一些内置的服务端点和`Book`服务,它们都是REST风格的端点:
![bookstore-swagger](images/bookstore-swagger.png)
![bookstore-swagger](./images/bookstore-swagger.png)
Swagger有一个很好的UI来测试API.
Swagger有一个很好的UI来测试API.
你可以尝试执行`[GET] /api/app/book` API来获取书籍列表, 服务端会返回以下JSON结果:

254
docs/zh-Hans/Tutorials/Part-2.md

@ -2,26 +2,10 @@
````json
//[doc-params]
{
"UI": ["MVC","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
{{
if UI == "MVC"
DB="ef"
DB_Text="Entity Framework Core"
UI_Text="mvc"
else if UI == "NG"
DB="mongodb"
DB_Text="MongoDB"
UI_Text="angular"
else
DB ="?"
UI_Text="?"
end
}}
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
@ -44,16 +28,30 @@ end
## 下载源码
本教程根据你的**UI** 和 **Database**偏好有多个版,我们准备了两种可供下载的源码组合:
本教程根据你的**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=UDNlLiPiBiw&list=PLsNclT2aHJcPNaCf7Io3DbMN6yAk_DgWJ&index=2" target="_blank">发布在YouTube</a>**.
{{end}}
{{if UI == "MVC"}}
## 动态JavaScript代理
通常在 **JavaScript** 端通过AJAX调用HTTP API端点. 你可以使用 `$.ajax` 或其他工具来调用端点. 但是ABP提供了更好的方法.
**JavaScript** 端通过AJAX调用HTTP API端点是常见的做法. 你可以使用 `$.ajax` 或其他工具来调用端点. 但是ABP提供了更好的方法.
ABP**动态**为所有API端点创建 **[JavaScript代理](../UI/AspNetCore/Dynamic-JavaScript-Proxies.md)**. 所以你可以像调用**Javascript本地方法**一样使用任何**端点**.
@ -79,21 +77,21 @@ acme.bookStore.books.book.getList({}).done(function (result) { console.log(resul
![bookstore-getlist-result-network](images/bookstore-getlist-result-network.png)
Let's **create a new book** using the `create` function:
让我们使用 `create` 函数**创建一本书**:
````js
acme.bookStore.books.book.create({
name: 'Foundation',
type: 7,
publishDate: '1951-05-24',
price: 21.5
}).then(function (result) {
console.log('successfully created the book with id: ' + result.id);
acme.bookStore.books.book.create({
name: 'Foundation',
type: 7,
publishDate: '1951-05-24',
price: 21.5
}).then(function (result) {
console.log('successfully created the book with id: ' + result.id);
});
````
> 如果你下载了本教程的源代码并按照示例中的步骤操作,你需要传递`authorId`参数给创建方法以**创建一本新书**.
您应该在控制台中看到类似以下的消息:
````text
@ -102,7 +100,7 @@ successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
检查数据库中的 `Books` 表你会看到新的一行. 你可以自己尝试使用 `get`, `update``delete` 函数.
我们将利用这些动态代理功能在接下来的章节来与服务器通信.
在接下来的章节,我们将利用这些动态代理函数与服务器通信.
{{end}}
@ -112,7 +110,7 @@ successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
本地化文本位于 `Acme.BookStore.Domain.Shared` 项目的 `Localization/BookStore` 文件夹下:
![bookstore-localization-files](./images/bookstore-localization-files-v2.png)
![bookstore-localization-files](images/bookstore-localization-files-v2.png)
打开 `en.json` (*英文翻译*)文件并更改内容,如下所示:
@ -154,7 +152,7 @@ successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
* 为按钮项添加 `Menu:` 前缀.
* 使用 `Enum:<enum-type>:<enum-value>` 命名约定来本地化枚举成员. 当您这样做时ABP可以在某些适当的情况下自动将枚举本地化.
如果未在本地化文件中定义文本,则文本将**回退**到本地化键(作为ASP.NET Core的标准行为).
如果未在本地化文件中定义文本,则文本将**回退**到本地化键(ASP.NET Core的标准行为).
> ABP本地化系统建立在[ASP.NET Core标准本地化](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization)系统之上,并以多种方式进行了扩展. 有关详细信息请参见[本地化文档](../Localization.md).
@ -162,7 +160,7 @@ successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
## 创建图书页面
是时候创建可见的和可用的东西了! 代替经典的MVC,我们将使用微软推荐的[Razor Pages UI](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/razor-pages-start).
是时候创建可见的和可用的东西了! 我们将使用微软推荐的[Razor Pages UI](https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/razor-pages-start),而不是经典的MVC.
`Acme.BookStore.Web` 项目的 `Pages` 文件夹下创建一个名为新的 `Books` 的文件夹. 然后在文件夹右键选择 **添加 > Razor Page** 菜单. 输入名称 `Index`:
@ -189,13 +187,13 @@ namespace Acme.BookStore.Web.Pages.Books
{
public void OnGet()
{
}
}
}
```
### 将Book页面添加到主菜单
### 将图书页面添加到主菜单
打开 `Menus` 文件夹中的 `BookStoreMenuContributor` 类,在 `ConfigureMainMenuAsync` 方法的底部添加如下代码:
@ -223,9 +221,7 @@ context.Menu.AddItem(
### 图书列表
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.
我们将使用[Datatables.net](https://datatables.net/)JQuery插件来显示页面上的表格列表. [Datatables](https://datatables.net/)可以完全通过AJAX工作,速度快,并提供良好的用户体验.
我们将使用[Datatables.net](https://datatables.net/)JQuery插件来显示图书列表. [Datatables](https://datatables.net/)可以完全通过AJAX工作,速度快,并提供良好的用户体验.
> Datatables插件在启动模板中配置,因此你可以直接在任何页面中使用它,无需在页面中引用样式和脚本文件.
@ -261,7 +257,7 @@ We will use the [Datatables.net](https://datatables.net/) jQuery library to show
`Pages/Books/` 文件夹中创建 `index.js`文件
![bookstore-index-js-file](./images/bookstore-index-js-file-v3.png)
![bookstore-index-js-file](images/bookstore-index-js-file-v3.png)
`index.js` 的内容如下:
@ -321,8 +317,8 @@ $(function () {
````
* `abp.localization.getResource` 获取一个函数,该函数用于使用服务器端定义的相同JSON文件对文本进行本地化. 通过这种方式你可以与客户端共享本地化值.
* `abp.libs.datatables.normalizeConfiguration`一个辅助方法.不是必须的, 但是它通过为缺少的选项提供常规值来简化数据表配置.
* `abp.libs.datatables.createAjax`帮助ABP的动态JavaScript API代理跟[Datatable](https://datatables.net/)的格式相适应的辅助方法.
* `abp.libs.datatables.normalizeConfiguration`是一个辅助方法.不是必须的, 但是它通过为缺省的选项提供约定的值来简化[Datatables](https://datatables.net/)配置.
* `abp.libs.datatables.createAjax`另一个辅助方法,用来适配ABP的动态JavaScript API代理和[Datatable](https://datatables.net/)期望的参数格式.
* `acme.bookStore.books.book.getList` 是动态JavaScript代理函数(上面已经介绍过了)
* [luxon](https://moment.github.io/luxon/) 库也是该解决方案中预先配置的标准库,你可以轻松地执行日期/时间操作.
@ -334,15 +330,13 @@ $(function () {
![Book list](images/bookstore-book-list-3.png)
这是一个完全正常工作的服务端分页,排序和本地化的图书列表.
{{end}}
这是一个可以正常工作的,服务端分页,排序和本地化的图书列表.
{{if UI == "NG"}}
## 安装NPM包
>注意: 本教程基于ABP Framework v3.0.3+. 如果你的项目版本较旧,请升级您的解决方案. 如果要升级现有的v2.x项目,请参阅[迁移指南](../UI/Angular/Migration-Guide-v3.md).
>注意: 本教程基于ABP Framework v3.1.0+. 如果你的项目版本较旧,请升级您的解决方案. 如果要升级现有的v2.x项目,请参阅[迁移指南](../UI/Angular/Migration-Guide-v3.md).
`angular` 目录下打开命令行窗口,选择 `yarn` 命令安装NPM包:
@ -357,9 +351,7 @@ yarn
- [Ng Bootstrap](https://ng-bootstrap.github.io/#/home) 用做UI组件库.
- [ngx-datatable](https://swimlane.gitbook.io/ngx-datatable/) 用做 datatable 类库.
### BookModule
运行以下命令创建一个名为 `BookModule` 的新模块:
运行以下命令在angular应用程序根目录创建一个名为 `BookModule` 的新模块:
```bash
yarn ng generate module book --module app --routing --route books
@ -417,7 +409,7 @@ const routes: Routes = [
];
````
现在打开 `src/app/route.provider.ts` 以下替换 `configureRoutes` 函数:
现在打开 `src/app/route.provider.ts` 替换 `configureRoutes` 函数为以下代码:
```js
function configureRoutes(routes: RoutesService) {
@ -450,27 +442,31 @@ function configureRoutes(routes: RoutesService) {
`RoutesService` 是ABP框架提供的用于配置主菜单和路由的服务.
* `path` 路由的URL.
* `path` 路由的URL.
* `name` 菜单项的名称(参阅[本地化文档](../UI/Angular/Localization.md)了解更多).
* `iconClass` 菜单项的图标(你可以使用默认的[Font Awesome](https://fontawesome.com/)图标).
* `order` 菜单项的排序.我们定义了101,它显示在 "Administration" 项的后面.
* `layout` BooksModule路由的布局. 可以定义 `eLayoutType.application`, `eLayoutType.account``eLayoutType.empty`.
* `iconClass` 菜单项的图标(你可以使用默认的[Font Awesome](https://fontawesome.com/)图标).
* `order` 菜单项的排序.
* `layout` BooksModule路由的布局. (有三个预定义的布局类型: `eLayoutType.application`, `eLayoutType.account``eLayoutType.empty`).
更多信息请参阅[RoutesService 文档](../UI/Angular/Modifying-the-Menu.md#via-routesservice).
更多信息请参阅[RoutesService 文档](https://docs.abp.io/en/abp/latest/UI/Angular/Modifying-the-Menu.md#via-routesservice).
### 生成服务代理
### 生成代理
[ABP CLI](../CLI.md) 提供 `generate-proxy` 命令为HTTP APIs生成客户端代理.有了这些代理,在客户端使用HTTP APIs变得更加方便. 运行 `generate-proxy` 命令前, 你的 host 必须正在运行.
ABP CLI提供了 `generate-proxy` 命令为你的服务HTTP API生成客户端代理简化客户端使用服务的成本. 运行 `generate-proxy` 命令前你的host必须正在运行. 参阅 [CLI 文档](../CLI.md).
> **警告**: 使用IIS Express时有一个问题; 它不允许从另一个进程连接应用程序. 如果你使用Visual Studio, 在运行按钮的下拉框中选择`Acme.BookStore.HttpApi.Host`,不要选择IIS Express, 如下图:
`angular` 文件夹下运行以下命令:
![vs-run-without-iisexpress](images/vs-run-without-iisexpress.png)
启动host应用程序后,在 `angular` 文件夹下运行以下命令:
```bash
abp generate-proxy -t ng
```
生成的文件如下:
这个命令将在`/src/app/proxy/books`文件夹下产生以下文件:
![Generated files](./images/generated-proxies-2.png)
![Generated files](images/generated-proxies-3.png)
### BookComponent
@ -479,8 +475,7 @@ abp generate-proxy -t ng
```js
import { ListService, PagedResultDto } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
import { BookDto } from './models';
import { BookService } from './services';
import { BookService, BookDto } from '@proxy/books';
@Component({
selector: 'app-book',
@ -494,7 +489,7 @@ export class BookComponent implements OnInit {
constructor(public readonly list: ListService, private bookService: BookService) {}
ngOnInit() {
const bookStreamCreator = (query) => this.bookService.getListByInput(query);
const bookStreamCreator = (query) => this.bookService.getList(query);
this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
this.book = response;
@ -503,8 +498,8 @@ export class BookComponent implements OnInit {
}
```
* 我们注入了生成的 `BookService`.
* 我们实现了 [ListService](https://docs.abp.io/en/abp/latest/UI/Angular/List-Service),它是一个公用服务,提供了简单的分页,排序和搜索.
* 我们引入并注入了生成的 `BookService`.
* 我们使用 [ListService](../UI/Angular/List-Service.md),它是一个工具服务,提供了易用的分页,排序和搜索.
打开 `/src/app/book/book.component.html` 用以下内容替换它:
@ -545,9 +540,138 @@ export class BookComponent implements OnInit {
现在你可以在浏览器看到最终结果:
![Book list final result](./images/bookstore-book-list.png)
![图书列表最终结果](images/bookstore-book-list.png)
{{end}}
{{else if UI == "Blazor" || UI == "BlazorServer"}}
## 创建图书页面
是时候创建可见和可用的东西了! 右击`Acme.BookStore.Blazor`项目下的`Pages`文件夹,新建一个名为`Books.razor`的**razor组件**.
![blazor-add-books-component](images/blazor-add-books-component.png)
用以下内容替换这个组件的内容:
````html
@page "/books"
<h2>Books</h2>
@code {
}
````
### 将图书页面添加到主菜单
打开`Blazor`项目中的`BookStoreMenuContributor`类,在 `ConfigureMainMenuAsync` 方法的底部添加如下代码:
````csharp
context.Menu.AddItem(
new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
).AddItem(
new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/books"
)
)
);
````
运行项目,使用用户名 `admin` 和密码 `1q2w3E*` 登录到应用程序. 看到新菜单项已添加到顶部栏:
![blazor-menu-bookstore](images/blazor-menu-bookstore.png)
点击BookStore下的Books子菜单项就会跳转到空的图书页面.
### 图书列表
我们将使用[Blazorise library](https://blazorise.com/)作为UI组件.它是一个强大的库,支持主要的HTML/CSS框架,包括Bootstrap.
ABP提供了一个通用的基类,`AbpCrudPageBase<...>`,用来创建CRUD风格的页面.这个基类兼容用来构建`IBookAppService`的`ICrudAppService`.所以我们从`AbpCrudPageBase`继承,获得标准CRUD的默认实现.
打开`Books.razor` 并把内容修改成下面这样:
````xml
@page "/books"
@using Volo.Abp.Application.Dtos
@using Acme.BookStore.Books
@using Acme.BookStore.Localization
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<BookStoreResource> L
@inherits AbpCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>
<Card>
<CardHeader>
<h2>@L["Books"]</h2>
</CardHeader>
<CardBody>
<DataGrid TItem="BookDto"
Data="Entities"
ReadData="OnDataGridReadAsync"
TotalItems="TotalCount"
ShowPager="true"
PageSize="PageSize">
<DataGridColumns>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.Name)"
Caption="@L["Name"]"></DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
<DisplayTemplate>
@L[$"Enum:BookType:{(int)context.Type}"]
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.PublishDate)"
Caption="@L["PublishDate"]">
<DisplayTemplate>
@context.PublishDate.ToShortDateString()
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.Price)"
Caption="@L["Price"]">
</DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.CreationTime)"
Caption="@L["CreationTime"]">
<DisplayTemplate>
@context.CreationTime.ToLongDateString()
</DisplayTemplate>
</DataGridColumn>
</DataGridColumns>
</DataGrid>
</CardBody>
</Card>
````
> 如果你可以编译并运行成功,但看到一些语法错误.你可以忽略这些错误,因为Visual Studio处理Blazor还有一些bug.
* `AbpCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>`实现了所有的CRUD细节,我们从它继承.
* `Entities`, `TotalCount`, `PageSize`, `OnDataGridReadAsync`定义在基类中.
* 注入`IStringLocalizer<BookStoreResource>` (作为`L`对象),用于本地化.
虽然上面的代码非常容易理解,你仍然可以查看Blazorise [Card](https://blazorise.com/docs/components/card/)和[DataGrid](https://blazorise.com/docs/extensions/datagrid/)文档以更好地理解它们.
#### 关于AbpCrudPageBase
对于图书页面,我们将持续从`AbpCrudPageBase`获得益处. 你可以只注入`IBookAppService`并自己执行所有的服务端调用(感谢ABP的[动态C# HTTP API客户端代理](../API/Dynamic-CSharp-API-Clients.md)系统).
## 运行最终应用程序
你可以运行应用程序!该部分的最终用户界面如下所示:
![blazor-bookstore-book-list](images/blazor-bookstore-book-list.png)
这是一个可以正常工作的,服务端分页,排序和本地化的图书列表.
{{end # UI }}
## 下一章

600
docs/zh-Hans/Tutorials/Part-3.md

@ -2,27 +2,10 @@
````json
//[doc-params]
{
"UI": ["MVC","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
{{
if UI == "MVC"
UI_Text="mvc"
else if UI == "NG"
UI_Text="angular"
else
UI_Text="?"
end
if DB == "EF"
DB_Text="Entity Framework Core"
else if DB == "Mongo"
DB_Text="MongoDB"
else
DB_Text="?"
end
}}
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
@ -45,16 +28,30 @@ end
## 下载源码
本教程根据你的**UI** 和 **Database**偏好有多个版,我们准备了两种可供下载的源码组合:
本教程根据你的**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=TLShZO8u2VE&list=PLsNclT2aHJcPNaCf7Io3DbMN6yAk_DgWJ&index=3" target="_blank">发布在YouTube</a>**.
{{end}}
{{if UI == "MVC"}}
## 创建新书籍
通过本节, 你将会了解如何创建一个 modal form 来实现新增书籍的功能. 最终成果如下图所示:
通过本节, 你将会了解如何创建一个 modal form 实现新增书籍的功能. model dialog将如下图所示:
![bookstore-create-dialog](./images/bookstore-create-dialog-2.png)
@ -66,7 +63,7 @@ end
#### CreateModal.cshtml.cs
打开 `CreateModal.cshtml.cs` 代码文件,用如下代码替换 `CreateModalModel` 类的实现:
打开 `CreateModal.cshtml.cs` 代码文件(`CreateModalModel` 类),替换成以下代码:
````C#
using System.Threading.Tasks;
@ -101,10 +98,10 @@ namespace Acme.BookStore.Web.Pages.Books
}
````
* 该类派生于 `BookStorePageModel` 而非默认的 `PageModel`. `BookStorePageModel` 继承了 `PageModel` 并且添加了一些可以被你的page model类使用的通用属性和方法.
* 该类派生于 `BookStorePageModel` 而非默认的 `PageModel`. `BookStorePageModel` 间接继承了 `PageModel` 并且添加了一些可以被你的page model类使用的通用属性和方法.
* `Book` 属性上的 `[BindProperty]` 特性将post请求提交上来的数据绑定到该属性上.
* 该类通过构造函数注入了 `IBookAppService` 应用服务,并且在 `OnPostAsync` 处理程序中调用了服务的 `CreateAsync` 方法.
* 它在 `OnGet` 方法中创建一个新的 `CreateUpdateBookDto` 对象。 ASP.NET Core不需要像这样创建一个新实例就可以正常工作. 但是它不会为你创建实例,并且如果你的类在类构造函数中具有一些默认值分配或代码执行,它们将无法工作. 对于这种情况,我们为某些 `CreateUpdateBookDto` 属性设置了默认值.
* 它在 `OnGet` 方法中创建一个新的 `CreateUpdateBookDto` 对象。 ASP.NET Core不需要像这样创建一个新实例就可以正常工作. 但是它不会为你创建实例,并且如果你的类在类构造函数中赋值一些默认值或执行一些代码,它们将无法工作. 对于这种情况,我们为某些 `CreateUpdateBookDto` 属性设置了默认值.
#### CreateModal.cshtml
@ -134,10 +131,9 @@ namespace Acme.BookStore.Web.Pages.Books
* 这个 modal 使用 `abp-dynamic-form` [tag Helper](../UI/AspNetCore/Tag-Helpers/Dynamic-Forms.md) 根据 `CreateBookViewModel` 类自动构建了表单.
* `abp-model` 指定了 `Book` 属性为模型对象.
* `data-ajaxForm` 设置了表单通过AJAX提交,而不是经典的页面回发.
* `abp-form-content` tag helper 作为表单控件渲染位置的占位符 (这是可选的,只有你在 `abp-dynamic-form` 中像本示例这样添加了其他内容才需要).
> 提示: 就像在本示例中一样,`Layout` 应该为 `null`,因为当通过AJAX加载模态时,我们不希望包括所有布局.
> 提示: 就像在本示例中一样,`Layout` 应该为 `null`,因为当通过AJAX加载模态窗口时,我们不希望包括所有布局.
### 添加 "New book" 按钮
@ -195,9 +191,9 @@ namespace Acme.BookStore.Web.Pages.Books
如下图所示,只是在表格 **右上方** 添加了 **New book** 按钮:
![bookstore-new-book-button](./images/bookstore-new-book-button-2.png)
![bookstore-new-book-button](images/bookstore-new-book-button-2.png)
打开 `Pages/book/index.js``datatable` 配置代码后面添加如下代码:
打开 `Pages/Book/Index.js``datatable` 配置代码后面添加如下代码:
````js
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
@ -212,9 +208,9 @@ $('#NewBookButton').click(function (e) {
});
````
* `abp.ModalManager` 是一个在客户端打开和管理modal的辅助类.它基于Twitter Bootstrap的标准modal组件通过简化的API抽象隐藏了许多细节.
* `abp.ModalManager` 是一个在客户端管理modal的辅助类.它内部使用了Twitter Bootstrap的标准modal组件,但通过简化的API抽象了许多细节.
* `createModal.onResult(...)` 用于在创建书籍后刷新数据表格.
* `createModal.open();` 用于打开模态创建新书籍.
* `createModal.open();` 用于打开modal创建新书籍.
`Index.js` 的内容最终如下所示:
@ -335,8 +331,8 @@ namespace Acme.BookStore.Web.Pages.Books
}
````
* `[HiddenInput]``[BindProperty]` 是标准的 ASP.NET Core MVC 特性.这里启用 `SupportsGet` 从Http请求的查询字符串中获取Id的值.
* 在 `OnGetAsync` 方法中,`BookAppService.GetAsync` 方法返回的 `BookDto` 映射成 `CreateUpdateBookDto` 并赋值给Book属性.
* `[HiddenInput]``[BindProperty]` 是标准的 ASP.NET Core MVC 特性.这里启用 `SupportsGet` 从Http请求的查询字符串参数中获取Id的值.
* 在 `OnGetAsync` 方法中, 我们从 `BookAppService` 获得 `BookDto` ,并将它映射成DTO对象 `CreateUpdateBookDto`.
* `OnPostAsync` 方法直接使用 `BookAppService.UpdateAsync` 来更新实体.
### BookDto 到 CreateUpdateBookDto 对象映射
@ -391,10 +387,10 @@ namespace Acme.BookStore.Web
这个页面内容和 `CreateModal.cshtml` 非常相似,除了以下几点:
* 它包含`id`属性的`abp-input`, 用于存储编辑书的 `id` (它是隐藏的Input)
* 它包含`id`属性的`abp-input`, 用于存储编辑书`id` (它是隐藏的Input)
* 此页面指定的post地址是`Books/EditModal`.
### 为表格添加 "操作(Actions)" 下拉菜单
### 为表格添加 "操作(Actions)" 下拉菜单
我们将为表格每行添加下拉按钮 ("Actions"):
@ -516,9 +512,9 @@ $(function () {
}
````
* `confirmMessage` 用来在实际执行 `action` 前向用户进行确认.
* 通过javascript代理方法 `acme.bookStore.books.book.delete(...)` 执行一个AJAX请求删除一个book实体.
* `abp.notify.info` 用来在执行删除操作后显示一个toastr通知信息.
* `confirmMessage` 执行 `action` 前向用户进行确认.
* `acme.bookStore.books.book.delete(...)` 执行一个AJAX请求删除一个book.
* `abp.notify.info` 执行删除操作后显示一个通知信息.
由于我们使用了两个新的本地化文本(`BookDeletionConfirmationMessage`和`SuccesslyDeleted`),因此你需要将它们添加到本地化文件(`Acme.BookStore.Domain.Shared`项目的`Localization/BookStore`文件夹下的`en.json`):
@ -640,7 +636,7 @@ $(function () {
## 创建新书籍
下面的章节中,你将学习到如何创建一个新的模态对话框来新增书籍.
下面的章节中,你将学习到如何创建一个新的模态窗口新增书籍.
### BookComponent
@ -649,8 +645,7 @@ $(function () {
```js
import { ListService, PagedResultDto } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
import { BookDto } from './models';
import { BookService } from './services';
import { BookService, BookDto } from '@proxy/books';
@Component({
selector: 'app-book',
@ -666,7 +661,7 @@ export class BookComponent implements OnInit {
constructor(public readonly list: ListService, private bookService: BookService) {}
ngOnInit() {
const bookStreamCreator = (query) => this.bookService.getListByInput(query);
const bookStreamCreator = (query) => this.bookService.getList(query);
this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
this.book = response;
@ -680,7 +675,8 @@ export class BookComponent implements OnInit {
}
```
* 我们定义了一个名为 `isModalOpen` 的变量和 `createBook` 方法.
* 我们定义了一个名为 `isModalOpen` 的属性和 `createBook` 方法.
打开 `/src/app/book/book.component.html` 做以下更改:
@ -690,9 +686,9 @@ export class BookComponent implements OnInit {
<div class="row">
<div class="col col-md-6">
<h5 class="card-title">{%{{{ '::Menu:Books' | abpLocalization }}}%}</h5>
</div>
</div>
<div class="text-right col col-md-6">
<!-- Add the "new book" button here -->
<div class="text-lg-right pt-2">
<button id="create" class="btn btn-primary" type="button" (click)="createBook()">
@ -700,7 +696,7 @@ export class BookComponent implements OnInit {
<span>{%{{{ "::NewBook" | abpLocalization }}}%}</span>
</button>
</div>
</div>
</div>
</div>
@ -726,11 +722,11 @@ export class BookComponent implements OnInit {
```
* 添加了 `New book` 按钮到卡片头部.
* 添加了 `abp-modal` 渲染模态框,允许用户创建新书. `abp-modal` 是显示模态框的预构建组件. 你也可以使用其它方法显示模态框,但 `abp-modal` 提供了一些附加的好处.
* 添加了 `abp-modal` 渲染模态框,允许用户创建新书. `abp-modal` 是显示模态框的预构建组件. 你也可以使用其它方法显示模态框,但 `abp-modal` 提供了一些额外的好处.
你可以打开浏览器,点击**New book**按钮看到模态框.
![Empty modal for new book](./images/bookstore-empty-new-book-modal.png)
![Empty modal for new book](images/bookstore-empty-new-book-modal.png)
### 添加响应式表单
@ -741,8 +737,7 @@ export class BookComponent implements OnInit {
```js
import { ListService, PagedResultDto } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
import { BookDto, BookType } from './models'; // add BookType
import { BookService } from './services';
import { BookService, BookDto, bookTypeOptions } from '@proxy/books'; // add bookTypeOptions
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // add this
@Component({
@ -756,12 +751,8 @@ export class BookComponent implements OnInit {
form: FormGroup; // add this line
bookType = BookType; // add this line
// add bookTypes as a list of BookType enum members
bookTypes = Object.keys(this.bookType).filter(
(key) => typeof this.bookType[key] === 'number'
);
bookTypes = bookTypeOptions;
isModalOpen = false;
@ -772,7 +763,7 @@ export class BookComponent implements OnInit {
) {}
ngOnInit() {
const bookStreamCreator = (query) => this.bookService.getListByInput(query);
const bookStreamCreator = (query) => this.bookService.getList(query);
this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
this.book = response;
@ -800,7 +791,7 @@ export class BookComponent implements OnInit {
return;
}
this.bookService.createByInput(this.form.value).subscribe(() => {
this.bookService.create(this.form.value).subscribe(() => {
this.isModalOpen = false;
this.form.reset();
this.list.get();
@ -809,12 +800,11 @@ export class BookComponent implements OnInit {
}
```
* 导入了 `FormGroup, FormBuilder and Validators`.
* 从` @angular/forms `导入了 `FormGroup, FormBuilder and Validators`.
* 添加了 `form: FormGroup` 变量.
* 添加了 `bookType` 属性,你可以从模板中获取 `BookType` 枚举成员.
* 添加了 `bookTypes` 属性作为 `BookType` 枚举成员列表. 将在表单选项中使用.
* 我们注入了 `fb: FormBuilder` 服务到构造函数. [FormBuilder](https://angular.io/api/forms/FormBuilder) 服务为生成控件提供了方便的方法. 它减少了构建复杂表单所需的样板文件的数量.
* 我们添加了 `buildForm` 方法到文件末尾, 在 `createBook` 方法调用 `buildForm()` 方法. 该方法创建一个响应式表单去创建新书.
* 我们注入了 `FormBuilder` 到构造函数. [FormBuilder](https://angular.io/api/forms/FormBuilder) 提供了简便的方法生成表单控件. 它减少了构建复杂表单所需的样板文件的数量.
* 我们添加了 `buildForm` 方法到文件末尾, 在 `createBook` 方法调用 `buildForm()` 方法.
* 添加了`save` 方法.
打开 `/src/app/book/book.component.html`,使用以下内容替换 `<ng-template #abpBody> </ng-template>`:
@ -836,7 +826,7 @@ export class BookComponent implements OnInit {
<label for="book-type">Type</label><span> * </span>
<select class="form-control" id="book-type" formControlName="type">
<option [ngValue]="null">Select a book type</option>
<option [ngValue]="bookType[type]" *ngFor="let type of bookTypes"> {%{{{ type }}}%}</option>
<option [ngValue]="type.value" *ngFor="let type of bookTypes"> {%{{{ type.key }}}%}</option>
</select>
</div>
@ -897,13 +887,12 @@ export class BookModule { }
* 我们导入了 `NgbDatepickerModule` 来使用日期选择器.
打开 `/src/app/book/book.component.ts` 使用以内容替换:
打开 `/src/app/book/book.component.ts` 使用以内容替换:
```js
import { ListService, PagedResultDto } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
import { BookDto, BookType } from './models';
import { BookService } from './services';
import { BookService, BookDto, bookTypeOptions } from '@proxy/books';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
// added this line
@ -923,11 +912,7 @@ export class BookComponent implements OnInit {
form: FormGroup;
bookType = BookType;
bookTypes = Object.keys(this.bookType).filter(
(key) => typeof this.bookType[key] === 'number'
);
bookTypes = bookTypeOptions;
isModalOpen = false;
@ -938,7 +923,7 @@ export class BookComponent implements OnInit {
) {}
ngOnInit() {
const bookStreamCreator = (query) => this.bookService.getListByInput(query);
const bookStreamCreator = (query) => this.bookService.getList(query);
this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
this.book = response;
@ -964,7 +949,7 @@ export class BookComponent implements OnInit {
return;
}
this.bookService.createByInput(this.form.value).subscribe(() => {
this.bookService.create(this.form.value).subscribe(() => {
this.isModalOpen = false;
this.form.reset();
this.list.get();
@ -974,11 +959,11 @@ export class BookComponent implements OnInit {
```
* 导入了 `NgbDateNativeAdapter``NgbDateAdapter`.
* 我们添加了一个新的 `NgbDateAdapter` 提供程序,它将Datepicker值转换为 `Date` 类型. 有关更多详细信息,请参见[datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview).
* 我们添加了一个新的 `NgbDateAdapter` 提供程序,它将Datepicker值转换为 `Date` 类型. 更多详细信息,请参见[datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview).
现在你可以打开浏览器看到以下变化:
![Save button to the modal](./images/bookstore-new-book-form-v2.png)
![Save button to the modal](images/bookstore-new-book-form-v2.png)
## 更新书籍
@ -987,8 +972,7 @@ export class BookComponent implements OnInit {
```js
import { ListService, PagedResultDto } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
import { BookDto, BookType, CreateUpdateBookDto } from './models';
import { BookService } from './services';
import { BookService, BookDto, bookTypeOptions } from '@proxy/books';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap';
@ -1001,15 +985,11 @@ import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap
export class BookComponent implements OnInit {
book = { items: [], totalCount: 0 } as PagedResultDto<BookDto>;
selectedBook = new BookDto(); // declare selectedBook
selectedBook = {} as BookDto; // declare selectedBook
form: FormGroup;
bookType = BookType;
bookTypes = Object.keys(this.bookType).filter(
(key) => typeof this.bookType[key] === 'number'
);
bookTypes = bookTypeOptions;
isModalOpen = false;
@ -1020,7 +1000,7 @@ export class BookComponent implements OnInit {
) {}
ngOnInit() {
const bookStreamCreator = (query) => this.bookService.getListByInput(query);
const bookStreamCreator = (query) => this.bookService.getList(query);
this.list.hookToQuery(bookStreamCreator).subscribe((response) => {
this.book = response;
@ -1028,14 +1008,14 @@ export class BookComponent implements OnInit {
}
createBook() {
this.selectedBook = new BookDto(); // reset the selected book
this.selectedBook = {} as BookDto; // reset the selected book
this.buildForm();
this.isModalOpen = true;
}
// Add editBook method
editBook(id: string) {
this.bookService.getById(id).subscribe((book) => {
this.bookService.get(id).subscribe((book) => {
this.selectedBook = book;
this.buildForm();
this.isModalOpen = true;
@ -1061,8 +1041,8 @@ export class BookComponent implements OnInit {
}
const request = this.selectedBook.id
? this.bookService.updateByIdAndInput(this.form.value, this.selectedBook.id)
: this.bookService.createByInput(this.form.value);
? this.bookService.update(this.selectedBook.id, this.form.value)
: this.bookService.create(this.form.value);
request.subscribe(() => {
this.isModalOpen = false;
@ -1074,10 +1054,10 @@ export class BookComponent implements OnInit {
```
* 我们声明了类型为 `BookDto``selectedBook` 变量.
* 我们添加了 `editBook` 方法, 根据给定`Id` 设置 `selectedBook` 对象.
* 我们添加了 `editBook` 方法, 根据给定书 `Id` 设置 `selectedBook` 对象.
* 我们替换了 `buildForm` 方法使用 `selectedBook` 数据创建表单.
* 我们替换了 `createBook` 方法,设置 `selectedBook` 为空对象.
* 我们替换了 `save` 方法.
* 我们修改了 `save` 方法,同时处理新建和更新操作.
### 添加 "Actions" 下拉框到表格
@ -1111,7 +1091,7 @@ export class BookComponent implements OnInit {
在表格的第一列添加了一个 "Actions" 下拉菜单,如下图所示:
![Action buttons](./images/bookstore-actions-buttons.png)
![Action buttons](images/bookstore-actions-buttons.png)
同时如下所示更改 `ng-template #abpHeader` 部分:
@ -1147,13 +1127,13 @@ constructor(
delete(id: string) {
this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure').subscribe((status) => {
if (status === Confirmation.Status.confirm) {
this.bookService.deleteById(id).subscribe(() => this.list.get());
this.bookService.delete(id).subscribe(() => this.list.get());
}
});
}
```
* 我们入了 `ConfirmationService`.
* 我们入了 `ConfirmationService`.
* 我们注入了 `ConfirmationService` 到构造函数.
* 添加了 `delete` 方法.
@ -1161,6 +1141,7 @@ delete(id: string) {
### 添加删除按钮:
打开 `/src/app/book/book.component.html` 修改 `ngbDropdownMenu` 添加删除按钮:
```html
@ -1174,14 +1155,445 @@ delete(id: string) {
最终操作下拉框UI看起来如下:
![bookstore-final-actions-dropdown](./images/bookstore-final-actions-dropdown.png)
![bookstore-final-actions-dropdown](images/bookstore-final-actions-dropdown.png)
点击 `delete` 操作调用 `delete` 方法,然后显示一个确认弹层如下图所示.
![bookstore-confirmation-popup](images/bookstore-confirmation-popup.png)
{{end}}
{{if UI == "Blazor" || UI == "BlazorServer"}}
## 创建新书籍
通过本节, 你将会了解如何创建一个模态窗口实现新增书籍的功能. 因为我们已经从 `AbpCrudPageBase` 继承, 所以只需要开发视图部分.
### 添加 "New Button" 按钮
打开 `Books.razor` 替换 `<CardHeader>` 部分为以下代码:
````xml
<CardHeader>
<Row Class="justify-content-between">
<Column ColumnSize="ColumnSize.IsAuto">
<h2>@L["Books"]</h2>
</Column>
<Column ColumnSize="ColumnSize.IsAuto">
<Button Color="Color.Primary"
Clicked="OpenCreateModalAsync">@L["NewBook"]</Button>
</Column>
</Row>
</CardHeader>
````
如下图所示,卡片头 **右侧** 添加了 **New book** 按钮:
![blazor-add-book-button](images/blazor-add-book-button.png)
现在, 我们可以添加点击按钮后打开的模态窗口了.
### 书籍创建模态窗口
打开 `Books.razor`, 添加以下代码到页面底部:
````xml
<Modal @ref="@CreateModal">
<ModalBackdrop />
<ModalContent IsCentered="true">
<Form>
<ModalHeader>
<ModalTitle>@L["NewBook"]</ModalTitle>
<CloseButton Clicked="CloseCreateModalAsync"/>
</ModalHeader>
<ModalBody>
<Validations @ref="@CreateValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["Name"]</FieldLabel>
<TextEdit @bind-Text="@NewEntity.Name">
<Feedback>
<ValidationError/>
</Feedback>
</TextEdit>
</Field>
</Validation>
<Field>
<FieldLabel>@L["Type"]</FieldLabel>
<Select TValue="BookType" @bind-SelectedValue="@NewEntity.Type">
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
<SelectItem TValue="BookType" Value="@((BookType) bookTypeValue)">
@L[$"Enum:BookType:{bookTypeValue}"]
</SelectItem>
}
</Select>
</Field>
<Field>
<FieldLabel>@L["PublishDate"]</FieldLabel>
<DateEdit TValue="DateTime" @bind-Date="NewEntity.PublishDate"/>
</Field>
<Field>
<FieldLabel>@L["Price"]</FieldLabel>
<NumericEdit TValue="float" @bind-Value="NewEntity.Price"/>
</Field>
</Validations>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary"
Clicked="CloseCreateModalAsync">@L["Cancel"]</Button>
<Button Color="Color.Primary"
Type="@ButtonType.Submit"
PreventDefaultOnSubmit="true"
Clicked="CreateEntityAsync">@L["Save"]</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>
````
这段代码需要一个服务; 在文件顶部, `@inherits...` 行前, 注入 `AbpBlazorMessageLocalizerHelper<T>`:
````csharp
@inject AbpBlazorMessageLocalizerHelper<BookStoreResource> LH
````
* 表单实现了验证功能, `AbpBlazorMessageLocalizerHelper` 用于本地化验证消息.
* `CreateModal` 对象, `CloseCreateModalAsync``CreateEntityAsync` 方法定义在基类中. 参阅 [Blazorise文档](https://blazorise.com/docs/) 以深入理解 `Modal` 和其它组件.
这就是全部了. 运行应用程序, 尝试添加一本新书.
![blazor-new-book-modal](images/blazor-new-book-modal.png)
## 更新书籍
编辑书籍与新建书籍很类似.
点击 `delete` 动作调用 `delete` 方法,然后无法显示一个确认弹层如下图所示.
### 操作下拉菜单
![bookstore-confirmation-popup](./images/bookstore-confirmation-popup.png)
打开 `Books.razor` , 在 `DataGridColumns` 中添加以下 `DataGridEntityActionsColumn` 作为第一项:
````xml
<DataGridEntityActionsColumn TItem="BookDto" @ref="@EntityActionsColumn">
<DisplayTemplate>
<EntityActions TItem="BookDto" EntityActionsColumn="@EntityActionsColumn">
<EntityAction TItem="BookDto"
Text="@L["Edit"]"
Clicked="() => OpenEditModalAsync(context)" />
</EntityActions>
</DisplayTemplate>
</DataGridEntityActionsColumn>
````
* `OpenEditModalAsync` 定义在基类中, 它接收实体(书籍)参数, 编辑这个实体.
`DataGridEntityActionsColumn` 组件用于显示 `DataGrid` 每一行中的"操作" 下拉菜单. 如果其中只有唯一的操作, `DataGridEntityActionsColumn` 显示 **唯一按钮**, 而不是下拉菜单.
![blazor-edit-book-action](images/blazor-edit-book-action-2.png)
### 编辑模态窗口
我们现在可以定义一个模态窗口编辑书籍. 加入下面的代码到 `Books.razor` 页面的底部:
````xml
<Modal @ref="@EditModal">
<ModalBackdrop />
<ModalContent IsCentered="true">
<Form>
<ModalHeader>
<ModalTitle>@EditingEntity.Name</ModalTitle>
<CloseButton Clicked="CloseEditModalAsync"/>
</ModalHeader>
<ModalBody>
<Validations @ref="@EditValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["Name"]</FieldLabel>
<TextEdit @bind-Text="@EditingEntity.Name">
<Feedback>
<ValidationError/>
</Feedback>
</TextEdit>
</Field>
</Validation>
<Field>
<FieldLabel>@L["Type"]</FieldLabel>
<Select TValue="BookType" @bind-SelectedValue="@EditingEntity.Type">
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
<SelectItem TValue="BookType" Value="@((BookType) bookTypeValue)">
@L[$"Enum:BookType:{bookTypeValue}"]
</SelectItem>
}
</Select>
</Field>
<Field>
<FieldLabel>@L["PublishDate"]</FieldLabel>
<DateEdit TValue="DateTime" @bind-Date="EditingEntity.PublishDate"/>
</Field>
<Field>
<FieldLabel>@L["Price"]</FieldLabel>
<NumericEdit TValue="float" @bind-Value="EditingEntity.Price"/>
</Field>
</Validations>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary"
Clicked="CloseEditModalAsync">@L["Cancel"]</Button>
<Button Color="Color.Primary"
Type="@ButtonType.Submit"
PreventDefaultOnSubmit="true"
Clicked="UpdateEntityAsync">@L["Save"]</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>
````
### AutoMapper 配置
基类 `AbpCrudPageBase` 使用 [对象到对象映射](../Object-To-Object-Mapping.md) 系统将 `BookDto` 对象转化为`CreateUpdateBookDto` 对象. 因此, 我们需要定义映射.
打开 `Acme.BookStore.Blazor` 项目中的 `BookStoreBlazorAutoMapperProfile `, 替换成以下内容:
````csharp
using Acme.BookStore.Books;
using AutoMapper;
namespace Acme.BookStore.Blazor
{
public class BookStoreBlazorAutoMapperProfile : Profile
{
public BookStoreBlazorAutoMapperProfile()
{
CreateMap<BookDto, CreateUpdateBookDto>();
}
}
}
````
* `CreateMap<BookDto, CreateUpdateBookDto>();` 行用于定义映射.
### 测试编辑模态窗口
你可以运行程序并尝试编辑一本书.
![blazor-edit-book-modal](images/blazor-edit-book-modal.png)
> 提示: 尝试保留 *Name* 字段为空并提交表单, 将显示验证错误消息.
## 删除书籍
打开 `Books.razor` 页面, 在 `EntityActions` 中的"编辑" 操作下面加入以下的 `EntityAction`:
````xml
<EntityAction TItem="BookDto"
Text="@L["Delete"]"
Clicked="() => DeleteEntityAsync(context)"
ConfirmationMessage="() => GetDeleteConfirmationMessage(context)" />
````
* `DeleteEntityAsync` 定义在基类中. 通过向服务器发起请求删除实体.
* `ConfirmationMessage` 执行操作前显示确认消息的回调函数.
* `GetDeleteConfirmationMessage` 定义在基类中. 你可以覆写这个方法 (或传递其它值给 `ConfirmationMessage` 参数) 以定制本地化消息.
因为"操作" 按钮现在有了两个操作, 变成了下拉菜单:
![blazor-edit-book-action](images/blazor-delete-book-action.png)
运行程序并尝试删除一本书.
## 完整的 CRUD UI 代码
下面是完整的创建图书管理CRUD页面的代码, 这些代码在上面是分成两部分开发的:
````xml
@page "/books"
@using Volo.Abp.Application.Dtos
@using Acme.BookStore.Books
@using Acme.BookStore.Localization
@using Microsoft.Extensions.Localization
@using Volo.Abp.AspNetCore.Components.Web
@inject IStringLocalizer<BookStoreResource> L
@inject AbpBlazorMessageLocalizerHelper<BookStoreResource> LH
@inherits AbpCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>
<Card>
<CardHeader>
<Row Class="justify-content-between">
<Column ColumnSize="ColumnSize.IsAuto">
<h2>@L["Books"]</h2>
</Column>
<Column ColumnSize="ColumnSize.IsAuto">
<Button Color="Color.Primary"
Clicked="OpenCreateModalAsync">@L["NewBook"]</Button>
</Column>
</Row>
</CardHeader>
<CardBody>
<DataGrid TItem="BookDto"
Data="Entities"
ReadData="OnDataGridReadAsync"
CurrentPage="CurrentPage"
TotalItems="TotalCount"
ShowPager="true"
PageSize="PageSize">
<DataGridColumns>
<DataGridEntityActionsColumn TItem="BookDto" @ref="@EntityActionsColumn">
<DisplayTemplate>
<EntityActions TItem="BookDto" EntityActionsColumn="@EntityActionsColumn">
<EntityAction TItem="BookDto"
Text="@L["Edit"]"
Clicked="() => OpenEditModalAsync(context)" />
<EntityAction TItem="BookDto"
Text="@L["Delete"]"
Clicked="() => DeleteEntityAsync(context)"
ConfirmationMessage="()=>GetDeleteConfirmationMessage(context)" />
</EntityActions>
</DisplayTemplate>
</DataGridEntityActionsColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.Name)"
Caption="@L["Name"]"></DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.Type)"
Caption="@L["Type"]">
<DisplayTemplate>
@L[$"Enum:BookType:{(int) context.Type}"]
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.PublishDate)"
Caption="@L["PublishDate"]">
<DisplayTemplate>
@context.PublishDate.ToShortDateString()
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.Price)"
Caption="@L["Price"]">
</DataGridColumn>
<DataGridColumn TItem="BookDto"
Field="@nameof(BookDto.CreationTime)"
Caption="@L["CreationTime"]">
<DisplayTemplate>
@context.CreationTime.ToLongDateString()
</DisplayTemplate>
</DataGridColumn>
</DataGridColumns>
</DataGrid>
</CardBody>
</Card>
<Modal @ref="@CreateModal">
<ModalBackdrop />
<ModalContent IsCentered="true">
<Form>
<ModalHeader>
<ModalTitle>@L["NewBook"]</ModalTitle>
<CloseButton Clicked="CloseCreateModalAsync"/>
</ModalHeader>
<ModalBody>
<Validations @ref="@CreateValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["Name"]</FieldLabel>
<TextEdit @bind-Text="@NewEntity.Name">
<Feedback>
<ValidationError/>
</Feedback>
</TextEdit>
</Field>
</Validation>
<Field>
<FieldLabel>@L["Type"]</FieldLabel>
<Select TValue="BookType" @bind-SelectedValue="@NewEntity.Type">
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
<SelectItem TValue="BookType" Value="@((BookType) bookTypeValue)">
@L[$"Enum:BookType:{bookTypeValue}"]
</SelectItem>
}
</Select>
</Field>
<Field>
<FieldLabel>@L["PublishDate"]</FieldLabel>
<DateEdit TValue="DateTime" @bind-Date="NewEntity.PublishDate"/>
</Field>
<Field>
<FieldLabel>@L["Price"]</FieldLabel>
<NumericEdit TValue="float" @bind-Value="NewEntity.Price"/>
</Field>
</Validations>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary"
Clicked="CloseCreateModalAsync">@L["Cancel"]</Button>
<Button Color="Color.Primary"
Type="@ButtonType.Submit"
PreventDefaultOnSubmit="true"
Clicked="CreateEntityAsync">@L["Save"]</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>
<Modal @ref="@EditModal">
<ModalBackdrop />
<ModalContent IsCentered="true">
<Form>
<ModalHeader>
<ModalTitle>@EditingEntity.Name</ModalTitle>
<CloseButton Clicked="CloseEditModalAsync"/>
</ModalHeader>
<ModalBody>
<Validations @ref="@EditValidationsRef" Model="@NewEntity" ValidateOnLoad="false">
<Validation MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@L["Name"]</FieldLabel>
<TextEdit @bind-Text="@EditingEntity.Name">
<Feedback>
<ValidationError/>
</Feedback>
</TextEdit>
</Field>
</Validation>
<Field>
<FieldLabel>@L["Type"]</FieldLabel>
<Select TValue="BookType" @bind-SelectedValue="@EditingEntity.Type">
@foreach (int bookTypeValue in Enum.GetValues(typeof(BookType)))
{
<SelectItem TValue="BookType" Value="@((BookType) bookTypeValue)">
@L[$"Enum:BookType:{bookTypeValue}"]
</SelectItem>
}
</Select>
</Field>
<Field>
<FieldLabel>@L["PublishDate"]</FieldLabel>
<DateEdit TValue="DateTime" @bind-Date="EditingEntity.PublishDate"/>
</Field>
<Field>
<FieldLabel>@L["Price"]</FieldLabel>
<NumericEdit TValue="float" @bind-Value="EditingEntity.Price"/>
</Field>
</Validations>
</ModalBody>
<ModalFooter>
<Button Color="Color.Secondary"
Clicked="CloseEditModalAsync">@L["Cancel"]</Button>
<Button Color="Color.Primary"
Type="@ButtonType.Submit"
PreventDefaultOnSubmit="true"
Clicked="UpdateEntityAsync">@L["Save"]</Button>
</ModalFooter>
</Form>
</ModalContent>
</Modal>
````
{{end}}
## 下一章
查看本教程的[下一章](Part-4.md).
查看本教程的[下一章](Part-4.md).

60
docs/zh-Hans/Tutorials/Part-4.md

@ -2,27 +2,10 @@
````json
//[doc-params]
{
"UI": ["MVC","NG"],
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
{{
if UI == "MVC"
UI_Text="mvc"
else if UI == "NG"
UI_Text="angular"
else
UI_Text="?"
end
if DB == "EF"
DB_Text="Entity Framework Core"
else if DB == "Mongo"
DB_Text="MongoDB"
else
DB_Text="?"
end
}}
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
@ -45,16 +28,32 @@ end
## 下载源码
本教程根据你的**UI** 和 **Database**偏好有多个版,我们准备了两种可供下载的源码组合:
本教程根据你的**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=aidRB4YFDLM&list=PLsNclT2aHJcPNaCf7Io3DbMN6yAk_DgWJ&index=4" target="_blank">发布在YouTube</a>**.
{{end}}
## 解决方案中的测试项目
这一部分涵盖了 **服务器端** 测试. 解决方案中有多个测试项目:
![bookstore-test-projects-v2](./images/bookstore-test-projects-{{UI_Text}}.png)
![bookstore-test-projects-v2](./images/bookstore-test-projects-mvc.png)
> 根据你选择的UI和数据库, 测试项目略微有所不同. 例如, 如果选择MongoDB, 那么 `Acme.BookStore.EntityFrameworkCore.Tests` 会变为 `Acme.BookStore.MongoDB.Tests`.
每个项目用于测试相关的应用程序项目.测试项目使用以下库进行测试:
@ -64,11 +63,11 @@ end
{{if DB=="EF"}}
> 测试项目配置为使用 **SQLite内存** 作为数据库. 创建一个单独的数据库实例并使用数据种子系统进行初始化种子数据,为每个测试准备一个新的数据库.
> 测试项目配置为使用 **SQLite内存** 作为数据库. 创建一个单独的数据库实例并使用[数据种子系统](../Data-Seeding.md)初始化种子数据,为每个测试准备一个新的数据库.
{{else if DB=="Mongo"}}
> **[Mongo2Go](https://github.com/Mongo2Go/Mongo2Go)**库用于模拟MongoDB数据库. 创建一个单独的数据库实例并使用数据种子系统进行初始化种子数据,为每个测试准备一个新的数据库.
> **[Mongo2Go](https://github.com/Mongo2Go/Mongo2Go)**库用于模拟MongoDB数据库. 创建一个单独的数据库实例并使用[数据种子系统](../Data-Seeding.md)初始化种子数据,为每个测试准备一个新的数据库.
{{end}}
@ -78,12 +77,15 @@ end
## 测试 BookAppService
`Acme.BookStore.Application.Tests` 项目中创建一个名叫 `BookAppService_Tests` 的测试类:
`Acme.BookStore.Application.Tests` 项目`Books` 命名空间(文件夹)中创建一个名叫 `BookAppService_Tests` 的测试类:
````csharp
using System;
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Validation;
using Xunit;
namespace Acme.BookStore.Books
@ -129,7 +131,7 @@ public async Task Should_Create_A_Valid_Book()
{
Name = "New test book 42",
Price = 10,
PublishDate = System.DateTime.Now,
PublishDate = DateTime.Now,
Type = BookType.ScienceFiction
}
);
@ -201,7 +203,7 @@ namespace Acme.BookStore.Books
result.TotalCount.ShouldBeGreaterThan(0);
result.Items.ShouldContain(b => b.Name == "1984");
}
[Fact]
public async Task Should_Create_A_Valid_Book()
{
@ -211,7 +213,7 @@ namespace Acme.BookStore.Books
{
Name = "New test book 42",
Price = 10,
PublishDate = System.DateTime.Now,
PublishDate = DateTime.Now,
Type = BookType.ScienceFiction
}
);
@ -220,7 +222,7 @@ namespace Acme.BookStore.Books
result.Id.ShouldNotBe(Guid.Empty);
result.Name.ShouldBe("New test book 42");
}
[Fact]
public async Task Should_Not_Create_A_Book_Without_Name()
{
@ -244,7 +246,7 @@ namespace Acme.BookStore.Books
}
````
打开**测试资源管理器**(测试 -> Windows -> 测试资源管理器)并**执行**所有测试:
打开**测试资源管理器**(测试 -> Windows -> 测试资源管理器)并**执行所有**测试:
![bookstore-appservice-tests](./images/bookstore-appservice-tests.png)
@ -252,4 +254,4 @@ namespace Acme.BookStore.Books
## 下一章
查看本教程的[下一章](Part-5.md).
查看本教程的[下一章](Part-5.md).

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).

BIN
docs/zh-Hans/Tutorials/images/blazor-add-book-button.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
docs/zh-Hans/Tutorials/images/blazor-add-books-component.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
docs/zh-Hans/Tutorials/images/blazor-bookstore-book-list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
docs/zh-Hans/Tutorials/images/blazor-delete-book-action.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
docs/zh-Hans/Tutorials/images/blazor-edit-book-action-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
docs/zh-Hans/Tutorials/images/blazor-edit-book-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

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

Loading…
Cancel
Save