committed by
GitHub
508 changed files with 32119 additions and 3465 deletions
@ -0,0 +1,76 @@ |
|||||
|
# 10.2.0 - 10.4.0 |
||||
|
|
||||
|
## 模块变更 |
||||
|
|
||||
|
1. [身份标识模块] 增加不活跃用户通知/清理作业,实现了三个通知模板(账户保持活跃通知、账户停用通知、账户删除通知) |
||||
|
2. [身份标识模块] 增加不活跃用户实体 `IdentityUserInactive` 需要执行数据库迁移 |
||||
|
3. [身份标识模块] 增加用户登录Url设置定义: `Abp.Identity.Link.UserLoginUri`, 用于在外部系统中关联用户登录页 |
||||
|
4. [身份认证模块] 增加用户登录Url定义: `Abp.Account.UserLogin` |
||||
|
5. [身份认证模块] 增加关联用户登录功能, 可以实现跨租户用户关联, 切换关联用户登录 |
||||
|
6. [设置管理模块] 增加身份标识模块缺少的设置项: 启用防止密码重用、防止密码重用数量 |
||||
|
7. [设置基础模块] 增加设置定义分组、所属设置、优先级、依赖权限、依赖功能、选择项等常用结构扩展 |
||||
|
8. [设置管理模块] 重构设置管理应用服务接口, 通过预设定的设置定义分组、上下级关系等自动构成Dto结构 |
||||
|
|
||||
|
## 依赖项变更 |
||||
|
|
||||
|
| 库名称 | 原版本 | 现版本 | |
||||
|
| -------------------------------------------- | --------- | ------ | |
||||
|
| Microsoft.AspNetCore.* | 10.0.2 | 10.0.7 | |
||||
|
| Microsoft.Bcl.AsyncInterfaces | 10.0.2 | 10.0.7 | |
||||
|
| Microsoft.Data.Sqlite.Core | 10.0.0 | 10.0.7 | |
||||
|
| Microsoft.EntityFrameworkCore.* | 10.0.2 | 10.0.7 | |
||||
|
| Microting.EntityFrameworkCore.MySql | 10.0.3 | 10.0.7 | |
||||
|
| Microsoft.Extensions.* | 10.0.2 | 10.0.7 | |
||||
|
| OpenTelemetry.Extensions.Hosting | 1.14.0 | 1.15.3 | |
||||
|
| OpenTelemetry.Exporter.Console | 1.14.0 | 1.15.3 | |
||||
|
| OpenTelemetry.Exporter.OpenTelemetryProtocol | 1.14.0 | 1.15.3 | |
||||
|
| OpenTelemetry.Exporter.Zipkin | 1.14.0 | 1.15.3 | |
||||
|
| OpenTelemetry.Instrumentation.AspNetCore | 1.14.0 | 1.15.2 | |
||||
|
| OpenTelemetry.Instrumentation.Http | 1.14.0 | 1.15.1 | |
||||
|
| OpenTelemetry.Instrumentation.Quartz | 1.14.0-beta.2 | 1.15.1-beta.1 | |
||||
|
| OpenTelemetry.Instrumentation.Runtime | 1.14.0 | 1.15.1 | |
||||
|
| OpenTelemetry.Instrumentation.SqlClient | 1.14.0-beta.1 | 1.15.2 | |
||||
|
| OpenIddict.Server.DataProtection | 7.2.0 | 7.5.0 | |
||||
|
| OpenIddict.Validation.DataProtection | 7.2.0 | 7.5.0 | |
||||
|
| System.Threading.Channels | 10.0.0 | 10.0.7 | |
||||
|
| Volo.Abp.* | 10.2.0 | 10.4.0 | |
||||
|
| Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite | 5.2.0 | 5.4.0 | |
||||
|
|
||||
|
|
||||
|
|
||||
|
## 数据库迁移 |
||||
|
|
||||
|
| Project Name | Database Provider | Scripts | EF Core Version | |
||||
|
| ------------------------ | ----------------- | ---------------------------------------------- | --------------- | |
||||
|
| aspire/AuthServer | PostgreSQL | 20260530060327_Add-Identity-User-Inactive | 10.0.2 | |
||||
|
| services/Single | MySQL | 20260529063257_Add-Identity-User-Inactive | 10.0.3 | |
||||
|
| services/Single | PostgreSQL | 20260530055941_Add-Identity-User-Inactive | 10.0.2 | |
||||
|
| services/Single | SqlServer | 20260530060009_Add-Identity-User-Inactive | 10.0.2 | |
||||
|
| services/AuthServer | MySQL | 20260530061141_Add-Identity-User-Inactive | 10.0.3 | |
||||
|
|
||||
|
|
||||
|
## 数据库连接字符串 |
||||
|
|
||||
|
| Module Name | ConnectionString Name | Example(MySQL) | |
||||
|
| ----------------------------- | ---------------------------- | ------------------------------------------------------------ | |
||||
|
| Default | Default | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| abp/Identity | AbpIdentity | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| abp/IdentityServer | AbpIdentityServer | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| abp/OpenIddict | AbpOpenIddict | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| abp/TenantManagement | AbpTenantManagement(AbpSaas) | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| abp/FeatureManagement | AbpFeatureManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| abp/SettingManagement | AbpSettingManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| abp/PermissionManagement | AbpPermissionManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/AIManagement | AbpAIManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/BlobManagement | AbpBlobManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/DataProtectionManagement | AbpDataProtectionManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/Gdpr | AbpGdpr | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/Saas | AbpSaas | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/LocalizationManagement | AbpLocalizationManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/TextTemplating | AbpTextTemplating | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/Platform | AppPlatform | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/MessageService | MessageService | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/NotificationService | Notifications | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/TaskManagement | TaskManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/WebhooksManagement | WebhooksManagement | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
|
| labp/Elsa | Workflow | Server=127.0.0.1;Database=abp;User Id=root;Password=123456;SslMode=None | |
||||
@ -1,5 +1,6 @@ |
|||||
export { useAccountApi } from './useAccountApi'; |
export { useAccountApi } from './useAccountApi'; |
||||
export { useExternalLoginsApi } from './useExternalLoginsApi'; |
export { useExternalLoginsApi } from './useExternalLoginsApi'; |
||||
|
export { useLinkUsersApi } from './useLinkUsersApi'; |
||||
export { useMySessionApi } from './useMySessionApi'; |
export { useMySessionApi } from './useMySessionApi'; |
||||
export { useProfileApi } from './useProfileApi'; |
export { useProfileApi } from './useProfileApi'; |
||||
export { useScanQrCodeApi } from './useScanQrCodeApi'; |
export { useScanQrCodeApi } from './useScanQrCodeApi'; |
||||
|
|||||
@ -0,0 +1,54 @@ |
|||||
|
import type { ListResultDto } from '@abp/core'; |
||||
|
|
||||
|
import type { LinkUserDto, UnLinkUserInput } from '../types/link-user'; |
||||
|
|
||||
|
import { useRequest } from '@abp/request'; |
||||
|
|
||||
|
export function useLinkUsersApi() { |
||||
|
const { cancel, request } = useRequest(); |
||||
|
|
||||
|
/** |
||||
|
* 查询关联用户列表 |
||||
|
* @returns { Promise<ListResultDto<LinkUserDto>> } 关联用户列表 |
||||
|
*/ |
||||
|
function getListApi(): Promise<ListResultDto<LinkUserDto>> { |
||||
|
return request<ListResultDto<LinkUserDto>>('api/account/link-users', { |
||||
|
method: 'GET', |
||||
|
}); |
||||
|
} |
||||
|
/** |
||||
|
* 生成关联用户Token |
||||
|
*/ |
||||
|
function generateLinkTokenApi(): Promise<string> { |
||||
|
return request(`api/account/link-users/generate-link-token`, { |
||||
|
method: 'POST', |
||||
|
}); |
||||
|
} |
||||
|
/** |
||||
|
* 生成关联用户登录Token |
||||
|
*/ |
||||
|
function generateLinkLoginTokenApi(): Promise<string> { |
||||
|
return request(`api/account/link-users/generate-link-login-token`, { |
||||
|
method: 'POST', |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 取消用户关联 |
||||
|
* @param input 参数 |
||||
|
*/ |
||||
|
function unLinkApi(input: UnLinkUserInput): Promise<void> { |
||||
|
return request(`api/account/link-users/unlink`, { |
||||
|
method: 'POST', |
||||
|
data: input, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
cancel, |
||||
|
getListApi, |
||||
|
generateLinkTokenApi, |
||||
|
generateLinkLoginTokenApi, |
||||
|
unLinkApi, |
||||
|
}; |
||||
|
} |
||||
@ -0,0 +1,198 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import type { VxeGridProps } from '@abp/ui'; |
||||
|
|
||||
|
import type { LinkUserDto } from '../types'; |
||||
|
|
||||
|
import { h, ref } from 'vue'; |
||||
|
|
||||
|
import { confirm, useVbenModal } from '@vben/common-ui'; |
||||
|
import { $t } from '@vben/locales'; |
||||
|
|
||||
|
import { sortby } from '@abp/core'; |
||||
|
import { useMessage, useVbenVxeGrid } from '@abp/ui'; |
||||
|
import { |
||||
|
CheckOutlined, |
||||
|
CloseOutlined, |
||||
|
DeleteOutlined, |
||||
|
LoginOutlined, |
||||
|
PlusOutlined, |
||||
|
} from '@ant-design/icons-vue'; |
||||
|
import { Button } from 'ant-design-vue'; |
||||
|
|
||||
|
import { useLinkUsersApi } from '../api/useLinkUsersApi'; |
||||
|
|
||||
|
const emit = defineEmits<{ |
||||
|
(event: 'link', token: string): void; |
||||
|
(event: 'login', userId: string, tenantId?: string): void; |
||||
|
}>(); |
||||
|
|
||||
|
const message = useMessage(); |
||||
|
const { getListApi, generateLinkTokenApi, unLinkApi } = useLinkUsersApi(); |
||||
|
|
||||
|
const linkUsers = ref<LinkUserDto[]>([]); |
||||
|
|
||||
|
const [Modal, modalApi] = useVbenModal({ |
||||
|
async onOpenChange(isOpen) { |
||||
|
if (isOpen) { |
||||
|
await onInit(); |
||||
|
} |
||||
|
}, |
||||
|
title: $t('AbpAccount.LinkUser'), |
||||
|
}); |
||||
|
const gridOptions: VxeGridProps<LinkUserDto> = { |
||||
|
columns: [ |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'linkUserName', |
||||
|
formatter: ({ row }) => { |
||||
|
if (row.linkTenantName) { |
||||
|
return `${row.linkTenantName}/${row.linkUserName}`; |
||||
|
} |
||||
|
return row.linkUserName; |
||||
|
}, |
||||
|
sortable: true, |
||||
|
title: $t('AbpAccount.DisplayName:LinkUserName'), |
||||
|
}, |
||||
|
{ |
||||
|
align: 'left', |
||||
|
field: 'directlyLinked', |
||||
|
slots: { default: 'directlyLinked' }, |
||||
|
sortable: true, |
||||
|
title: $t('AbpAccount.DisplayName:DirectlyLinked'), |
||||
|
width: 150, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'actions', |
||||
|
fixed: 'right', |
||||
|
slots: { default: 'actions' }, |
||||
|
title: $t('AbpUi.Actions'), |
||||
|
width: 220, |
||||
|
}, |
||||
|
], |
||||
|
exportConfig: {}, |
||||
|
keepSource: true, |
||||
|
proxyConfig: { |
||||
|
ajax: { |
||||
|
query: async ({ page, sort }) => { |
||||
|
let items = sortby(linkUsers.value, sort.field); |
||||
|
if (sort.order === 'desc') { |
||||
|
items = items.toReversed(); |
||||
|
} |
||||
|
const result = { |
||||
|
totalCount: linkUsers.value.length, |
||||
|
items: items.slice( |
||||
|
(page.currentPage - 1) * page.pageSize, |
||||
|
page.currentPage * page.pageSize, |
||||
|
), |
||||
|
}; |
||||
|
return new Promise((resolve) => { |
||||
|
resolve(result); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
response: { |
||||
|
total: 'totalCount', |
||||
|
list: 'items', |
||||
|
}, |
||||
|
}, |
||||
|
sortConfig: { |
||||
|
remote: true, |
||||
|
allowBtn: true, |
||||
|
}, |
||||
|
toolbarConfig: { |
||||
|
custom: true, |
||||
|
export: true, |
||||
|
zoom: true, |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
const [Grid, gridApi] = useVbenVxeGrid({ |
||||
|
gridOptions, |
||||
|
}); |
||||
|
|
||||
|
async function onInit() { |
||||
|
const { items } = await getListApi(); |
||||
|
linkUsers.value = items; |
||||
|
gridApi.query(); |
||||
|
} |
||||
|
|
||||
|
async function onCreatLink() { |
||||
|
confirm({ |
||||
|
async beforeClose(scope) { |
||||
|
if (scope.isConfirm) { |
||||
|
const token = await generateLinkTokenApi(); |
||||
|
emit('link', token); |
||||
|
} |
||||
|
}, |
||||
|
centered: true, |
||||
|
content: $t('AbpAccount.LinkAccountWillBeCreateWarning'), |
||||
|
title: $t('AbpUi.AreYouSure'), |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function onLoginByLink(record: LinkUserDto) { |
||||
|
emit('login', record.linkUserId, record.linkTenantId); |
||||
|
modalApi.close(); |
||||
|
} |
||||
|
|
||||
|
async function onDeleteLink(record: LinkUserDto) { |
||||
|
confirm({ |
||||
|
async beforeClose(scope) { |
||||
|
if (scope.isConfirm) { |
||||
|
await unLinkApi({ |
||||
|
userId: record.linkUserId, |
||||
|
tenantId: record.linkTenantId, |
||||
|
}); |
||||
|
message.success($t('AbpUi.DeletedSuccessfully')); |
||||
|
await onInit(); |
||||
|
} |
||||
|
}, |
||||
|
centered: true, |
||||
|
content: $t('AbpAccount.LinkAccountWillBeDeleteWarning', [ |
||||
|
record.linkUserName, |
||||
|
]), |
||||
|
title: $t('AbpUi.AreYouSure'), |
||||
|
}); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Modal> |
||||
|
<Grid> |
||||
|
<template #toolbar-tools> |
||||
|
<Button :icon="h(PlusOutlined)" type="primary" @click="onCreatLink"> |
||||
|
{{ $t('AbpAccount.LinkUser:New') }} |
||||
|
</Button> |
||||
|
</template> |
||||
|
<template #directlyLinked="{ row }"> |
||||
|
<div class="flex flex-row justify-center"> |
||||
|
<CheckOutlined v-if="row.directlyLinked" class="text-green-500" /> |
||||
|
<CloseOutlined v-else class="text-red-500" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template #actions="{ row }"> |
||||
|
<div class="flex flex-row"> |
||||
|
<Button |
||||
|
:icon="h(LoginOutlined)" |
||||
|
block |
||||
|
type="link" |
||||
|
@click="onLoginByLink(row)" |
||||
|
> |
||||
|
{{ $t('AbpAccount.LinkUser:Login') }} |
||||
|
</Button> |
||||
|
<Button |
||||
|
:icon="h(DeleteOutlined)" |
||||
|
block |
||||
|
danger |
||||
|
type="link" |
||||
|
@click="onDeleteLink(row)" |
||||
|
> |
||||
|
{{ $t('AbpUi.Delete') }} |
||||
|
</Button> |
||||
|
</div> |
||||
|
</template> |
||||
|
</Grid> |
||||
|
</Modal> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped></style> |
||||
@ -1,3 +1,4 @@ |
|||||
export { default as MyProfile } from './MyProfile.vue'; |
export { default as MyProfile } from './MyProfile.vue'; |
||||
export { default as MySetting } from './MySetting.vue'; |
export { default as MySetting } from './MySetting.vue'; |
||||
export { default as QrCodeLogin } from './QrCodeLogin.vue'; |
export { default as QrCodeLogin } from './QrCodeLogin.vue'; |
||||
|
export { default as UserLinkModal } from './UserLinkModal.vue'; |
||||
|
|||||
@ -1,6 +1,8 @@ |
|||||
export * from './account'; |
export * from './account'; |
||||
export * from './bind'; |
export * from './bind'; |
||||
export * from './external-logins'; |
export * from './external-logins'; |
||||
|
export * from './link-user'; |
||||
export * from './profile'; |
export * from './profile'; |
||||
export * from './token'; |
export * from './token'; |
||||
export * from './user'; |
export * from './user'; |
||||
|
export type { SigninRedirectArgs } from 'oidc-client-ts'; |
||||
|
|||||
@ -0,0 +1,14 @@ |
|||||
|
interface LinkUserDto { |
||||
|
directlyLinked: boolean; |
||||
|
linkTenantId?: string; |
||||
|
linkTenantName?: string; |
||||
|
linkUserId: string; |
||||
|
linkUserName: string; |
||||
|
} |
||||
|
|
||||
|
interface UnLinkUserInput { |
||||
|
tenantId?: string; |
||||
|
userId: string; |
||||
|
} |
||||
|
|
||||
|
export type { LinkUserDto, UnLinkUserInput }; |
||||
@ -0,0 +1,106 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
import type { BlobDto } from '../../types/blobs'; |
||||
|
|
||||
|
import { defineAsyncComponent, ref } from 'vue'; |
||||
|
|
||||
|
import { useVbenModal } from '@vben/common-ui'; |
||||
|
import { downloadFileFromUrl } from '@vben/utils'; |
||||
|
|
||||
|
import { Button, Spin } from 'ant-design-vue'; |
||||
|
|
||||
|
import { useBlobsApi } from '../../api/useBlobsApi'; |
||||
|
|
||||
|
const VueFilesPreview = defineAsyncComponent({ |
||||
|
loader: async () => { |
||||
|
const res = await import('vue-files-preview'); |
||||
|
import('vue-files-preview/lib/style.css'); |
||||
|
return res.VueFilesPreview; |
||||
|
}, |
||||
|
loadingComponent: Spin, |
||||
|
delay: 200, |
||||
|
}); |
||||
|
|
||||
|
const fileName = ref<string>(); |
||||
|
const previewUrl = ref<string>(); |
||||
|
const errorMsg = ref<string>(); |
||||
|
|
||||
|
const { generatePreviewUrlApi } = useBlobsApi(); |
||||
|
|
||||
|
const [Modal, modalApi] = useVbenModal({ |
||||
|
showCancelButton: false, |
||||
|
showConfirmButton: false, |
||||
|
fullscreen: true, |
||||
|
fullscreenButton: false, |
||||
|
onOpenChange: async (isOpen) => { |
||||
|
isOpen && onInit(); |
||||
|
}, |
||||
|
onClosed() { |
||||
|
previewUrl.value = undefined; |
||||
|
fileName.value = undefined; |
||||
|
errorMsg.value = undefined; |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
async function onInit() { |
||||
|
try { |
||||
|
modalApi.lock(); |
||||
|
const blob = modalApi.getData<BlobDto>(); |
||||
|
fileName.value = blob.name; |
||||
|
previewUrl.value = await generatePreviewUrlApi(blob.id); |
||||
|
} finally { |
||||
|
modalApi.unlock(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async function handleDownload() { |
||||
|
downloadFileFromUrl({ |
||||
|
fileName: fileName.value!, |
||||
|
source: previewUrl.value!, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
function onError(error: Error) { |
||||
|
errorMsg.value = error.message; |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<Modal :title="fileName"> |
||||
|
<div class="preview-container"> |
||||
|
<VueFilesPreview |
||||
|
v-if="previewUrl" |
||||
|
:url="previewUrl" |
||||
|
:name="fileName" |
||||
|
@error="onError" |
||||
|
/> |
||||
|
|
||||
|
<!-- 下载按钮 --> |
||||
|
<div v-if="errorMsg && previewUrl" class="download-button"> |
||||
|
<Button type="primary" @click="handleDownload"> |
||||
|
{{ $t('BlobManagement.Blobs:Download') }} |
||||
|
</Button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</Modal> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.preview-container { |
||||
|
position: relative; |
||||
|
height: 100%; |
||||
|
|
||||
|
.error-message { |
||||
|
padding: 40px 20px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.download-button { |
||||
|
position: sticky; |
||||
|
right: 20px; |
||||
|
bottom: 20px; |
||||
|
z-index: 10; |
||||
|
float: right; |
||||
|
margin-top: 20px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,2 @@ |
|||||
|
/** 启用企业微信认证 */ |
||||
|
export const WeixinWorkAuthEnable = 'Abp.Account.OAuth.WeCom.Enable'; |
||||
@ -0,0 +1,258 @@ |
|||||
|
using LINGYUN.Abp.SettingManagement; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Emailing; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.SettingManagement; |
||||
|
using Volo.Abp.SettingManagement.Localization; |
||||
|
using Volo.Abp.Settings; |
||||
|
using Volo.Abp.Timing; |
||||
|
using ValueType = Volo.Abp.Settings.ValueType; |
||||
|
|
||||
|
namespace LINGYUN.Abp.MicroService.AdminService; |
||||
|
|
||||
|
public class SystemGroupSettingDefinitionProvider : SettingDefinitionProvider |
||||
|
{ |
||||
|
private const string GroupName = "System"; |
||||
|
|
||||
|
protected ITimezoneProvider TimezoneProvider { get; } |
||||
|
protected AbpLocalizationOptions LocalizationOptions { get; } |
||||
|
protected IStringLocalizerFactory StringLocalizerFactory { get; } |
||||
|
|
||||
|
public SystemGroupSettingDefinitionProvider( |
||||
|
ITimezoneProvider timezoneProvider, |
||||
|
IStringLocalizerFactory stringLocalizerFactory, |
||||
|
IOptions<AbpLocalizationOptions> localizationOptions) |
||||
|
{ |
||||
|
TimezoneProvider = timezoneProvider; |
||||
|
StringLocalizerFactory = stringLocalizerFactory; |
||||
|
LocalizationOptions = localizationOptions.Value; |
||||
|
} |
||||
|
|
||||
|
public override void Define(ISettingDefinitionContext context) |
||||
|
{ |
||||
|
SetSystemSettingGroup(context); |
||||
|
SetEmailSettingGroup(context); |
||||
|
} |
||||
|
|
||||
|
private void SetSystemSettingGroup(ISettingDefinitionContext context) |
||||
|
{ |
||||
|
context.GetOrNull(LocalizationSettingNames.DefaultLanguage) |
||||
|
?.WithGroup(GroupName, L("Settings:System"), order: 0) |
||||
|
?.WithParent("Language", L("Settings:System.Language"), order: 0) |
||||
|
?.WithOrder(0) |
||||
|
?.WithOptions(LocalizationOptions.Languages.Select(l => new NameValue<string>(l.DisplayName, l.CultureName))) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
|
||||
|
var timezoneSetting = context.GetOrNull(TimingSettingNames.TimeZone); |
||||
|
if (timezoneSetting != null) |
||||
|
{ |
||||
|
var stringLocalizer = StringLocalizerFactory.Create<AbpSettingManagementResource>(); |
||||
|
var timezones = TimeZoneHelper.GetTimezones(TimezoneProvider.GetIanaTimezones()); |
||||
|
timezones.Insert(0, new NameValue |
||||
|
{ |
||||
|
Name = stringLocalizer["DefaultTimeZone"], |
||||
|
Value = "Unspecified" |
||||
|
}); |
||||
|
|
||||
|
timezoneSetting |
||||
|
.WithGroup( |
||||
|
GroupName, |
||||
|
L("Settings:System"), |
||||
|
order: 0, |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.TimeZone]) |
||||
|
.WithParent("Timing", L("Settings:System.Timing"), order: 0) |
||||
|
.WithOrder(1) |
||||
|
.WithOptions(timezones) |
||||
|
.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static void SetEmailSettingGroup(ISettingDefinitionContext context) |
||||
|
{ |
||||
|
context.GetOrNull(EmailSettingNames.DefaultFromAddress) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Default", |
||||
|
L("Settings:Emailing.Default"), |
||||
|
order: 0) |
||||
|
?.WithOrder(0) |
||||
|
?.WithValueType(ValueType.String) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
context.GetOrNull(EmailSettingNames.DefaultFromDisplayName) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Default", |
||||
|
L("Settings:Emailing.Default"), |
||||
|
order: 0) |
||||
|
?.WithOrder(1) |
||||
|
?.WithValueType(ValueType.String) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
|
||||
|
context.GetOrNull(EmailSettingNames.Smtp.Domain) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Smtp", |
||||
|
L("Settings:Emailing.Smtp"), |
||||
|
order: 1, |
||||
|
requiredPermissions: [AbpSettingManagementPermissions.Settings.Manager]) |
||||
|
?.WithOrder(0) |
||||
|
?.WithValueType(ValueType.String) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
context.GetOrNull(EmailSettingNames.Smtp.Host) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Smtp", |
||||
|
L("Settings:Emailing.Smtp"), |
||||
|
order: 1, |
||||
|
requiredPermissions: [AbpSettingManagementPermissions.Settings.Manager]) |
||||
|
?.WithOrder(1) |
||||
|
?.WithValueType(ValueType.String) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
context.GetOrNull(EmailSettingNames.Smtp.Port) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Smtp", |
||||
|
L("Settings:Emailing.Smtp"), |
||||
|
order: 1, |
||||
|
requiredPermissions: [AbpSettingManagementPermissions.Settings.Manager]) |
||||
|
?.WithOrder(2) |
||||
|
?.WithValueType(ValueType.Number) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
context.GetOrNull(EmailSettingNames.Smtp.UserName) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Smtp", |
||||
|
L("Settings:Emailing.Smtp"), |
||||
|
order: 1, |
||||
|
requiredPermissions: [AbpSettingManagementPermissions.Settings.Manager]) |
||||
|
?.WithOrder(3) |
||||
|
?.WithValueType(ValueType.String) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
context.GetOrNull(EmailSettingNames.Smtp.Password) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Smtp", |
||||
|
L("Settings:Emailing.Smtp"), |
||||
|
order: 1, |
||||
|
requiredPermissions: [AbpSettingManagementPermissions.Settings.Manager]) |
||||
|
?.WithOrder(4) |
||||
|
?.WithValueType(ValueType.String) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
context.GetOrNull(EmailSettingNames.Smtp.EnableSsl) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Smtp", |
||||
|
L("Settings:Emailing.Smtp"), |
||||
|
order: 1, |
||||
|
requiredPermissions: [AbpSettingManagementPermissions.Settings.Manager]) |
||||
|
?.WithOrder(5) |
||||
|
?.WithValueType(ValueType.Boolean) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
context.GetOrNull(EmailSettingNames.Smtp.UseDefaultCredentials) |
||||
|
?.WithGroup( |
||||
|
"Emailing", |
||||
|
L("Settings:Emailing"), |
||||
|
order: 1, |
||||
|
requiredFeatures: [SettingManagementFeatures.Enable, SettingManagementFeatures.AllowChangingEmailSettings], |
||||
|
requiredPermissions: [Volo.Abp.SettingManagement.SettingManagementPermissions.Emailing]) |
||||
|
?.WithParent( |
||||
|
"Smtp", |
||||
|
L("Settings:Emailing.Smtp"), |
||||
|
order: 1, |
||||
|
requiredPermissions: [AbpSettingManagementPermissions.Settings.Manager]) |
||||
|
?.WithOrder(6) |
||||
|
?.WithValueType(ValueType.Boolean) |
||||
|
?.ReplaceProviders( |
||||
|
DefaultValueSettingValueProvider.ProviderName, |
||||
|
ConfigurationSettingValueProvider.ProviderName, |
||||
|
GlobalSettingValueProvider.ProviderName, |
||||
|
TenantSettingValueProvider.ProviderName); |
||||
|
} |
||||
|
|
||||
|
public static LocalizableString L(string name) |
||||
|
{ |
||||
|
return LocalizableString.Create<AbpSettingManagementResource>(name); |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,48 @@ |
|||||
|
using System; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; |
||||
|
|
||||
|
#nullable disable |
||||
|
|
||||
|
namespace LINGYUN.Abp.MicroService.AuthServer.Migrations |
||||
|
{ |
||||
|
/// <inheritdoc />
|
||||
|
public partial class AddIdentityUserInactive : Migration |
||||
|
{ |
||||
|
/// <inheritdoc />
|
||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.CreateTable( |
||||
|
name: "AbpUserInactives", |
||||
|
columns: table => new |
||||
|
{ |
||||
|
Id = table.Column<long>(type: "bigint", nullable: false) |
||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), |
||||
|
UserId = table.Column<Guid>(type: "uuid", nullable: false), |
||||
|
TenantId = table.Column<Guid>(type: "uuid", nullable: true), |
||||
|
LastSignInTime = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false), |
||||
|
LastNotificationTime = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true), |
||||
|
Status = table.Column<int>(type: "integer", nullable: false), |
||||
|
DeactivatedTime = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true), |
||||
|
CreationTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false), |
||||
|
CreatorId = table.Column<Guid>(type: "uuid", nullable: true) |
||||
|
}, |
||||
|
constraints: table => |
||||
|
{ |
||||
|
table.PrimaryKey("PK_AbpUserInactives", x => x.Id); |
||||
|
}); |
||||
|
|
||||
|
migrationBuilder.CreateIndex( |
||||
|
name: "IX_AbpUserInactives_TenantId_UserId", |
||||
|
table: "AbpUserInactives", |
||||
|
columns: new[] { "TenantId", "UserId" }); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropTable( |
||||
|
name: "AbpUserInactives"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,9 +1,9 @@ |
|||||
{ |
{ |
||||
"version": "10.2.0", |
"version": "10.4.0", |
||||
"name": "my-app-authserver", |
"name": "aspire-authserver", |
||||
"private": true, |
"private": true, |
||||
"dependencies": { |
"dependencies": { |
||||
"@abp/aspnetcore.mvc.ui.theme.leptonxlite": "5.2.0", |
"@abp/aspnetcore.mvc.ui.theme.leptonxlite": "5.4.0", |
||||
"@abp/qrcode": "10.2.0" |
"@abp/qrcode": "10.4.0" |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,120 @@ |
|||||
|
using LINGYUN.Abp.Notifications; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace LINGYUN.Abp.MicroService.MessageService.DataSeeds; |
||||
|
|
||||
|
public class NotificationDataSeeder : ITransientDependency |
||||
|
{ |
||||
|
public ILogger<NotificationDataSeeder> Logger { protected get; set; } |
||||
|
protected INotificationSender NotificationSender { get; } |
||||
|
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; } |
||||
|
public NotificationDataSeeder( |
||||
|
INotificationSender notificationSender, |
||||
|
INotificationSubscriptionManager notificationSubscriptionManager) |
||||
|
{ |
||||
|
NotificationSender = notificationSender; |
||||
|
NotificationSubscriptionManager = notificationSubscriptionManager; |
||||
|
|
||||
|
Logger = NullLogger<NotificationDataSeeder>.Instance; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task SeedAsync(DataSeedContext context) |
||||
|
{ |
||||
|
await SubscribeDefaultNotifierAsync(context); |
||||
|
await SeedWelcomeNotifierAsync(context); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task SubscribeDefaultNotifierAsync(DataSeedContext context) |
||||
|
{ |
||||
|
if (!context.Properties.TryGetValue(MessageServiceDataSeedConsts.AdminUserIdPropertyName, out var userIdString) || |
||||
|
!Guid.TryParse(userIdString?.ToString(), out var adminUserId)) |
||||
|
{ |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
var adminUserName = context.Properties.GetOrDefault(MessageServiceDataSeedConsts.AdminUserNamePropertyName)?.ToString() |
||||
|
?? MessageServiceDataSeedConsts.AdminUserNameDefaultValue; |
||||
|
var userIdentifer = new UserIdentifier(adminUserId, adminUserName); |
||||
|
// 订阅内置通知
|
||||
|
await NotificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
context.TenantId, |
||||
|
userIdentifer, |
||||
|
DefaultNotifications.SystemNotice); |
||||
|
await NotificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
context.TenantId, |
||||
|
userIdentifer, |
||||
|
DefaultNotifications.OnsideNotice); |
||||
|
await NotificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
context.TenantId, |
||||
|
userIdentifer, |
||||
|
DefaultNotifications.ActivityNotice); |
||||
|
// 订阅用户欢迎消息
|
||||
|
await NotificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
context.TenantId, |
||||
|
userIdentifer, |
||||
|
UserNotificationNames.WelcomeToApplication); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task SeedWelcomeNotifierAsync(DataSeedContext context) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
if (!context.TenantId.HasValue) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
if (!context.Properties.TryGetValue(MessageServiceDataSeedConsts.AdminUserIdPropertyName, out var userIdString) || |
||||
|
!Guid.TryParse(userIdString?.ToString(), out var adminUserId)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
var adminEmailAddress = context.Properties.GetOrDefault(MessageServiceDataSeedConsts.AdminEmailPropertyName)?.ToString() |
||||
|
?? MessageServiceDataSeedConsts.AdminEmailDefaultValue; |
||||
|
var adminUserName = context.Properties.GetOrDefault(MessageServiceDataSeedConsts.AdminUserNamePropertyName)?.ToString() |
||||
|
?? MessageServiceDataSeedConsts.AdminUserNameDefaultValue; |
||||
|
|
||||
|
var tenantAdminUserIdentifier = new UserIdentifier(adminUserId, adminEmailAddress); |
||||
|
|
||||
|
// 租户管理员订阅事件
|
||||
|
await NotificationSubscriptionManager |
||||
|
.SubscribeAsync( |
||||
|
context.TenantId, |
||||
|
tenantAdminUserIdentifier, |
||||
|
TenantNotificationNames.NewTenantRegistered); |
||||
|
|
||||
|
Logger.LogInformation("publish new tenant notification.."); |
||||
|
await NotificationSender.SendNofiterAsync( |
||||
|
TenantNotificationNames.NewTenantRegistered, |
||||
|
new NotificationTemplate( |
||||
|
TenantNotificationNames.NewTenantRegistered, |
||||
|
formUser: adminEmailAddress, |
||||
|
data: new Dictionary<string, object> |
||||
|
{ |
||||
|
{ "name", adminUserName }, |
||||
|
{ "email", adminEmailAddress }, |
||||
|
{ "id", context.TenantId }, |
||||
|
}), |
||||
|
tenantAdminUserIdentifier, |
||||
|
context.TenantId, |
||||
|
NotificationSeverity.Success); |
||||
|
|
||||
|
Logger.LogInformation("tenant administrator subscribes to new tenant events.."); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning(ex, "Failed to send the tenant initialization notification."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
namespace LINGYUN.Abp.MicroService.MessageService; |
||||
|
|
||||
|
public static class MessageServiceDataSeedConsts |
||||
|
{ |
||||
|
public const string AdminUserIdPropertyName = "AdminUserId"; |
||||
|
public const string AdminEmailPropertyName = "AdminEmail"; |
||||
|
public const string AdminEmailDefaultValue = "admin@abp.io"; |
||||
|
public const string AdminUserNamePropertyName = "AdminUserName"; |
||||
|
public const string AdminUserNameDefaultValue = "admin"; |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using LINGYUN.Abp.MicroService.MessageService.DataSeeds; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace LINGYUN.Abp.MicroService.MessageService; |
||||
|
|
||||
|
public class MessageServiceDataSeeder : ITransientDependency |
||||
|
{ |
||||
|
protected NotificationDataSeeder NotificationDataSeeder { get; } |
||||
|
protected ICurrentTenant CurrentTenant { get; } |
||||
|
public MessageServiceDataSeeder( |
||||
|
ICurrentTenant currentTenant, |
||||
|
NotificationDataSeeder notificationDataSeeder) |
||||
|
{ |
||||
|
CurrentTenant = currentTenant; |
||||
|
NotificationDataSeeder = notificationDataSeeder; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task SeedAsync(DataSeedContext context) |
||||
|
{ |
||||
|
using (CurrentTenant.Change(context.TenantId)) |
||||
|
{ |
||||
|
await SeedNotificationAsync(context); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task SeedNotificationAsync(DataSeedContext context) |
||||
|
{ |
||||
|
await NotificationDataSeeder.SeedAsync(context); |
||||
|
} |
||||
|
} |
||||
@ -1,70 +0,0 @@ |
|||||
using LINGYUN.Abp.Data.DbMigrator; |
|
||||
using LINGYUN.Abp.MicroService.MessageService.MultiTenancy; |
|
||||
using LINGYUN.Abp.Notifications; |
|
||||
using LINGYUN.Abp.Saas.Tenants; |
|
||||
using Microsoft.Extensions.Logging; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.Domain.Entities.Events.Distributed; |
|
||||
using Volo.Abp.EventBus.Distributed; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
using Volo.Abp.Uow; |
|
||||
|
|
||||
namespace LINGYUN.Abp.MicroService.MessageService.Handlers.Distributed |
|
||||
{ |
|
||||
public class TenantSynchronizer : |
|
||||
IDistributedEventHandler<EntityCreatedEto<TenantEto>>, |
|
||||
IDistributedEventHandler<EntityUpdatedEto<TenantEto>>, |
|
||||
IDistributedEventHandler<EntityDeletedEto<TenantEto>>, |
|
||||
IDistributedEventHandler<TenantConnectionStringUpdatedEto>, |
|
||||
ITransientDependency |
|
||||
{ |
|
||||
protected ILogger<TenantSynchronizer> Logger { get; } |
|
||||
protected ICurrentTenant CurrentTenant { get; } |
|
||||
protected IUnitOfWorkManager UnitOfWorkManager { get; } |
|
||||
protected IDbSchemaMigrator DbSchemaMigrator { get; } |
|
||||
protected INotificationSender NotificationSender { get; } |
|
||||
protected ITenantConfigurationCache TenantConfigurationCache { get; } |
|
||||
protected INotificationSubscriptionManager NotificationSubscriptionManager { get; } |
|
||||
|
|
||||
public TenantSynchronizer( |
|
||||
ICurrentTenant currentTenant, |
|
||||
IDbSchemaMigrator dbSchemaMigrator, |
|
||||
IUnitOfWorkManager unitOfWorkManager, |
|
||||
INotificationSender notificationSender, |
|
||||
ITenantConfigurationCache tenantConfigurationCache, |
|
||||
INotificationSubscriptionManager notificationSubscriptionManager, |
|
||||
ILogger<TenantSynchronizer> logger) |
|
||||
{ |
|
||||
Logger = logger; |
|
||||
|
|
||||
CurrentTenant = currentTenant; |
|
||||
DbSchemaMigrator = dbSchemaMigrator; |
|
||||
UnitOfWorkManager = unitOfWorkManager; |
|
||||
TenantConfigurationCache = tenantConfigurationCache; |
|
||||
|
|
||||
NotificationSender = notificationSender; |
|
||||
NotificationSubscriptionManager = notificationSubscriptionManager; |
|
||||
} |
|
||||
|
|
||||
public async virtual Task HandleEventAsync(EntityCreatedEto<TenantEto> eventData) |
|
||||
{ |
|
||||
await TenantConfigurationCache.RefreshAsync(); |
|
||||
} |
|
||||
|
|
||||
public async virtual Task HandleEventAsync(EntityUpdatedEto<TenantEto> eventData) |
|
||||
{ |
|
||||
await TenantConfigurationCache.RefreshAsync(); |
|
||||
} |
|
||||
|
|
||||
public async virtual Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData) |
|
||||
{ |
|
||||
await TenantConfigurationCache.RefreshAsync(); |
|
||||
} |
|
||||
|
|
||||
public async virtual Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData) |
|
||||
{ |
|
||||
await TenantConfigurationCache.RefreshAsync(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue