committed by
GitHub
41 changed files with 970 additions and 50 deletions
@ -0,0 +1,56 @@ |
|||
<template> |
|||
<BasicModal |
|||
@register="registerModal" |
|||
:title="L('Languages')" |
|||
:can-fullscreen="false" |
|||
:width="800" |
|||
:height="500" |
|||
@ok="handleSubmit" |
|||
> |
|||
<BasicForm @register="registerForm" /> |
|||
</BasicModal> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { nextTick } from 'vue'; |
|||
import { BasicForm, useForm } from '/@/components/Form'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { useMessage } from '/@/hooks/web/useMessage'; |
|||
import { useLocalization } from '/@/hooks/abp/useLocalization'; |
|||
import { getModalFormSchemas } from './ModalData'; |
|||
import { formatToDateTime } from '/@/utils/dateUtil'; |
|||
import { Language } from '/@/api/localization/model/languagesModel'; |
|||
import { CreateAsyncByInput, UpdateAsyncByNameAndInput } from '/@/api/localization/languages'; |
|||
|
|||
const emits = defineEmits(['change', 'register']); |
|||
|
|||
const { createMessage } = useMessage(); |
|||
const { L } = useLocalization(['LocalizationManagement', 'AbpLocalization', 'AbpUi']); |
|||
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
|||
layout: 'vertical', |
|||
showActionButtonGroup: false, |
|||
schemas: getModalFormSchemas(), |
|||
transformDateFunc: (date) => { |
|||
return date ? formatToDateTime(date) : ''; |
|||
}, |
|||
}); |
|||
const [registerModal, { closeModal }] = useModalInner((data: Language) => { |
|||
nextTick(() => { |
|||
resetFields(); |
|||
setFieldsValue(data); |
|||
}); |
|||
}); |
|||
|
|||
function handleSubmit() { |
|||
validate().then((input) => { |
|||
const api = input.id |
|||
? UpdateAsyncByNameAndInput(input.cultureName, input) |
|||
: CreateAsyncByInput(input); |
|||
api.then((dto) => { |
|||
createMessage.success(L('SuccessfullySaved')); |
|||
emits('change', dto); |
|||
closeModal(); |
|||
}); |
|||
}); |
|||
} |
|||
</script> |
|||
@ -0,0 +1,56 @@ |
|||
<template> |
|||
<BasicModal |
|||
@register="registerModal" |
|||
:title="L('Resources')" |
|||
:can-fullscreen="false" |
|||
:width="800" |
|||
:height="500" |
|||
@ok="handleSubmit" |
|||
> |
|||
<BasicForm @register="registerForm" /> |
|||
</BasicModal> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { nextTick } from 'vue'; |
|||
import { BasicForm, useForm } from '/@/components/Form'; |
|||
import { BasicModal, useModalInner } from '/@/components/Modal'; |
|||
import { useMessage } from '/@/hooks/web/useMessage'; |
|||
import { useLocalization } from '/@/hooks/abp/useLocalization'; |
|||
import { getModalFormSchemas } from './ModalData'; |
|||
import { formatToDateTime } from '/@/utils/dateUtil'; |
|||
import { Resource } from '/@/api/localization/model/resourcesModel'; |
|||
import { CreateAsyncByInput, UpdateAsyncByNameAndInput } from '/@/api/localization/resources'; |
|||
|
|||
const emits = defineEmits(['change', 'register']); |
|||
|
|||
const { createMessage } = useMessage(); |
|||
const { L } = useLocalization(['LocalizationManagement', 'AbpUi']); |
|||
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({ |
|||
layout: 'vertical', |
|||
showActionButtonGroup: false, |
|||
schemas: getModalFormSchemas(), |
|||
transformDateFunc: (date) => { |
|||
return date ? formatToDateTime(date) : ''; |
|||
}, |
|||
}); |
|||
const [registerModal, { closeModal }] = useModalInner((data: Resource) => { |
|||
nextTick(() => { |
|||
resetFields(); |
|||
setFieldsValue(data); |
|||
}); |
|||
}); |
|||
|
|||
function handleSubmit() { |
|||
validate().then((input) => { |
|||
const api = input.id |
|||
? UpdateAsyncByNameAndInput(input.name, input) |
|||
: CreateAsyncByInput(input); |
|||
api.then((dto) => { |
|||
createMessage.success(L('SuccessfullySaved')); |
|||
emits('change', dto); |
|||
closeModal(); |
|||
}); |
|||
}); |
|||
} |
|||
</script> |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
public interface ILanguageAppService : IApplicationService |
|||
{ |
|||
Task<LanguageDto> GetByNameAsync(string name); |
|||
|
|||
Task<LanguageDto> CreateAsync(LanguageCreateDto input); |
|||
|
|||
Task<LanguageDto> UpdateAsync(string name, LanguageUpdateDto input); |
|||
|
|||
Task DeleteAsync(string name); |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
public interface IResourceAppService : IApplicationService |
|||
{ |
|||
Task<ResourceDto> GetByNameAsync(string name); |
|||
|
|||
Task<ResourceDto> CreateAsync(ResourceCreateDto input); |
|||
|
|||
Task<ResourceDto> UpdateAsync(string name, ResourceUpdateDto input); |
|||
|
|||
Task DeleteAsync(string name); |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
public class LanguageCreateDto : LanguageCreateOrUpdateDto |
|||
{ |
|||
[Required] |
|||
[DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxCultureNameLength))] |
|||
public string CultureName { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxUiCultureNameLength))] |
|||
public string UiCultureName { get; set; } |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
public abstract class LanguageCreateOrUpdateDto |
|||
{ |
|||
[Required] |
|||
[DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxDisplayNameLength))] |
|||
public string DisplayName { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxFlagIconLength))] |
|||
public string FlagIcon { get; set; } |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
public class LanguageDto : AuditedEntityDto<Guid> |
|||
{ |
|||
public string CultureName { get; set; } |
|||
public string UiCultureName { get; set; } |
|||
public string DisplayName { get; set; } |
|||
public string FlagIcon { get; set; } |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
public class LanguageUpdateDto : LanguageCreateOrUpdateDto |
|||
{ |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
public class ResourceCreateDto : ResourceCreateOrUpdateDto |
|||
{ |
|||
[Required] |
|||
[DynamicStringLength(typeof(ResourceConsts), nameof(ResourceConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
public abstract class ResourceCreateOrUpdateDto |
|||
{ |
|||
public bool Enable { get; set; } = true; |
|||
|
|||
[DynamicStringLength(typeof(ResourceConsts), nameof(ResourceConsts.MaxNameLength))] |
|||
public string DisplayName { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(ResourceConsts), nameof(ResourceConsts.MaxNameLength))] |
|||
public string Description { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(ResourceConsts), nameof(ResourceConsts.MaxNameLength))] |
|||
public string DefaultCultureName { get; set; } |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
public class ResourceDto : AuditedEntityDto<Guid> |
|||
{ |
|||
public bool Enable { get; set; } |
|||
public string Name { get; set; } |
|||
public string DisplayName { get; set; } |
|||
public string Description { get; set; } |
|||
public string DefaultCultureName { get; set; } |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
public class ResourceUpdateDto : ResourceCreateOrUpdateDto |
|||
{ |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using LINGYUN.Abp.LocalizationManagement.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.ObjectMapping; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Language.Default)] |
|||
public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppService |
|||
{ |
|||
private readonly ILanguageRepository _repository; |
|||
|
|||
public LanguageAppService(ILanguageRepository repository) |
|||
{ |
|||
_repository = repository; |
|||
} |
|||
|
|||
public async virtual Task<LanguageDto> GetByNameAsync(string name) |
|||
{ |
|||
var language = await InternalGetByNameAsync(name); |
|||
|
|||
return ObjectMapper.Map<Language, LanguageDto>(language); |
|||
} |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Language.Create)] |
|||
public async virtual Task<LanguageDto> CreateAsync(LanguageCreateDto input) |
|||
{ |
|||
if (_repository.FindByCultureNameAsync(input.CultureName) != null) |
|||
{ |
|||
throw new BusinessException(LocalizationErrorCodes.Language.NameAlreadyExists) |
|||
.WithData(nameof(Language.CultureName), input.CultureName); |
|||
} |
|||
|
|||
var language = new Language( |
|||
GuidGenerator.Create(), |
|||
input.CultureName, |
|||
input.UiCultureName, |
|||
input.DisplayName, |
|||
input.FlagIcon); |
|||
|
|||
language = await _repository.InsertAsync(language); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<Language, LanguageDto>(language); |
|||
} |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Language.Delete)] |
|||
public async virtual Task DeleteAsync(string name) |
|||
{ |
|||
var language = await InternalGetByNameAsync(name); |
|||
|
|||
await _repository.DeleteAsync(language); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Language.Update)] |
|||
public async virtual Task<LanguageDto> UpdateAsync(string name, LanguageUpdateDto input) |
|||
{ |
|||
var language = await InternalGetByNameAsync(name); |
|||
|
|||
language.SetFlagIcon(input.FlagIcon); |
|||
language.SetDisplayName(input.DisplayName); |
|||
|
|||
await _repository.UpdateAsync(language); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<Language, LanguageDto>(language); |
|||
} |
|||
|
|||
private async Task<Language> InternalGetByNameAsync(string name) |
|||
{ |
|||
var language = await _repository.FindByCultureNameAsync(name); |
|||
|
|||
return language ?? throw new BusinessException(LocalizationErrorCodes.Language.NameNotFoundOrStaticNotAllowed) |
|||
.WithData(nameof(Language.CultureName), name); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using LINGYUN.Abp.LocalizationManagement.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Resource.Default)] |
|||
public class ResourceAppService : LocalizationAppServiceBase, IResourceAppService |
|||
{ |
|||
private readonly IResourceRepository _repository; |
|||
|
|||
public ResourceAppService(IResourceRepository repository) |
|||
{ |
|||
_repository = repository; |
|||
} |
|||
|
|||
public async virtual Task<ResourceDto> GetByNameAsync(string name) |
|||
{ |
|||
var resource = await InternalGetByNameAsync(name); |
|||
|
|||
return ObjectMapper.Map<Resource, ResourceDto>(resource); |
|||
} |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Resource.Create)] |
|||
public async virtual Task<ResourceDto> CreateAsync(ResourceCreateDto input) |
|||
{ |
|||
if (_repository.FindByNameAsync(input.Name) != null) |
|||
{ |
|||
throw new BusinessException(LocalizationErrorCodes.Resource.NameAlreadyExists) |
|||
.WithData(nameof(Resource.Name), input.Name); |
|||
} |
|||
|
|||
var resource = new Resource( |
|||
GuidGenerator.Create(), |
|||
input.Name, |
|||
input.DisplayName, |
|||
input.Description, |
|||
input.DefaultCultureName); |
|||
|
|||
resource = await _repository.InsertAsync(resource); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<Resource, ResourceDto>(resource); |
|||
} |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Resource.Delete)] |
|||
public async virtual Task DeleteAsync(string name) |
|||
{ |
|||
var resource = await InternalGetByNameAsync(name); |
|||
|
|||
await _repository.DeleteAsync(resource); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Resource.Update)] |
|||
public async virtual Task<ResourceDto> UpdateAsync(string name, ResourceUpdateDto input) |
|||
{ |
|||
var resource = await InternalGetByNameAsync(name); |
|||
|
|||
resource.SetDisplayName(input.DisplayName); |
|||
resource.SetDescription(input.Description); |
|||
resource.SetDefaultCultureName(input.DefaultCultureName); |
|||
|
|||
await _repository.UpdateAsync(resource); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return ObjectMapper.Map<Resource, ResourceDto>(resource); |
|||
} |
|||
|
|||
private async Task<Resource> InternalGetByNameAsync(string name) |
|||
{ |
|||
var resource = await _repository.FindByNameAsync(name); |
|||
|
|||
return resource ?? throw new BusinessException(LocalizationErrorCodes.Resource.NameNotFoundOrStaticNotAllowed) |
|||
.WithData(nameof(Resource.Name), name); |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
public static class LocalizationErrorCodes |
|||
{ |
|||
public const string Namespace = "Localization"; |
|||
|
|||
/// <summary>
|
|||
/// 语言代码002
|
|||
/// </summary>
|
|||
public static class Language |
|||
{ |
|||
public const string Prefix = Namespace + ":001"; |
|||
/// <summary>
|
|||
/// 语言 {CultureName} 已经存在
|
|||
/// </summary>
|
|||
public const string NameAlreadyExists = Prefix + "100"; |
|||
/// <summary>
|
|||
/// 没有找到名为 {CultureName} 的语言名称或内置语言不允许操作!
|
|||
/// </summary>
|
|||
public const string NameNotFoundOrStaticNotAllowed = Prefix + "400"; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 资源代码002
|
|||
/// </summary>
|
|||
public static class Resource |
|||
{ |
|||
public const string Prefix = Namespace + ":002"; |
|||
/// <summary>
|
|||
/// 资源 {Name} 已经存在
|
|||
/// </summary>
|
|||
public const string NameAlreadyExists = Prefix + "100"; |
|||
/// <summary>
|
|||
/// 没有找到名为 {Name} 的资源名称或内置资源不允许操作!
|
|||
/// </summary>
|
|||
public const string NameNotFoundOrStaticNotAllowed = Prefix + "400"; |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
[ExposeServices( |
|||
typeof(ILanguageProvider), |
|||
typeof(LanguageProvider))] |
|||
public class LanguageProvider : ILanguageProvider, ITransientDependency |
|||
{ |
|||
protected ILanguageRepository Repository { get; } |
|||
|
|||
public LanguageProvider(ILanguageRepository repository) |
|||
{ |
|||
Repository = repository; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync() |
|||
{ |
|||
var languages = await Repository.GetActivedListAsync(); |
|||
|
|||
return languages.Select(MapToLanguageInfo).ToImmutableList(); |
|||
} |
|||
|
|||
protected virtual LanguageInfo MapToLanguageInfo(Language language) |
|||
{ |
|||
return new LanguageInfo( |
|||
language.CultureName, |
|||
language.UiCultureName, |
|||
language.DisplayName, |
|||
language.FlagIcon); |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using LINGYUN.Abp.LocalizationManagement.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Language.Default)] |
|||
[RemoteService(Name = LocalizationRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("localization")] |
|||
[Route("api/localization/languages")] |
|||
public class LanguageController : AbpControllerBase, ILanguageAppService |
|||
{ |
|||
private readonly ILanguageAppService _service; |
|||
|
|||
public LanguageController(ILanguageAppService service) |
|||
{ |
|||
_service = service; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{name}")] |
|||
public virtual Task<LanguageDto> GetByNameAsync(string name) |
|||
{ |
|||
return _service.GetByNameAsync(name); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize(LocalizationManagementPermissions.Language.Create)] |
|||
public virtual Task<LanguageDto> CreateAsync(LanguageCreateDto input) |
|||
{ |
|||
return _service.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{name}")] |
|||
[Authorize(LocalizationManagementPermissions.Language.Delete)] |
|||
public virtual Task DeleteAsync(string name) |
|||
{ |
|||
return _service.DeleteAsync(name); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{name}")] |
|||
[Authorize(LocalizationManagementPermissions.Language.Update)] |
|||
public virtual Task<LanguageDto> UpdateAsync(string name, LanguageUpdateDto input) |
|||
{ |
|||
return _service.UpdateAsync(name, input); |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
using LINGYUN.Abp.LocalizationManagement.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace LINGYUN.Abp.LocalizationManagement; |
|||
|
|||
[Authorize(LocalizationManagementPermissions.Resource.Default)] |
|||
[RemoteService(Name = LocalizationRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("localization")] |
|||
[Route("api/localization/resources")] |
|||
public class ResourceController : AbpControllerBase, IResourceAppService |
|||
{ |
|||
private readonly IResourceAppService _service; |
|||
|
|||
public ResourceController(IResourceAppService service) |
|||
{ |
|||
_service = service; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{name}")] |
|||
public virtual Task<ResourceDto> GetByNameAsync(string name) |
|||
{ |
|||
return _service.GetByNameAsync(name); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize(LocalizationManagementPermissions.Resource.Create)] |
|||
public virtual Task<ResourceDto> CreateAsync(ResourceCreateDto input) |
|||
{ |
|||
return _service.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{name}")] |
|||
[Authorize(LocalizationManagementPermissions.Resource.Delete)] |
|||
public virtual Task DeleteAsync(string name) |
|||
{ |
|||
return _service.DeleteAsync(name); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{name}")] |
|||
[Authorize(LocalizationManagementPermissions.Resource.Update)] |
|||
public virtual Task<ResourceDto> UpdateAsync(string name, ResourceUpdateDto input) |
|||
{ |
|||
return _service.UpdateAsync(name, input); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue