diff --git a/.changes/Migration 10.2.0 - 10.4.0.md b/.changes/Migration 10.2.0 - 10.4.0.md new file mode 100644 index 000000000..864bde8f2 --- /dev/null +++ b/.changes/Migration 10.2.0 - 10.4.0.md @@ -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 | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2af9bb3f9..fd3852373 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,4 +14,4 @@ jobs: with: repo_token: "${{ secrets.GITHUB_TOKEN }}" prerelease: false - automatic_release_tag: "10.2.0" + automatic_release_tag: "10.4.0" diff --git a/Directory.Packages.props b/Directory.Packages.props index b9d54b3e0..eae775c5f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,17 +3,17 @@ 10.0.0 2.16.1 3.6.0 - 10.2.0 - 10.2.0 - 10.0.2 - 10.0.2 - 10.0.2 + 10.4.0 + 10.4.0 + 10.0.7 + 10.0.7 + 10.0.7 13.1.0 true - + @@ -164,7 +164,7 @@ - + @@ -186,11 +186,11 @@ - + - + @@ -200,7 +200,7 @@ - + @@ -276,16 +276,16 @@ - - - - - - + + + + + + - - - + + + @@ -318,7 +318,7 @@ - + @@ -333,6 +333,10 @@ + + + + @@ -350,6 +354,7 @@ + @@ -360,8 +365,8 @@ - - + + @@ -378,7 +383,7 @@ - + diff --git a/apps/vben5/apps/app-antd/src/layouts/basic.vue b/apps/vben5/apps/app-antd/src/layouts/basic.vue index c2682b198..eeb8302f4 100644 --- a/apps/vben5/apps/app-antd/src/layouts/basic.vue +++ b/apps/vben5/apps/app-antd/src/layouts/basic.vue @@ -1,10 +1,10 @@ + + + + + + + {{ $t('AbpAccount.LinkUser:New') }} + + + + + + + + + + + + {{ $t('AbpAccount.LinkUser:Login') }} + + + {{ $t('AbpUi.Delete') }} + + + + + + + + diff --git a/apps/vben5/packages/@abp/account/src/components/index.ts b/apps/vben5/packages/@abp/account/src/components/index.ts index 807e2f91a..3bbd032e1 100644 --- a/apps/vben5/packages/@abp/account/src/components/index.ts +++ b/apps/vben5/packages/@abp/account/src/components/index.ts @@ -1,3 +1,4 @@ export { default as MyProfile } from './MyProfile.vue'; export { default as MySetting } from './MySetting.vue'; export { default as QrCodeLogin } from './QrCodeLogin.vue'; +export { default as UserLinkModal } from './UserLinkModal.vue'; diff --git a/apps/vben5/packages/@abp/account/src/hooks/useOAuthService.ts b/apps/vben5/packages/@abp/account/src/hooks/useOAuthService.ts index 92e064aeb..d5e87dd90 100644 --- a/apps/vben5/packages/@abp/account/src/hooks/useOAuthService.ts +++ b/apps/vben5/packages/@abp/account/src/hooks/useOAuthService.ts @@ -1,4 +1,7 @@ +import type { SigninRedirectArgs, SignoutRedirectArgs } from 'oidc-client-ts'; + import type { + LinkUserTokenRequest, PasswordTokenRequestModel, PhoneNumberTokenRequest, QrCodeTokenRequest, @@ -7,8 +10,12 @@ import type { import { userManager } from '../utils/auth'; export function useOAuthService() { - async function login() { - return userManager.signinRedirect(); + async function login(args?: SigninRedirectArgs) { + return userManager.signinRedirect(args); + } + + async function loginByLinkUser(input: LinkUserTokenRequest) { + return userManager.signinLinkUser(input); } async function loginByPassword(input: PasswordTokenRequestModel) { @@ -23,8 +30,8 @@ export function useOAuthService() { return userManager.signinQrCode(input); } - async function logout() { - return userManager.signoutRedirect(); + async function logout(args?: SignoutRedirectArgs) { + return userManager.signoutRedirect(args); } async function revokeTokens() { @@ -55,6 +62,7 @@ export function useOAuthService() { return { login, + loginByLinkUser, loginByPassword, loginBySmsCode, loginByQrCode, diff --git a/apps/vben5/packages/@abp/account/src/types/index.ts b/apps/vben5/packages/@abp/account/src/types/index.ts index 0f182a66b..dae3e2f1b 100644 --- a/apps/vben5/packages/@abp/account/src/types/index.ts +++ b/apps/vben5/packages/@abp/account/src/types/index.ts @@ -1,6 +1,8 @@ export * from './account'; export * from './bind'; export * from './external-logins'; +export * from './link-user'; export * from './profile'; export * from './token'; export * from './user'; +export type { SigninRedirectArgs } from 'oidc-client-ts'; diff --git a/apps/vben5/packages/@abp/account/src/types/link-user.ts b/apps/vben5/packages/@abp/account/src/types/link-user.ts new file mode 100644 index 000000000..c80c605f4 --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/types/link-user.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 }; diff --git a/apps/vben5/packages/@abp/account/src/types/token.ts b/apps/vben5/packages/@abp/account/src/types/token.ts index 653b5cde8..cf06a2e11 100644 --- a/apps/vben5/packages/@abp/account/src/types/token.ts +++ b/apps/vben5/packages/@abp/account/src/types/token.ts @@ -38,6 +38,15 @@ interface PasswordTokenRequestModel { /** 用户名 */ username: string; } +/** 关联用户授权请求数据模型 */ +interface LinkUserTokenRequest { + /** 当前用户访问令牌 */ + accessToken?: string; + /** 关联用户租户Id */ + linkTenantId?: string; + /** 关联用户Id */ + linkUserId: string; +} /** 令牌撤销请求数据类型 */ interface RevokeTokenRequest { /** 令牌 */ @@ -92,6 +101,7 @@ interface ShouldChangePasswordError extends OAuthError { } export type { + LinkUserTokenRequest, OAuthError, OAuthTokenRefreshModel, OAuthTokenResult, diff --git a/apps/vben5/packages/@abp/account/src/utils/auth.ts b/apps/vben5/packages/@abp/account/src/utils/auth.ts index bc15f2775..b32ca9ae9 100644 --- a/apps/vben5/packages/@abp/account/src/utils/auth.ts +++ b/apps/vben5/packages/@abp/account/src/utils/auth.ts @@ -1,6 +1,7 @@ import type { Logger, UserManagerSettings } from 'oidc-client-ts'; import type { + LinkUserTokenRequest, PasswordTokenRequestModel, PhoneNumberTokenRequest, QrCodeTokenRequest, @@ -71,6 +72,28 @@ class AbpUserManager extends UserManager { params.set('userId', model.userId); } } + async signinLinkUser(params: LinkUserTokenRequest) { + const logger = this._logger.create('signinLinkUser'); + const body = new URLSearchParams({ + LinkUserId: params.linkUserId, + grant_type: 'link_user', + client_id: this.settings.client_id, + }); + if (params.accessToken) { + body.set('access_token', params.accessToken); + } + if (params.linkTenantId) { + body.set('LinkTenantId', params.linkTenantId); + } + const client_secret = this.settings.client_secret; + if (client_secret) { + body.set('client_secret', client_secret); + } + this._writeUserId(body, params); + this._writeTenantId(body, params); + this._writeTwoFactorToken(body, params); + return await this._fetchUser(logger, body); + } async signinQrCode(params: QrCodeTokenRequest) { const logger = this._logger.create('signinQrCode'); const client_secret = this.settings.client_secret; @@ -89,7 +112,6 @@ class AbpUserManager extends UserManager { this._writeTwoFactorToken(body, params); return await this._fetchUser(logger, body); } - override async signinResourceOwnerCredentials( params: PasswordTokenRequestModel, ) { @@ -111,7 +133,6 @@ class AbpUserManager extends UserManager { this._writeChangePasswordToken(body, params); return await this._fetchUser(logger, body); } - async signinSmsCode(params: PhoneNumberTokenRequest) { const logger = this._logger.create('signinSmsCode'); const client_secret = this.settings.client_secret; diff --git a/apps/vben5/packages/@abp/ai-management/src/components/tools/AIToolDefinitionTable.vue b/apps/vben5/packages/@abp/ai-management/src/components/tools/AIToolDefinitionTable.vue index fe687793c..72ebd68af 100644 --- a/apps/vben5/packages/@abp/ai-management/src/components/tools/AIToolDefinitionTable.vue +++ b/apps/vben5/packages/@abp/ai-management/src/components/tools/AIToolDefinitionTable.vue @@ -140,7 +140,8 @@ const gridOptions: VxeGridProps = { custom: true, export: true, // import: true, - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, zoom: true, diff --git a/apps/vben5/packages/@abp/ai-management/src/components/workspaces/WorkspaceDefinitionTable.vue b/apps/vben5/packages/@abp/ai-management/src/components/workspaces/WorkspaceDefinitionTable.vue index d59fb691e..dc35d5766 100644 --- a/apps/vben5/packages/@abp/ai-management/src/components/workspaces/WorkspaceDefinitionTable.vue +++ b/apps/vben5/packages/@abp/ai-management/src/components/workspaces/WorkspaceDefinitionTable.vue @@ -130,7 +130,8 @@ const gridOptions: VxeGridProps = { custom: true, export: true, // import: true, - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, zoom: true, diff --git a/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue b/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue index d841a8a50..7aa2848b8 100644 --- a/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue +++ b/apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue @@ -241,7 +241,8 @@ const gridOptions: VxeGridProps = { custom: true, export: true, // import: true, - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, zoom: true, diff --git a/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingDrawer.vue b/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingDrawer.vue index 2db94f182..ede5a944e 100644 --- a/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingDrawer.vue +++ b/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingDrawer.vue @@ -219,7 +219,7 @@ async function onGet(id: string) { {{ row.hResult }} - {{ row.helpURL }} + {{ row.helpUrl }} diff --git a/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingTable.vue b/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingTable.vue index edb0db0a0..d4bd06923 100644 --- a/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingTable.vue +++ b/apps/vben5/packages/@abp/auditing/src/components/loggings/LoggingTable.vue @@ -278,7 +278,8 @@ const gridOptions: VxeGridProps = { toolbarConfig: { custom: true, export: true, - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, zoom: true, diff --git a/apps/vben5/packages/@abp/blob-management/package.json b/apps/vben5/packages/@abp/blob-management/package.json index de1e2f0ec..93fddb80b 100644 --- a/apps/vben5/packages/@abp/blob-management/package.json +++ b/apps/vben5/packages/@abp/blob-management/package.json @@ -37,13 +37,10 @@ "@vben/locales": "workspace:*", "@vben/stores": "workspace:*", "@vben/utils": "workspace:*", - "@vue-office/docx": "catalog:", - "@vue-office/excel": "catalog:", - "@vue-office/pdf": "catalog:", - "@vue-office/pptx": "catalog:", "ant-design-vue": "catalog:", "vue": "catalog:", "vue-demi": "catalog:", + "vue-files-preview": "catalog:", "vue-simple-uploader": "catalog:", "vxe-table": "catalog:" } diff --git a/apps/vben5/packages/@abp/blob-management/src/api/useBlobsApi.ts b/apps/vben5/packages/@abp/blob-management/src/api/useBlobsApi.ts index f1c109147..9ea8590f7 100644 --- a/apps/vben5/packages/@abp/blob-management/src/api/useBlobsApi.ts +++ b/apps/vben5/packages/@abp/blob-management/src/api/useBlobsApi.ts @@ -32,8 +32,26 @@ export function useBlobsApi() { }); } - function getContentApi(id: string): Promise { - return request(`/api/blob-management/blobs/uid/${id}/content`, { + function generateDownloadUrlApi(id: string): Promise { + return request( + `/api/blob-management/blobs/generate/download-url/${id}`, + { + method: 'GET', + }, + ); + } + + function generatePreviewUrlApi(id: string): Promise { + return request( + `/api/blob-management/blobs/generate/preview-url/${id}`, + { + method: 'GET', + }, + ); + } + + function downloadApi(id: string): Promise { + return request(`/api/blob-management/blobs/download/${id}`, { method: 'GET', responseType: 'blob', }); @@ -70,8 +88,10 @@ export function useBlobsApi() { cancel, createFolderApi, deleteApi, + downloadApi, getApi, - getContentApi, + generateDownloadUrlApi, + generatePreviewUrlApi, getFolderPagedListApi, getFilePagedListApi, getPagedListApi, diff --git a/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal.vue b/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal.vue index 55caa5ddf..69868c3ff 100644 --- a/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal.vue +++ b/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal.vue @@ -64,7 +64,7 @@ const blobType = ref(); const errorMessage = ref(''); const excelComponentKey = ref(0); // 只对 Excel 组件使用 key -const { getContentApi } = useBlobsApi(); +const { downloadApi } = useBlobsApi(); // 文件类型配置 const allowFiles: Record = { @@ -175,7 +175,7 @@ async function onInit() { } // 获取文件内容 - const content = await getContentApi(blob.value.id); + const content = await downloadApi(blob.value.id); // 检查文件大小 if (!isFileSizeValid(content)) { diff --git a/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal1.vue b/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal1.vue new file mode 100644 index 000000000..aac734a60 --- /dev/null +++ b/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFilePreviewModal1.vue @@ -0,0 +1,106 @@ + + + + + + + + + + + {{ $t('BlobManagement.Blobs:Download') }} + + + + + + + diff --git a/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFileTable.vue b/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFileTable.vue index 36dab6532..2d8cdd2ad 100644 --- a/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFileTable.vue +++ b/apps/vben5/packages/@abp/blob-management/src/components/blobs/BlobFileTable.vue @@ -35,7 +35,7 @@ const kbUnit = 1 * 1024; const mbUnit = kbUnit * 1024; const gbUnit = mbUnit * 1024; -const { deleteApi, getPagedListApi } = useBlobsApi(); +const { deleteApi, getPagedListApi, generateDownloadUrlApi } = useBlobsApi(); const selectedKeys = ref([]); @@ -169,7 +169,7 @@ const [BlobFileUploadModal, uploadModalApi] = useVbenModal({ }); const [BlobFilePreviewModal, previewModalApi] = useVbenModal({ connectedComponent: defineAsyncComponent( - () => import('./BlobFilePreviewModal.vue'), + () => import('./BlobFilePreviewModal1.vue'), ), }); @@ -191,10 +191,11 @@ function onDownload(row: BlobDto) { centered: true, content: $t('BlobManagement.BlobWellDownloadMessage', [row.name]), onCancel: () => {}, - onOk: () => { + onOk: async () => { + const downloadUrl = await generateDownloadUrlApi(row.id); downloadFileFromUrl({ fileName: row.name, - source: `/api/blob-management/blobs/uid/${row.id}/content`, + source: downloadUrl, }); }, title: $t('AbpUi.AreYouSure'), diff --git a/apps/vben5/packages/@abp/blob-management/src/components/containers/BlobContainerTable.vue b/apps/vben5/packages/@abp/blob-management/src/components/containers/BlobContainerTable.vue index 2f544fe6f..832fa8162 100644 --- a/apps/vben5/packages/@abp/blob-management/src/components/containers/BlobContainerTable.vue +++ b/apps/vben5/packages/@abp/blob-management/src/components/containers/BlobContainerTable.vue @@ -109,7 +109,8 @@ const gridOptions: VxeGridProps = { toolbarConfig: { custom: true, export: true, - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, zoom: true, diff --git a/apps/vben5/packages/@abp/data-protection/src/components/entity-type-infos/EntityTypeInfoTable.vue b/apps/vben5/packages/@abp/data-protection/src/components/entity-type-infos/EntityTypeInfoTable.vue index 37b37e797..574e3f8ee 100644 --- a/apps/vben5/packages/@abp/data-protection/src/components/entity-type-infos/EntityTypeInfoTable.vue +++ b/apps/vben5/packages/@abp/data-protection/src/components/entity-type-infos/EntityTypeInfoTable.vue @@ -91,7 +91,8 @@ const gridOptions: VxeGridProps = { }, }, toolbarConfig: { - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, }, diff --git a/apps/vben5/packages/@abp/demo/src/components/books/BookTable.vue b/apps/vben5/packages/@abp/demo/src/components/books/BookTable.vue index c524544e0..858f22175 100644 --- a/apps/vben5/packages/@abp/demo/src/components/books/BookTable.vue +++ b/apps/vben5/packages/@abp/demo/src/components/books/BookTable.vue @@ -108,7 +108,8 @@ const gridOptions: VxeGridProps = { }, }, toolbarConfig: { - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, }, diff --git a/apps/vben5/packages/@abp/features/src/components/features/FeatureModal.vue b/apps/vben5/packages/@abp/features/src/components/features/FeatureModal.vue index 57bd213f5..0d3ec8e92 100644 --- a/apps/vben5/packages/@abp/features/src/components/features/FeatureModal.vue +++ b/apps/vben5/packages/@abp/features/src/components/features/FeatureModal.vue @@ -269,7 +269,7 @@ async function onSubmit() { + diff --git a/apps/vben5/packages/@abp/settings/src/components/settings/SystemSetting.vue b/apps/vben5/packages/@abp/settings/src/components/settings/SystemSetting.vue index 25d0d2cc0..c1c144fe7 100644 --- a/apps/vben5/packages/@abp/settings/src/components/settings/SystemSetting.vue +++ b/apps/vben5/packages/@abp/settings/src/components/settings/SystemSetting.vue @@ -6,7 +6,7 @@ import { ref } from 'vue'; import { useVbenModal } from '@vben/common-ui'; import { $t } from '@vben/locales'; -import { isEmail, useAbpStore } from '@abp/core'; +import { isEmail } from '@abp/core'; import { FeatureModal } from '@abp/features'; import { Button, Form, InputSearch, message, Modal } from 'ant-design-vue'; @@ -19,14 +19,7 @@ defineOptions({ const FormItem = Form.Item; -const abpStore = useAbpStore(); -const { - getGlobalSettingsApi, - getTenantSettingsApi, - sendTestEmailApi, - setGlobalSettingsApi, - setTenantSettingsApi, -} = useSettingsApi(); +const { getSettingsApi, setSettingsApi, sendTestEmailApi } = useSettingsApi(); const [HostFeatureModal, featureModalApi] = useVbenModal({ connectedComponent: FeatureModal, }); @@ -34,18 +27,12 @@ const [HostFeatureModal, featureModalApi] = useVbenModal({ const sending = ref(false); async function onGet() { - const api = abpStore.application?.currentTenant.isAvailable - ? getTenantSettingsApi - : getGlobalSettingsApi; - const { items } = await api(); + const { items } = await getSettingsApi(); return items; } async function onSubmit(input: SettingsUpdateInput) { - const api = abpStore.application?.currentTenant.isAvailable - ? setTenantSettingsApi - : setGlobalSettingsApi; - await api(input); + await setSettingsApi(input); } async function onSendMail(email: string) { diff --git a/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoDrawer.vue b/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoDrawer.vue index 715ffb614..d00607eb5 100644 --- a/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoDrawer.vue +++ b/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoDrawer.vue @@ -27,7 +27,7 @@ import { } from 'ant-design-vue'; import { useJobInfosApi } from '../../api/useJobInfosApi'; -import { JobPriority, JobType } from '../../types/job-infos'; +import { JobPriority, JobSource, JobType } from '../../types/job-infos'; defineOptions({ name: 'JobInfoDrawer', @@ -40,6 +40,9 @@ interface JobParamter { key: string; value: any; } +interface ModalState extends BackgroundJobInfoDto { + isCopy?: boolean; +} const activedTab = ref('basic'); const jobTypeOptions = reactive([ @@ -79,6 +82,7 @@ const jobPriorityOptions = reactive([ }, ]); const jobDefinetions = ref([]); +const jobArgsDisplayNameMap = ref>({}); const form = useTemplateRef('form'); const formModel = ref({} as BackgroundJobInfoDto); const { createApi, getApi, getDefinitionsApi, updateApi } = useJobInfosApi(); @@ -101,9 +105,9 @@ const [Drawer, drawerApi] = useVbenDrawer({ priority: JobPriority.Normal, } as BackgroundJobInfoDto; drawerApi.setState({ loading: true }); - const dto = drawerApi.getData(); - if (dto?.id) { - await onGet(dto.id); + const state = drawerApi.getData(); + if (state?.id) { + await onGet(state.id, state.isCopy); } else { await onInitDefaultJobs(); drawerApi.setState({ @@ -117,12 +121,23 @@ const [Drawer, drawerApi] = useVbenDrawer({ }, title: $t('BackgroundJobs:Edit'), }); -async function onGet(id: string) { + +async function onGet(id: string, isCopy?: boolean) { const dto = await getApi(id); + if (isCopy === true) { + dto.id = ''; + dto.name = ''; + dto.source = JobSource.User; + drawerApi.setState({ + title: $t('TaskManagement.BackgroundJobs:AddNew'), + }); + await onInitDefaultJobs(); + } else { + drawerApi.setState({ + title: `${$t('TaskManagement.BackgroundJobs:Edit')} - ${dto.name}`, + }); + } formModel.value = dto; - drawerApi.setState({ - title: `${$t('TaskManagement.BackgroundJobs:Edit')} - ${dto.name}`, - }); } async function onInitDefaultJobs() { @@ -148,14 +163,18 @@ async function onSubmit() { function onJobDefineChange(jobName: string) { formModel.value.args = {}; + jobArgsDisplayNameMap.value = {}; const jobDefine = jobDefinetions.value.find((x) => x.name === jobName); if (jobDefine) { const params: Record = {}; + const paramDisplayNames: Record = {}; jobDefine.paramters.forEach((param) => { params[param.name] = undefined; + paramDisplayNames[param.name] = param.displayName; }); formModel.value.args = params; formModel.value.type = jobDefine.name; + jobArgsDisplayNameMap.value = paramDisplayNames; } } @@ -206,6 +225,7 @@ function onDeleteParam(record: JobParamter) { > @@ -217,6 +237,7 @@ function onDeleteParam(record: JobParamter) { > @@ -228,6 +249,7 @@ function onDeleteParam(record: JobParamter) { > @@ -241,6 +263,7 @@ function onDeleteParam(record: JobParamter) { @@ -280,7 +303,16 @@ function onDeleteParam(record: JobParamter) { /> + + + diff --git a/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoTable.vue b/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoTable.vue index f656debe9..7f6d64983 100644 --- a/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoTable.vue +++ b/apps/vben5/packages/@abp/tasks/src/components/job-infos/JobInfoTable.vue @@ -16,6 +16,7 @@ import { $t } from '@vben/locales'; import { formatToDateTime } from '@abp/core'; import { useVbenVxeGrid } from '@abp/ui'; import { + CopyOutlined, DeleteOutlined, EditOutlined, EllipsisOutlined, @@ -25,6 +26,7 @@ import { Button, Dropdown, Menu, + MenuDivider, MenuItem, message, Modal, @@ -387,7 +389,8 @@ const gridOptions: VxeGridProps = { }, }, toolbarConfig: { - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, }, @@ -515,6 +518,14 @@ function onBulkStart() { function onMenuClick(row: BackgroundJobInfoDto, info: MenuInfo) { switch (info.key) { + case 'copy': { + jobDrawerApi.setData({ + ...row, + isCopy: true, + }); + jobDrawerApi.open(); + break; + } case 'pause': { onJobStatusChange( row, @@ -722,6 +733,14 @@ function onJobStatusChange( > {{ $t('TaskManagement.BackgroundJobs:Stop') }} + + + {{ $t('TaskManagement.BackgroundJobs:Copy') }} + diff --git a/apps/vben5/packages/@abp/tasks/src/types/job-infos.ts b/apps/vben5/packages/@abp/tasks/src/types/job-infos.ts index bb519da26..82b3eaa9c 100644 --- a/apps/vben5/packages/@abp/tasks/src/types/job-infos.ts +++ b/apps/vben5/packages/@abp/tasks/src/types/job-infos.ts @@ -35,8 +35,7 @@ enum JobSource { } interface BackgroundJobInfoDto - extends ExtensibleAuditedEntityDto, - IHasConcurrencyStamp { + extends ExtensibleAuditedEntityDto, IHasConcurrencyStamp { args: Record; beginTime: string; cron?: string; @@ -53,6 +52,7 @@ interface BackgroundJobInfoDto maxTryCount: number; name: string; nextRunTime?: string; + nodeName?: string; priority: JobPriority; result?: string; source: JobSource; @@ -75,8 +75,7 @@ interface BackgroundJobInfoCreateOrUpdateDto { priority: JobPriority; } -interface BackgroundJobInfoCreateDto - extends BackgroundJobInfoCreateOrUpdateDto { +interface BackgroundJobInfoCreateDto extends BackgroundJobInfoCreateOrUpdateDto { beginTime: string; endTime?: string; group: string; @@ -87,8 +86,7 @@ interface BackgroundJobInfoCreateDto } interface BackgroundJobInfoUpdateDto - extends BackgroundJobInfoCreateOrUpdateDto, - IHasConcurrencyStamp {} + extends BackgroundJobInfoCreateOrUpdateDto, IHasConcurrencyStamp {} interface BackgroundJobInfoGetListInput extends PagedAndSortedResultRequestDto { beginCreationTime?: Date; diff --git a/apps/vben5/packages/@abp/ui/src/components/properties/PropertyTable.vue b/apps/vben5/packages/@abp/ui/src/components/properties/PropertyTable.vue index 6a377f570..7f7819829 100644 --- a/apps/vben5/packages/@abp/ui/src/components/properties/PropertyTable.vue +++ b/apps/vben5/packages/@abp/ui/src/components/properties/PropertyTable.vue @@ -46,8 +46,7 @@ const getTableColumns = computed((): TableColumnsType => { { align: 'left', dataIndex: 'key', - fixed: 'left', - width: 100, + width: 150, title: $t('component.extra_property_dictionary.key'), customRender: (opt) => { if (props.renderKey && isFunction(props.renderKey)) { @@ -58,8 +57,8 @@ const getTableColumns = computed((): TableColumnsType => { { align: 'left', dataIndex: 'value', - fixed: 'left', - minWidth: 150, + width: 500, + ellipsis: true, title: $t('component.extra_property_dictionary.value'), }, ]; @@ -74,7 +73,7 @@ const getTableColumns = computed((): TableColumnsType => { fixed: 'right', key: 'action', title: $t('component.extra_property_dictionary.actions.title'), - width: 150, + width: 200, }, ] as TableColumnsType)), ]; @@ -122,7 +121,16 @@ function onChange(prop: Record) { - + + + {{ record.key }} + {{ props.displayNameMap[record.key] }} + + + + ; disabled?: boolean; + displayNameMap?: Dictionary; renderKey?: (key: string) => string | VNode; } diff --git a/apps/vben5/packages/@abp/webhooks/src/components/send-attempts/WebhookSendAttemptTable.vue b/apps/vben5/packages/@abp/webhooks/src/components/send-attempts/WebhookSendAttemptTable.vue index ac89bb49d..dbe1913f2 100644 --- a/apps/vben5/packages/@abp/webhooks/src/components/send-attempts/WebhookSendAttemptTable.vue +++ b/apps/vben5/packages/@abp/webhooks/src/components/send-attempts/WebhookSendAttemptTable.vue @@ -211,7 +211,8 @@ const gridOptions: VxeGridProps = { toolbarConfig: { custom: true, export: true, - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, zoom: true, diff --git a/apps/vben5/packages/@abp/webhooks/src/components/subscriptions/WebhookSubscriptionTable.vue b/apps/vben5/packages/@abp/webhooks/src/components/subscriptions/WebhookSubscriptionTable.vue index 0634ecaff..7f5952a9c 100644 --- a/apps/vben5/packages/@abp/webhooks/src/components/subscriptions/WebhookSubscriptionTable.vue +++ b/apps/vben5/packages/@abp/webhooks/src/components/subscriptions/WebhookSubscriptionTable.vue @@ -210,7 +210,8 @@ const gridOptions: VxeGridProps = { toolbarConfig: { custom: true, export: true, - refresh: { + refresh: true, + refreshOptions: { code: 'query', }, zoom: true, diff --git a/apps/vben5/packages/@abp/wechat/src/components/bind-user/index.vue b/apps/vben5/packages/@abp/wechat/src/components/bind-user/index.vue index bd5d15688..ae96254eb 100644 --- a/apps/vben5/packages/@abp/wechat/src/components/bind-user/index.vue +++ b/apps/vben5/packages/@abp/wechat/src/components/bind-user/index.vue @@ -3,11 +3,13 @@ import { useTemplateRef } from 'vue'; import { useVbenModal } from '@vben/common-ui'; -import { buildUUID } from '@abp/core'; +import { buildUUID, useFeatures } from '@abp/core'; import { WWLoginRedirectType, WWLoginType } from '@wecom/jssdk'; import * as ww from '@wecom/jssdk'; +import { Empty } from 'ant-design-vue'; import { userWorkWeixinJsSdkApi } from '../../api/userWorkWeixinJsSdkApi'; +import { WeixinWorkAuthEnable } from '../../constants/features'; const emits = defineEmits<{ /** @@ -18,6 +20,7 @@ const emits = defineEmits<{ }>(); const wxLoginRef = useTemplateRef('wxLogin'); +const { isEnabled } = useFeatures(); const { getAgentConfigApi } = userWorkWeixinJsSdkApi(); const [Modal, modalApi] = useVbenModal({ @@ -54,7 +57,15 @@ async function onInitLogin() { - + + diff --git a/apps/vben5/packages/@abp/wechat/src/constants/features.ts b/apps/vben5/packages/@abp/wechat/src/constants/features.ts new file mode 100644 index 000000000..bab96f2c5 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/constants/features.ts @@ -0,0 +1,2 @@ +/** 启用企业微信认证 */ +export const WeixinWorkAuthEnable = 'Abp.Account.OAuth.WeCom.Enable'; diff --git a/apps/vben5/pnpm-workspace.yaml b/apps/vben5/pnpm-workspace.yaml index e267880d2..058ee7799 100644 --- a/apps/vben5/pnpm-workspace.yaml +++ b/apps/vben5/pnpm-workspace.yaml @@ -83,6 +83,7 @@ catalog: '@vite-pwa/vitepress': ^1.1.0 '@vitejs/plugin-vue': ^6.0.4 '@vitejs/plugin-vue-jsx': ^5.1.4 + '@vue-files-preview': ^0.0.0 '@vue-office/docx': ^1.6.3 '@vue-office/excel': ^1.7.14 '@vue-office/pdf': ^2.0.10 @@ -235,6 +236,7 @@ catalog: vue: ^3.5.27 vue-demi: ^0.14.6 vue-eslint-parser: ^10.2.0 + vue-files-preview: ^1.0.43 vue-i18n: ^11.2.8 vue-json-viewer: ^3.0.4 vue-router: ^5.0.3 diff --git a/aspnet-core/LINGYUN.MicroService.All.slnx b/aspnet-core/LINGYUN.MicroService.All.slnx index 3b8dc3c56..018ed8791 100644 --- a/aspnet-core/LINGYUN.MicroService.All.slnx +++ b/aspnet-core/LINGYUN.MicroService.All.slnx @@ -1,6 +1,14 @@ + + + + + + + + @@ -85,6 +93,7 @@ + @@ -97,6 +106,9 @@ + + + @@ -116,6 +128,7 @@ + @@ -365,6 +378,7 @@ + @@ -424,6 +438,7 @@ + @@ -471,6 +486,7 @@ + diff --git a/aspnet-core/LINGYUN.MicroService.Aspire.slnx b/aspnet-core/LINGYUN.MicroService.Aspire.slnx index d5539f4c5..bf4fcb03f 100644 --- a/aspnet-core/LINGYUN.MicroService.Aspire.slnx +++ b/aspnet-core/LINGYUN.MicroService.Aspire.slnx @@ -1,6 +1,7 @@ + @@ -90,6 +91,9 @@ + + + @@ -228,10 +232,6 @@ - - - - @@ -319,7 +319,9 @@ + + @@ -449,6 +451,7 @@ + @@ -459,6 +462,9 @@ + + + @@ -495,7 +501,9 @@ + + @@ -568,12 +576,10 @@ - - - + diff --git a/aspnet-core/LINGYUN.MicroService.SingleProject.slnx b/aspnet-core/LINGYUN.MicroService.SingleProject.slnx index 269419841..77245068b 100644 --- a/aspnet-core/LINGYUN.MicroService.SingleProject.slnx +++ b/aspnet-core/LINGYUN.MicroService.SingleProject.slnx @@ -11,6 +11,7 @@ + @@ -36,6 +37,9 @@ + + + @@ -96,6 +100,7 @@ + @@ -207,6 +212,7 @@ + @@ -276,6 +282,7 @@ + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/AIServiceModule.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/AIServiceModule.cs index 148ceb0c3..25cf39627 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/AIServiceModule.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/AIServiceModule.cs @@ -14,6 +14,7 @@ using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.Identity.Session.AspNetCore; using LINGYUN.Abp.Localization.CultureMap; +using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; using LINGYUN.Abp.Logging.Serilog.Elasticsearch; using LINGYUN.Abp.Serilog.Enrichers.Application; using LINGYUN.Abp.Serilog.Enrichers.UniqueId; @@ -57,6 +58,7 @@ namespace LINGYUN.Abp.MicroService.AIService; typeof(AbpAIManagementApplicationModule), typeof(AbpAIManagementHttpApiModule), typeof(AIServiceMigrationsEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), typeof(AbpDataDbMigratorModule), typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpEmailingExceptionHandlingModule), diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/appsettings.Development.json b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/appsettings.Development.json index 095e88d8f..efa09e2e7 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/appsettings.Development.json +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/appsettings.Development.json @@ -35,7 +35,8 @@ "CollectorCleaningInterval": 3600000 }, "PostgreSql": { - "TableNamePrefix": "admin", + "Schema": "ai", + "TableNamePrefix": "ai", "ConnectionString": "Host=127.0.0.1;Database=abp;Username=postgres;Password=123456" }, "RabbitMQ": { diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDataSeeder.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDataSeeder.cs index a94e9bc6d..49ca51707 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDataSeeder.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService.EntityFrameworkCore/AdminServiceDataSeeder.cs @@ -7,6 +7,7 @@ using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; using Volo.Abp.PermissionManagement; +using Volo.Abp.Roles; namespace LINGYUN.Abp.MicroService.AdminService; public class AdminServiceDataSeeder : ITransientDependency @@ -49,7 +50,7 @@ public class AdminServiceDataSeeder : ITransientDependency await PermissionDataSeeder.SeedAsync( RolePermissionValueProvider.ProviderName, - "admin", + AbpRoleConsts.AdminRoleName, permissionNames, context?.TenantId ); diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/AdminServiceModule.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/AdminServiceModule.cs index d5198f7e1..a751ca3fc 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/AdminServiceModule.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/AdminServiceModule.cs @@ -4,6 +4,7 @@ using LINGYUN.Abp.AspNetCore.Mvc.Localization; using LINGYUN.Abp.AspNetCore.Mvc.Wrapper; using LINGYUN.Abp.Auditing; using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.BlobManagement.SettingManagement; using LINGYUN.Abp.CachingManagement; using LINGYUN.Abp.CachingManagement.StackExchangeRedis; using LINGYUN.Abp.Claims.Mapping; @@ -58,6 +59,7 @@ namespace LINGYUN.Abp.MicroService.AdminService; typeof(AbpTencentCloudSettingManagementModule), // typeof(AbpWeChatSettingManagementModule), typeof(AbpWxPusherSettingManagementModule), + typeof(AbpBlobManagementSettingManagementModule), typeof(AbpSettingManagementApplicationModule), typeof(AbpSettingManagementHttpApiModule), diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/LINGYUN.Abp.MicroService.AdminService.csproj b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/LINGYUN.Abp.MicroService.AdminService.csproj index f6010ebc6..a7916e170 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/LINGYUN.Abp.MicroService.AdminService.csproj +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/LINGYUN.Abp.MicroService.AdminService.csproj @@ -55,6 +55,7 @@ + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/SystemGroupSettingDefinitionProvider.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/SystemGroupSettingDefinitionProvider.cs new file mode 100644 index 000000000..e964206d8 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/SystemGroupSettingDefinitionProvider.cs @@ -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 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(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(); + 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(name); + } +} diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/appsettings.Development.json b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/appsettings.Development.json index b49b3ff7f..7901df684 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/appsettings.Development.json +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/appsettings.Development.json @@ -27,6 +27,7 @@ "CollectorCleaningInterval": 3600000 }, "PostgreSql": { + "Schema": "admin", "TableNamePrefix": "admin", "ConnectionString": "Host=127.0.0.1;Database=abp;Username=postgres;Password=123456" }, diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.ApiGateway/yarp.json b/aspnet-core/aspire/LINGYUN.Abp.MicroService.ApiGateway/yarp.json index 0b523b419..4d6c69e54 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.ApiGateway/yarp.json +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.ApiGateway/yarp.json @@ -143,6 +143,21 @@ } ] }, + "gdpr-route": { + "ClusterId": "identity-service-cluster", + "Match": { + "Path": "/api/gdpr/{**everything}" + }, + "Transforms": [ + { + "HeaderPrefix": "X-Forwarded-", + "X-Forwarded": "Append" + }, + { + "ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat" + } + ] + }, "identity-server-route": { "ClusterId": "identity-service-cluster", "Match": { @@ -293,6 +308,21 @@ } ] }, + "setting-management-v2-route": { + "ClusterId": "admin-service-cluster", + "Match": { + "Path": "/api/v2/setting-management/{**everything}" + }, + "Transforms": [ + { + "HeaderPrefix": "X-Forwarded-", + "X-Forwarded": "Append" + }, + { + "ResponseHeadersAllowed": "_AbpWrapResult;_AbpDontWrapResult;_AbpErrorFormat" + } + ] + }, "localization-management-route": { "ClusterId": "localization-service-cluster", "Match": { diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AppHost/AppHost.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AppHost/AppHost.cs index cf5b01b09..203b63814 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AppHost/AppHost.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AppHost/AppHost.cs @@ -5,7 +5,8 @@ var builder = DistributedApplication.CreateBuilder(args); // Redis var redis = builder.AddRedis("redis", password: builder.AddParameter("redis-password", "123456", secret: true)) - .WithContainerName("redis") + .WithContainerName("redis-aspire") + .WithImageTag("8.0.2") .WithDataVolume("redis-dev"); if (builder.Environment.IsDevelopment()) @@ -16,8 +17,9 @@ if (builder.Environment.IsDevelopment()) } // Elasticsearch -var elasticsearch = builder.AddElasticsearch("elasticsearch") - .WithContainerName("elasticsearch") +var elasticsearch = builder.AddElasticsearch("elasticsearch", + password: builder.AddParameter("elasticsearch-password", "123456", secret: true)) + .WithContainerName("elasticsearch-aspire") .WithImageTag("8.17.3") .WithDataVolume("elasticsearch-dev") .WithEnvironment("ES_JAVA_OPTS", "-Xms2g -Xmx2g") @@ -26,15 +28,17 @@ var elasticsearch = builder.AddElasticsearch("elasticsearch") // Kibana builder.AddContainer("kibana", "kibana", "8.17.3") + .WithContainerName("kibana-aspire") .WithReference(elasticsearch) .WithEndpoint(5601, 5601) .WaitFor(elasticsearch); // Postgres -var postgres = builder.AddPostgres("postgres") - .WithPassword(builder.AddParameter("postgres-pwd", "123456", secret: true)) +var postgres = builder.AddPostgres("postgres", + userName: builder.AddParameter("postgres-username", "postgres", secret: true), + password: builder.AddParameter("postgres-pwd", "123456", secret: true)) .WithImage("postgres", "17-alpine") - .WithContainerName("postgres") + .WithContainerName("postgres-aspire") .WithDataVolume("postgres-dev"); var abpDb = postgres.AddDatabase("abp"); @@ -43,7 +47,8 @@ var abpDb = postgres.AddDatabase("abp"); var rabbitmq = builder.AddRabbitMQ("rabbitmq", userName: builder.AddParameter("rabbitmq-username", "admin", secret: true), password: builder.AddParameter("rabbitmq-password", "123456", secret: true)) - .WithContainerName("rabbitmq") + .WithContainerName("rabbitmq-aspire") + .WithImageTag("3.13.1") .WithDataVolume("rabbitmq-dev") .WithManagementPlugin(); diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerMigrationsDbContext.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerMigrationsDbContext.cs index f38674d4a..72956c22a 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerMigrationsDbContext.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/AuthServerMigrationsDbContext.cs @@ -1,5 +1,6 @@ using LINGYUN.Abp.Gdpr; using LINGYUN.Abp.Gdpr.EntityFrameworkCore; +using LINGYUN.Abp.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; @@ -59,5 +60,7 @@ public class AuthServerMigrationsDbContext : modelBuilder.ConfigureIdentity(); modelBuilder.ConfigureOpenIddict(); modelBuilder.ConfigureGdpr(); + + modelBuilder.ConfigureIdentityUserInactive(); } } diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/OpenIddictDataSeeder.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/OpenIddictDataSeeder.cs index f19bb7e10..29398ecb0 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/OpenIddictDataSeeder.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/DataSeeds/OpenIddictDataSeeder.cs @@ -478,7 +478,9 @@ public class OpenIddictDataSeeder : OpenIddictDataSeedContributorBase, ITransien [OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit, OpenIddictConstants.GrantTypes.Password, - OpenIddictConstants.GrantTypes.RefreshToken], + OpenIddictConstants.GrantTypes.RefreshToken, + // TODO: 引用项目? + "link_user"], [OpenIddictConstants.Scopes.OpenId, OpenIddictConstants.Scopes.Email, OpenIddictConstants.Scopes.Roles, @@ -540,7 +542,9 @@ public class OpenIddictDataSeeder : OpenIddictDataSeedContributorBase, ITransien "Abp OAuth Client", null, [OpenIddictConstants.GrantTypes.AuthorizationCode, - OpenIddictConstants.GrantTypes.RefreshToken], + OpenIddictConstants.GrantTypes.RefreshToken, + // TODO: 引用项目? + "link_user"], [OpenIddictConstants.Scopes.OpenId, OpenIddictConstants.Scopes.Email, OpenIddictConstants.Scopes.Roles, diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/Migrations/20260530060327_Add-Identity-User-Inactive.Designer.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/Migrations/20260530060327_Add-Identity-User-Inactive.Designer.cs new file mode 100644 index 000000000..f1c69acc5 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer.EntityFrameworkCore/Migrations/20260530060327_Add-Identity-User-Inactive.Designer.cs @@ -0,0 +1,1403 @@ +// +using System; +using LINGYUN.Abp.MicroService.AuthServer; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace LINGYUN.Abp.MicroService.AuthServer.Migrations +{ + [DbContext(typeof(AuthServerMigrationsDbContext))] + [Migration("20260530060327_Add-Identity-User-Inactive")] + partial class AddIdentityUserInactive + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.PostgreSql) + .HasAnnotation("ProductVersion", "10.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("LINGYUN.Abp.Gdpr.GdprInfo", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Data") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Data"); + + b.Property("Provider") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("Provider"); + + b.Property("RequestId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RequestId"); + + b.ToTable("AbpGdprInfos", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Gdpr.GdprRequest", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("ReadyTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpGdprRequests", (string)null); + }); + + modelBuilder.Entity("LINGYUN.Abp.Identity.IdentityUserInactive", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uuid") + .HasColumnName("CreatorId"); + + b.Property("DeactivatedTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastNotificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastSignInTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpUserInactives", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Required") + .HasColumnType("boolean"); + + b.Property("ValueType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("SourceTenantId") + .HasColumnType("uuid"); + + b.Property("SourceUserId") + .HasColumnType("uuid"); + + b.Property("TargetTenantId") + .HasColumnType("uuid"); + + b.Property("TargetUserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique(); + + b.ToTable("AbpLinkUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("EntityVersion") + .HasColumnType("integer"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("boolean") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("boolean") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("boolean") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("character varying(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("character varying(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("character varying(96)"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExtraProperties") + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("IpAddresses") + .HasMaxLength(2048) + .HasColumnType("character varying(2048)"); + + b.Property("LastAccessed") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("SignedIn") + .HasColumnType("timestamp with time zone"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uuid") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uuid") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("EntityVersion") + .HasColumnType("integer"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("IsActive") + .HasColumnType("boolean") + .HasColumnName("IsActive"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uuid") + .HasColumnName("LastModifierId"); + + b.Property("LastPasswordChangeTime") + .HasColumnType("timestamp with time zone"); + + b.Property("LastSignInTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Leaved") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("Leaved"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("character varying(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("SecurityStamp"); + + b.Property("ShouldChangePasswordOnNextLogin") + .HasColumnType("boolean"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SourceUserId") + .HasColumnType("uuid"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("TargetUserId") + .HasColumnType("uuid"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("AbpUserDelegations", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("character varying(196)"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uuid") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasskey", b => + { + b.Property("CredentialId") + .HasMaxLength(1024) + .HasColumnType("bytea"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("CredentialId"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserPasskeys", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserPasswordHistory", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Password") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "Password"); + + b.ToTable("AbpUserPasswordHistories", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("character varying(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uuid") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uuid") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("EntityVersion") + .HasColumnType("integer"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uuid") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uuid"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uuid"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uuid") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uuid") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Applications.OpenIddictApplication", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ClientSecret") + .HasColumnType("text"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ClientUri") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uuid") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uuid") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("DisplayNames") + .HasColumnType("text"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("text"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("JsonWebKeySet") + .HasColumnType("text"); + + b.Property("LastModificationTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uuid") + .HasColumnName("LastModifierId"); + + b.Property("LogoUri") + .HasColumnType("text"); + + b.Property("Permissions") + .HasColumnType("text"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("RedirectUris") + .HasColumnType("text"); + + b.Property("Requirements") + .HasColumnType("text"); + + b.Property("Settings") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.OpenIddict.Authorizations.OpenIddictAuthorization", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("ApplicationId") + .HasColumnType("uuid"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b.Property