From 7a5ae418d594df5cce9dff9428b30f7ba8cfa027 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sun, 5 Feb 2023 13:13:51 +0800 Subject: [PATCH] feat(localization): add language&resource management ui support. --- apps/vue/src/api/localization/languages.ts | 52 ++++++++++++- .../api/localization/model/languagesModel.ts | 9 ++- .../api/localization/model/resourcesModel.ts | 12 ++- .../src/api/localization/model/textsModel.ts | 8 +- apps/vue/src/api/localization/resources.ts | 52 ++++++++++++- .../languages/components/LanguageModal.vue | 56 ++++++++++++++ .../languages/components/LanguageTable.vue | 77 ++++++++++++++++++- .../resources/components/ModalData.ts | 6 ++ .../resources/components/ResourceModal.vue | 56 ++++++++++++++ .../resources/components/ResourceTable.vue | 77 ++++++++++++++++++- .../resources/components/TableData.ts | 10 +++ .../texts/components/TextModal.vue | 2 +- .../Mvc/Localization/Resources/en.json | 3 +- .../Mvc/Localization/Resources/zh-Hans.json | 3 +- .../ILanguageAppService.cs | 2 + .../IResourceAppService.cs | 2 + .../LanguageAppService.cs | 14 +++- .../ResourceAppService.cs | 13 +++- .../Localization/Resources/en.json | 4 +- .../Localization/Resources/zh-Hans.json | 4 +- .../LanguageController.cs | 7 ++ .../ResourceController.cs | 7 ++ 22 files changed, 447 insertions(+), 29 deletions(-) create mode 100644 apps/vue/src/views/localization/languages/components/LanguageModal.vue create mode 100644 apps/vue/src/views/localization/resources/components/ResourceModal.vue diff --git a/apps/vue/src/api/localization/languages.ts b/apps/vue/src/api/localization/languages.ts index ee2971966..e5ada0d1f 100644 --- a/apps/vue/src/api/localization/languages.ts +++ b/apps/vue/src/api/localization/languages.ts @@ -1,5 +1,8 @@ import { defAbpHttp } from '/@/utils/http/abp'; -import { LanguageListResult } from './model/languagesModel'; +import { LanguageListResult, LanguageCreate, LanguageUpdate, Language } from './model/languagesModel'; + +const remoteServiceName = 'LocalizationManagement'; +const controllerName = 'Language'; enum Api { GetList = '/api/abp/localization/languages', @@ -10,3 +13,50 @@ export const getList = () => { url: Api.GetList, }); }; + +export const GetAsyncByName = (name: string) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'GetAsync', + uniqueName: 'GetAsyncByName', + params: { + name: name, + }, + }); +}; + +export const CreateAsyncByInput = (input: LanguageCreate) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'CreateAsync', + uniqueName: 'CreateAsyncByInput', + data: input, + }); +}; + +export const UpdateAsyncByNameAndInput = (name: string, input: LanguageUpdate) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'UpdateAsync', + uniqueName: 'UpdateAsyncByNameAndInput', + params: { + name: name, + }, + data: input, + }); +}; + +export const DeleteAsyncByName = (name: string) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'DeleteAsync', + uniqueName: 'DeleteAsyncByName', + params: { + name: name, + }, + }); +}; \ No newline at end of file diff --git a/apps/vue/src/api/localization/model/languagesModel.ts b/apps/vue/src/api/localization/model/languagesModel.ts index 7b2d9a9a5..546054993 100644 --- a/apps/vue/src/api/localization/model/languagesModel.ts +++ b/apps/vue/src/api/localization/model/languagesModel.ts @@ -8,12 +8,17 @@ export interface Language extends AuditedEntityDto { export interface LanguageCreateOrUpdate { enable: boolean; - cultureName: string; - uiCultureName: string; displayName: string; flagIcon: string; } +export interface LanguageCreate extends LanguageCreateOrUpdate { + cultureName: string; + uiCultureName: string; +} + +export interface LanguageUpdate extends LanguageCreateOrUpdate {} + export interface LanguageListResult extends ListResultDto {} export interface LanguagePagedResult extends PagedResultDto {} diff --git a/apps/vue/src/api/localization/model/resourcesModel.ts b/apps/vue/src/api/localization/model/resourcesModel.ts index ce2d9e1a4..c05f6ece2 100644 --- a/apps/vue/src/api/localization/model/resourcesModel.ts +++ b/apps/vue/src/api/localization/model/resourcesModel.ts @@ -1,4 +1,5 @@ export interface Resource { + id: string; name: string; displayName: string; description: string; @@ -6,11 +7,18 @@ export interface Resource { export interface ResourceCreateOrUpdate { enable: boolean; - name: string; displayName: string; - description: string; + description?: string; + defaultCultureName?: string; } +export interface ResourceCreate extends ResourceCreateOrUpdate { + name: string; +} + +export interface ResourceUpdate extends ResourceCreateOrUpdate {} + + export interface ResourceListResult extends ListResultDto {} export interface ResourcePagedResult extends PagedResultDto {} diff --git a/apps/vue/src/api/localization/model/textsModel.ts b/apps/vue/src/api/localization/model/textsModel.ts index 1f62a32cb..4bf83e957 100644 --- a/apps/vue/src/api/localization/model/textsModel.ts +++ b/apps/vue/src/api/localization/model/textsModel.ts @@ -1,12 +1,12 @@ export interface Text { - key: boolean; + key: string; value: string; cultureName: string; resourceName: string; } export interface TextDifference { - key: boolean; + key: string; value: string; cultureName: string; resourceName: string; @@ -15,7 +15,7 @@ export interface TextDifference { } export interface SetTextInput { - key: boolean; + key: string; value: string; cultureName: string; resourceName: string; @@ -24,7 +24,7 @@ export interface SetTextInput { export interface TextListResult extends ListResultDto {} export interface GetTextByKey { - key: boolean; + key: string; cultureName: string; resourceName: string; } diff --git a/apps/vue/src/api/localization/resources.ts b/apps/vue/src/api/localization/resources.ts index 7c9b7db56..32b4d497a 100644 --- a/apps/vue/src/api/localization/resources.ts +++ b/apps/vue/src/api/localization/resources.ts @@ -1,5 +1,8 @@ import { defAbpHttp } from '/@/utils/http/abp'; -import { ResourceListResult } from './model/resourcesModel'; +import { ResourceListResult, Resource, ResourceCreate, ResourceUpdate } from './model/resourcesModel'; + +const remoteServiceName = 'LocalizationManagement'; +const controllerName = 'Resource'; enum Api { GetList = '/api/abp/localization/resources', @@ -10,3 +13,50 @@ export const getList = () => { url: Api.GetList, }); }; + +export const GetAsyncByName = (name: string) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'GetAsync', + uniqueName: 'GetAsyncByName', + params: { + name: name, + }, + }); +}; + +export const CreateAsyncByInput = (input: ResourceCreate) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'CreateAsync', + uniqueName: 'CreateAsyncByInput', + data: input, + }); +}; + +export const UpdateAsyncByNameAndInput = (name: string, input: ResourceUpdate) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'UpdateAsync', + uniqueName: 'UpdateAsyncByNameAndInput', + params: { + name: name, + }, + data: input, + }); +}; + +export const DeleteAsyncByName = (name: string) => { + return defAbpHttp.request({ + service: remoteServiceName, + controller: controllerName, + action: 'DeleteAsync', + uniqueName: 'DeleteAsyncByName', + params: { + name: name, + }, + }); +}; diff --git a/apps/vue/src/views/localization/languages/components/LanguageModal.vue b/apps/vue/src/views/localization/languages/components/LanguageModal.vue new file mode 100644 index 000000000..c788896e7 --- /dev/null +++ b/apps/vue/src/views/localization/languages/components/LanguageModal.vue @@ -0,0 +1,56 @@ + + + diff --git a/apps/vue/src/views/localization/languages/components/LanguageTable.vue b/apps/vue/src/views/localization/languages/components/LanguageTable.vue index f3edf6472..272cec89a 100644 --- a/apps/vue/src/views/localization/languages/components/LanguageTable.vue +++ b/apps/vue/src/views/localization/languages/components/LanguageTable.vue @@ -1,18 +1,58 @@ diff --git a/apps/vue/src/views/localization/resources/components/ModalData.ts b/apps/vue/src/views/localization/resources/components/ModalData.ts index 4dee3b303..e537c7017 100644 --- a/apps/vue/src/views/localization/resources/components/ModalData.ts +++ b/apps/vue/src/views/localization/resources/components/ModalData.ts @@ -55,5 +55,11 @@ export function getModalFormSchemas(): FormSchema[] { label: L('DisplayName:Description'), colProps: { span: 24 }, }, + { + field: 'description', + component: 'InputTextArea', + label: L('DisplayName:Description'), + colProps: { span: 24 }, + }, ]; } diff --git a/apps/vue/src/views/localization/resources/components/ResourceModal.vue b/apps/vue/src/views/localization/resources/components/ResourceModal.vue new file mode 100644 index 000000000..954f2b398 --- /dev/null +++ b/apps/vue/src/views/localization/resources/components/ResourceModal.vue @@ -0,0 +1,56 @@ + + + diff --git a/apps/vue/src/views/localization/resources/components/ResourceTable.vue b/apps/vue/src/views/localization/resources/components/ResourceTable.vue index ed5829c10..8e634dbe0 100644 --- a/apps/vue/src/views/localization/resources/components/ResourceTable.vue +++ b/apps/vue/src/views/localization/resources/components/ResourceTable.vue @@ -1,17 +1,57 @@ diff --git a/apps/vue/src/views/localization/resources/components/TableData.ts b/apps/vue/src/views/localization/resources/components/TableData.ts index f1b99fc46..3ea166700 100644 --- a/apps/vue/src/views/localization/resources/components/TableData.ts +++ b/apps/vue/src/views/localization/resources/components/TableData.ts @@ -35,5 +35,15 @@ export function getDataColumns(): BasicColumn[] { return last.description?.localeCompare(next.description) ?? -1; }, }, + { + title: L('DisplayName:DefaultCultureName'), + dataIndex: 'defaultCultureName', + align: 'left', + width: 150, + resizable: true, + sorter: (last, next) => { + return last.defaultCultureName?.localeCompare(next.defaultCultureName) ?? -1; + }, + }, ]; } diff --git a/apps/vue/src/views/localization/texts/components/TextModal.vue b/apps/vue/src/views/localization/texts/components/TextModal.vue index b5277ce87..09c0a2295 100644 --- a/apps/vue/src/views/localization/texts/components/TextModal.vue +++ b/apps/vue/src/views/localization/texts/components/TextModal.vue @@ -47,7 +47,7 @@ resultField: 'items', labelField: 'uiCultureName', valueField: 'cultureName', - onChange: (key) => { + onSelect: (key) => { // 当文化变更时,检查键值是否有目标值 const model = unref(modelRef); if (model?.key) { diff --git a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/en.json b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/en.json index cf8f634e2..b6d2102e6 100644 --- a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/en.json +++ b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/en.json @@ -17,6 +17,7 @@ "DisplayName:UiCultureName": "Ui Culture Name", "DisplayName:DisplayName": "Display Name", "DisplayName:FlagIcon": "Flag Icon", - "DisplayName:Description": "Description" + "DisplayName:Description": "Description", + "DisplayName:DefaultCultureName": "Default Culture" } } \ No newline at end of file diff --git a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/zh-Hans.json b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/zh-Hans.json index a5c4c9553..b2eecb64d 100644 --- a/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/Resources/zh-Hans.json @@ -17,6 +17,7 @@ "DisplayName:UiCultureName": "Ui文件名称", "DisplayName:DisplayName": "显示名称", "DisplayName:FlagIcon": "旗帜图标", - "DisplayName:Description": "描述" + "DisplayName:Description": "描述", + "DisplayName:DefaultCultureName": "默认文化" } } \ No newline at end of file diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/ILanguageAppService.cs b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/ILanguageAppService.cs index d816717dc..c84ffb557 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/ILanguageAppService.cs +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/ILanguageAppService.cs @@ -6,6 +6,8 @@ namespace LINGYUN.Abp.LocalizationManagement; public interface ILanguageAppService : IApplicationService { + Task GetByNameAsync(string name); + Task CreateAsync(LanguageCreateDto input); Task UpdateAsync(string name, LanguageUpdateDto input); diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/IResourceAppService.cs b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/IResourceAppService.cs index cdfca38e4..b44dd34e1 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/IResourceAppService.cs +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application.Contracts/LINGYUN/Abp/LocalizationManagement/IResourceAppService.cs @@ -5,6 +5,8 @@ namespace LINGYUN.Abp.LocalizationManagement; public interface IResourceAppService : IApplicationService { + Task GetByNameAsync(string name); + Task CreateAsync(ResourceCreateDto input); Task UpdateAsync(string name, ResourceUpdateDto input); diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs index 1407e1008..500beea33 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Authorization; using System.Threading.Tasks; using Volo.Abp; +using Volo.Abp.ObjectMapping; namespace LINGYUN.Abp.LocalizationManagement; @@ -15,6 +16,13 @@ public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppServic _repository = repository; } + public async virtual Task GetByNameAsync(string name) + { + var language = await InternalGetByNameAsync(name); + + return ObjectMapper.Map(language); + } + [Authorize(LocalizationManagementPermissions.Language.Create)] public async virtual Task CreateAsync(LanguageCreateDto input) { @@ -41,7 +49,7 @@ public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppServic [Authorize(LocalizationManagementPermissions.Language.Delete)] public async virtual Task DeleteAsync(string name) { - var language = await GetByNameAsync(name); + var language = await InternalGetByNameAsync(name); await _repository.DeleteAsync(language); @@ -51,7 +59,7 @@ public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppServic [Authorize(LocalizationManagementPermissions.Language.Update)] public async virtual Task UpdateAsync(string name, LanguageUpdateDto input) { - var language = await GetByNameAsync(name); + var language = await InternalGetByNameAsync(name); language.SetFlagIcon(input.FlagIcon); language.SetDisplayName(input.DisplayName); @@ -63,7 +71,7 @@ public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppServic return ObjectMapper.Map(language); } - private async Task GetByNameAsync(string name) + private async Task InternalGetByNameAsync(string name) { var language = await _repository.FindByCultureNameAsync(name); diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs index 50206f337..ee88668a7 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs @@ -15,6 +15,13 @@ public class ResourceAppService : LocalizationAppServiceBase, IResourceAppServic _repository = repository; } + public async virtual Task GetByNameAsync(string name) + { + var resource = await InternalGetByNameAsync(name); + + return ObjectMapper.Map(resource); + } + [Authorize(LocalizationManagementPermissions.Resource.Create)] public async virtual Task CreateAsync(ResourceCreateDto input) { @@ -41,7 +48,7 @@ public class ResourceAppService : LocalizationAppServiceBase, IResourceAppServic [Authorize(LocalizationManagementPermissions.Resource.Delete)] public async virtual Task DeleteAsync(string name) { - var resource = await GetByNameAsync(name); + var resource = await InternalGetByNameAsync(name); await _repository.DeleteAsync(resource); @@ -51,7 +58,7 @@ public class ResourceAppService : LocalizationAppServiceBase, IResourceAppServic [Authorize(LocalizationManagementPermissions.Resource.Update)] public async virtual Task UpdateAsync(string name, ResourceUpdateDto input) { - var resource = await GetByNameAsync(name); + var resource = await InternalGetByNameAsync(name); resource.SetDisplayName(input.DisplayName); resource.SetDescription(input.Description); @@ -64,7 +71,7 @@ public class ResourceAppService : LocalizationAppServiceBase, IResourceAppServic return ObjectMapper.Map(resource); } - private async Task GetByNameAsync(string name) + private async Task InternalGetByNameAsync(string name) { var resource = await _repository.FindByNameAsync(name); diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/en.json b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/en.json index 609ef8d51..cb0f3a818 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/en.json +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/en.json @@ -17,6 +17,8 @@ "Filter": "Filter", "SaveAndNext": "Save & Next", "SearchFilter": "Search", - "Text:AddNew": "Add New Text" + "Text:AddNew": "New Text", + "Language:AddNew": "New Language", + "Resource:AddNew": "New Resource" } } \ No newline at end of file diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/zh-Hans.json index f1e1eee76..77fbe4207 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/Localization/Resources/zh-Hans.json @@ -17,6 +17,8 @@ "Filter": "过滤字符", "SaveAndNext": "保存并下一步", "SearchFilter": "请输入过滤字符", - "Text:AddNew": "添加新文档" + "Text:AddNew": "添加新文档", + "Language:AddNew": "添加新语言", + "Resource:AddNew": "添加新资源" } } \ No newline at end of file diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/LanguageController.cs b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/LanguageController.cs index 0b563571f..2e4e5d8ea 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/LanguageController.cs +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/LanguageController.cs @@ -19,6 +19,13 @@ public class LanguageController : AbpControllerBase, ILanguageAppService _service = service; } + [HttpGet] + [Route("{name}")] + public virtual Task GetByNameAsync(string name) + { + return _service.GetByNameAsync(name); + } + [HttpPost] [Authorize(LocalizationManagementPermissions.Language.Create)] public virtual Task CreateAsync(LanguageCreateDto input) diff --git a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/ResourceController.cs b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/ResourceController.cs index ba838bd49..b5639530e 100644 --- a/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/ResourceController.cs +++ b/aspnet-core/modules/lt/LINGYUN.Abp.LocalizationManagement.HttpApi/LINGYUN/Abp/LocalizationManagement/ResourceController.cs @@ -20,6 +20,13 @@ public class ResourceController : AbpControllerBase, IResourceAppService _service = service; } + [HttpGet] + [Route("{name}")] + public virtual Task GetByNameAsync(string name) + { + return _service.GetByNameAsync(name); + } + [HttpPost] [Authorize(LocalizationManagementPermissions.Resource.Create)] public virtual Task CreateAsync(ResourceCreateDto input)