Browse Source

Merge pull request #1521 from colinin/dynamic-localization-refresh

feat: Optimize dynamic language refresh
pull/1492/merge
yx lin 2 months ago
committed by GitHub
parent
commit
7406748c59
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 8
      apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageModal.vue
  2. 8
      apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageTable.vue
  3. 8
      apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceModal.vue
  4. 2
      apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceTable.vue
  5. 10
      apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextModal.vue
  6. 25
      apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextTable.vue
  7. 7
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs
  8. 8
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LocalizationAppServiceBase.cs
  9. 7
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs
  10. 6
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/TextAppService.cs
  11. 45
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/DynamicLocalizationRefreshEto.cs
  12. 19
      aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/DynamicLocalizationInitializerEventHandler.cs

8
apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageModal.vue

@ -56,7 +56,7 @@ async function onGet(name: string) {
const dto = await getApi(name);
formModel.value = dto;
modalApi.setState({
title: `${$t('AbpLocalization.Languages')} - ${dto.cultureName}`,
title: `${$t('LocalizationManagement.Languages')} - ${dto.cultureName}`,
});
} finally {
modalApi.setState({ loading: false });
@ -89,20 +89,20 @@ async function onSubmit() {
:wrapper-col="{ span: 18 }"
>
<FormItem
:label="$t('AbpLocalization.DisplayName:CultureName')"
:label="$t('LocalizationManagement.DisplayName:CultureName')"
name="cultureName"
required
>
<Input v-model:value="formModel.cultureName" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:UiCultureName')"
:label="$t('LocalizationManagement.DisplayName:UiCultureName')"
name="uiCultureName"
>
<Input v-model:value="formModel.uiCultureName" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:DisplayName')"
:label="$t('LocalizationManagement.DisplayName:DisplayName')"
name="displayName"
required
>

8
apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageTable.vue

@ -55,21 +55,21 @@ const gridOptions: VxeGridProps<LanguageDto> = {
field: 'cultureName',
minWidth: 150,
sortable: true,
title: $t('AbpLocalization.DisplayName:CultureName'),
title: $t('LocalizationManagement.DisplayName:CultureName'),
},
{
align: 'left',
field: 'displayName',
minWidth: 150,
sortable: true,
title: $t('AbpLocalization.DisplayName:DisplayName'),
title: $t('LocalizationManagement.DisplayName:DisplayName'),
},
{
align: 'left',
field: 'uiCultureName',
minWidth: 150,
sortable: true,
title: $t('AbpLocalization.DisplayName:UiCultureName'),
title: $t('LocalizationManagement.DisplayName:UiCultureName'),
},
{
field: 'action',
@ -161,7 +161,7 @@ async function onChange(data: LanguageDto) {
</script>
<template>
<Grid :table-title="$t('AbpLocalization.Languages')">
<Grid :table-title="$t('LocalizationManagement.Languages')">
<template #toolbar-tools>
<Button
:icon="h(PlusOutlined)"

8
apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceModal.vue

@ -60,7 +60,7 @@ async function onGet(name: string) {
const dto = await getApi(name);
formModel.value = dto;
modalApi.setState({
title: `${$t('AbpLocalization.Resources')} - ${dto.name}`,
title: `${$t('LocalizationManagement.Resources')} - ${dto.name}`,
});
} finally {
modalApi.setState({ loading: false });
@ -99,21 +99,21 @@ async function onSubmit() {
</Checkbox>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:ResourceName')"
:label="$t('LocalizationManagement.DisplayName:ResourceName')"
name="name"
required
>
<Input v-model:value="formModel.name" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:DisplayName')"
:label="$t('LocalizationManagement.DisplayName:DisplayName')"
name="displayName"
required
>
<Input v-model:value="formModel.displayName" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:Description')"
:label="$t('LocalizationManagement.DisplayName:Description')"
name="description"
>
<Input v-model:value="formModel.description" autocomplete="off" />

2
apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceTable.vue

@ -151,7 +151,7 @@ async function onChange() {
</script>
<template>
<Grid :table-title="$t('AbpLocalization.Resources')">
<Grid :table-title="$t('LocalizationManagement.Resources')">
<template #toolbar-tools>
<Button
:icon="h(PlusOutlined)"

10
apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextModal.vue

@ -105,7 +105,7 @@ async function onLoad(input: GetTextByKeyInput) {
const textDto = await getApi(input);
formModel.value = textDto;
modalApi.setState({
title: `${$t('AbpLocalization.Texts')} - ${textDto.key}`,
title: `${$t('LocalizationManagement.Texts')} - ${textDto.key}`,
});
} finally {
modalApi.setState({ loading: false });
@ -136,7 +136,7 @@ async function onSubmit() {
:wrapper-col="{ span: 18 }"
>
<FormItem
:label="$t('AbpLocalization.DisplayName:CultureName')"
:label="$t('LocalizationManagement.DisplayName:CultureName')"
name="cultureName"
required
>
@ -148,7 +148,7 @@ async function onSubmit() {
/>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:ResourceName')"
:label="$t('LocalizationManagement.DisplayName:ResourceName')"
name="resourceName"
required
>
@ -160,7 +160,7 @@ async function onSubmit() {
/>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:Key')"
:label="$t('LocalizationManagement.DisplayName:Key')"
name="key"
required
>
@ -171,7 +171,7 @@ async function onSubmit() {
/>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:Value')"
:label="$t('LocalizationManagement.DisplayName:Value')"
name="value"
required
>

25
apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextTable.vue

@ -36,11 +36,11 @@ const resources = ref<ResourceDto[]>([]);
const languages = ref<LanguageDto[]>([]);
const targetValueOptions = reactive([
{
label: $t('AbpLocalization.DisplayName:Any'),
label: $t('LocalizationManagement.DisplayName:Any'),
value: 'false',
},
{
label: $t('AbpLocalization.DisplayName:OnlyNull'),
label: $t('LocalizationManagement.DisplayName:OnlyNull'),
value: 'true',
},
]);
@ -71,25 +71,25 @@ const formOptions: VbenFormProps = {
component: 'Input',
fieldName: 'cultureName',
formItemClass: 'items-baseline',
label: $t('AbpLocalization.DisplayName:CultureName'),
label: $t('LocalizationManagement.DisplayName:CultureName'),
rules: 'selectRequired',
},
{
component: 'Input',
fieldName: 'targetCultureName',
formItemClass: 'items-baseline',
label: $t('AbpLocalization.DisplayName:TargetCultureName'),
label: $t('LocalizationManagement.DisplayName:TargetCultureName'),
rules: 'selectRequired',
},
{
component: 'Input',
fieldName: 'resourceName',
label: $t('AbpLocalization.DisplayName:ResourceName'),
label: $t('LocalizationManagement.DisplayName:ResourceName'),
},
{
component: 'Input',
fieldName: 'onlyNull',
label: $t('AbpLocalization.DisplayName:TargetValue'),
label: $t('LocalizationManagement.DisplayName:TargetValue'),
},
{
component: 'Input',
@ -111,28 +111,28 @@ const gridOptions: VxeGridProps<TextDifferenceDto> = {
field: 'key',
minWidth: 150,
sortable: true,
title: $t('AbpLocalization.DisplayName:Key'),
title: $t('LocalizationManagement.DisplayName:Key'),
},
{
align: 'left',
field: 'value',
minWidth: 150,
sortable: true,
title: $t('AbpLocalization.DisplayName:Value'),
title: $t('LocalizationManagement.DisplayName:Value'),
},
{
align: 'left',
field: 'targetValue',
minWidth: 150,
sortable: true,
title: $t('AbpLocalization.DisplayName:TargetValue'),
title: $t('LocalizationManagement.DisplayName:TargetValue'),
},
{
align: 'left',
field: 'resourceName',
minWidth: 150,
sortable: true,
title: $t('AbpLocalization.DisplayName:ResourceName'),
title: $t('LocalizationManagement.DisplayName:ResourceName'),
},
{
field: 'action',
@ -280,12 +280,13 @@ onMounted(onInit);
</script>
<template>
<Grid :table-title="$t('AbpLocalization.Texts')">
<Grid :table-title="$t('LocalizationManagement.Texts')">
<template #form-cultureName="{ modelValue }">
<Select
class="w-full"
allow-clear
show-search
:filter-option="undefined"
:options="languages"
:value="modelValue"
:field-names="{ label: 'displayName', value: 'cultureName' }"
@ -298,6 +299,7 @@ onMounted(onInit);
class="w-full"
allow-clear
show-search
:filter-option="undefined"
:options="languages"
:value="modelValue"
:field-names="{ label: 'displayName', value: 'cultureName' }"
@ -312,6 +314,7 @@ onMounted(onInit);
class="w-full"
allow-clear
show-search
:filter-option="undefined"
:options="resources"
:value="modelValue"
:field-names="{ label: 'displayName', value: 'name' }"

7
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LanguageAppService.cs

@ -18,6 +18,7 @@ namespace LINGYUN.Abp.LocalizationManagement;
[Authorize(LocalizationManagementPermissions.Language.Default)]
public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppService
{
private readonly ILanguageRepository _repository;
public LanguageAppService(ILanguageRepository repository)
@ -53,6 +54,8 @@ public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppServic
language = await _repository.InsertAsync(language);
await PublishDynamicLocalizationRefreshEvent(new DynamicLanguageRefreshEventData(language.CultureName));
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Language, LanguageDto>(language);
@ -66,6 +69,8 @@ public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppServic
await _repository.DeleteAsync(language);
await PublishDynamicLocalizationRefreshEvent(new DynamicLanguageRefreshEventData(language.CultureName));
await CurrentUnitOfWork.SaveChangesAsync();
}
@ -78,6 +83,8 @@ public class LanguageAppService : LocalizationAppServiceBase, ILanguageAppServic
await _repository.UpdateAsync(language);
await PublishDynamicLocalizationRefreshEvent(new DynamicLanguageRefreshEventData(language.CultureName));
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Language, LanguageDto>(language);

8
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/LocalizationAppServiceBase.cs

@ -1,13 +1,21 @@
using LINGYUN.Abp.LocalizationManagement.Localization;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.EventBus.Local;
namespace LINGYUN.Abp.LocalizationManagement;
public abstract class LocalizationAppServiceBase : ApplicationService
{
protected ILocalEventBus LocalEventBus => LazyServiceProvider.LazyGetService<ILocalEventBus>();
protected LocalizationAppServiceBase()
{
LocalizationResource = typeof(LocalizationManagementResource);
ObjectMapperContext = typeof(AbpLocalizationManagementApplicationModule);
}
protected async virtual Task PublishDynamicLocalizationRefreshEvent<TEvent>(TEvent @event)
{
await LocalEventBus?.PublishAsync(@event.GetType(), @event);
}
}

7
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/ResourceAppService.cs

@ -16,6 +16,7 @@ namespace LINGYUN.Abp.LocalizationManagement;
[Authorize(LocalizationManagementPermissions.Resource.Default)]
public class ResourceAppService : LocalizationAppServiceBase, IResourceAppService
{
private readonly IResourceRepository _repository;
public ResourceAppService(IResourceRepository repository)
@ -48,6 +49,8 @@ public class ResourceAppService : LocalizationAppServiceBase, IResourceAppServic
resource = await _repository.InsertAsync(resource);
await PublishDynamicLocalizationRefreshEvent(new DynamicResourceRefreshEventData(resource.Name));
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Resource, ResourceDto>(resource);
@ -60,6 +63,8 @@ public class ResourceAppService : LocalizationAppServiceBase, IResourceAppServic
await _repository.DeleteAsync(resource);
await PublishDynamicLocalizationRefreshEvent(new DynamicResourceRefreshEventData(resource.Name));
await CurrentUnitOfWork.SaveChangesAsync();
}
@ -74,6 +79,8 @@ public class ResourceAppService : LocalizationAppServiceBase, IResourceAppServic
await _repository.UpdateAsync(resource);
await PublishDynamicLocalizationRefreshEvent(new DynamicResourceRefreshEventData(resource.Name));
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<Resource, ResourceDto>(resource);

6
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Application/LINGYUN/Abp/LocalizationManagement/TextAppService.cs

@ -105,6 +105,8 @@ public class TextAppService : LocalizationAppServiceBase, ITextAppService
await _textRepository.UpdateAsync(text);
}
await PublishDynamicLocalizationRefreshEvent(new DynamicTextRefreshEventData(text.ResourceName, text.CultureName));
await CurrentUnitOfWork.SaveChangesAsync();
}
@ -116,6 +118,8 @@ public class TextAppService : LocalizationAppServiceBase, ITextAppService
{
await _textRepository.DeleteAsync(text);
await PublishDynamicLocalizationRefreshEvent(new DynamicTextRefreshEventData(text.ResourceName, text.CultureName));
await CurrentUnitOfWork.SaveChangesAsync();
}
}
@ -129,6 +133,8 @@ public class TextAppService : LocalizationAppServiceBase, ITextAppService
{
await _textRepository.DeleteAsync(text);
await PublishDynamicLocalizationRefreshEvent(new DynamicTextRefreshEventData(text.ResourceName, text.CultureName));
await CurrentUnitOfWork.SaveChangesAsync();
}
}

45
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain.Shared/LINGYUN/Abp/LocalizationManagement/DynamicLocalizationRefreshEto.cs

@ -0,0 +1,45 @@
namespace LINGYUN.Abp.LocalizationManagement;
public class DynamicLanguageRefreshEventData
{
public string CultureName { get; set; }
public DynamicLanguageRefreshEventData()
{
}
public DynamicLanguageRefreshEventData(string cultureName)
{
CultureName = cultureName;
}
}
public class DynamicResourceRefreshEventData
{
public string ResourceName { get; set; }
public DynamicResourceRefreshEventData()
{
}
public DynamicResourceRefreshEventData(string resourceName)
{
ResourceName = resourceName;
}
}
public class DynamicTextRefreshEventData
{
public string ResourceName { get; set; }
public string CultureName { get; set; }
public DynamicTextRefreshEventData()
{
}
public DynamicTextRefreshEventData(string resourceName, string cultureName)
{
ResourceName = resourceName;
CultureName = cultureName;
}
}

19
aspnet-core/modules/localization-management/LINGYUN.Abp.LocalizationManagement.Domain/LINGYUN/Abp/LocalizationManagement/DynamicLocalizationInitializerEventHandler.cs

@ -11,7 +11,6 @@ using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Domain.ChangeTracking;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Guids;
@ -24,9 +23,9 @@ public class DynamicLocalizationInitializerEventHandler :
IDistributedEventHandler<DynamicLanguageInitializerEto>,
IDistributedEventHandler<DynamicResourceInitializerEto>,
IDistributedEventHandler<DynamicTextInitializerEto>,
ILocalEventHandler<EntityChangedEventData<Resource>>,
ILocalEventHandler<EntityChangedEventData<Language>>,
ILocalEventHandler<EntityChangedEventData<Text>>,
ILocalEventHandler<DynamicLanguageRefreshEventData>,
ILocalEventHandler<DynamicResourceRefreshEventData>,
ILocalEventHandler<DynamicTextRefreshEventData>,
ITransientDependency
{
public ILogger<StaticLocalizationSaver> Logger { protected get; set; }
@ -88,7 +87,7 @@ public class DynamicLocalizationInitializerEventHandler :
}
[DisableEntityChangeTracking]
public async virtual Task HandleEventAsync(EntityChangedEventData<Language> eventData)
public async virtual Task HandleEventAsync(DynamicLanguageRefreshEventData eventData)
{
Logger.LogInformation("Languages have changed. Refresh the language cache.");
@ -137,7 +136,7 @@ public class DynamicLocalizationInitializerEventHandler :
}
[DisableEntityChangeTracking]
public async virtual Task HandleEventAsync(EntityChangedEventData<Resource> eventData)
public async virtual Task HandleEventAsync(DynamicResourceRefreshEventData eventData)
{
Logger.LogInformation("Resources have changed. Refresh the resource cache.");
@ -186,19 +185,19 @@ public class DynamicLocalizationInitializerEventHandler :
}
[DisableEntityChangeTracking]
public async virtual Task HandleEventAsync(EntityChangedEventData<Text> eventData)
public async virtual Task HandleEventAsync(DynamicTextRefreshEventData eventData)
{
Logger.LogInformation("Texts have changed. Refresh the text cache.");
var setTexts = new Dictionary<string, string>();
var allTexts = await TextRepository.GetListAsync(eventData.Entity.ResourceName, eventData.Entity.CultureName);
var allTexts = await TextRepository.GetListAsync(eventData.ResourceName, eventData.CultureName);
foreach (var text in allTexts)
{
setTexts[text.Key] = text.Value;
}
var textCacheKey = LocalizationTextCacheItem.CalculateCacheKey(eventData.Entity.ResourceName, eventData.Entity.CultureName);
var textCacheItem = new LocalizationTextCacheItem(eventData.Entity.ResourceName, eventData.Entity.CultureName, setTexts);
var textCacheKey = LocalizationTextCacheItem.CalculateCacheKey(eventData.ResourceName, eventData.CultureName);
var textCacheItem = new LocalizationTextCacheItem(eventData.ResourceName, eventData.CultureName, setTexts);
await LocalizationTextCache.SetAsync(textCacheKey, textCacheItem);

Loading…
Cancel
Save