diff --git a/apps/vben5/apps/app-antd/package.json b/apps/vben5/apps/app-antd/package.json index b4fc532a3..efbe91733 100644 --- a/apps/vben5/apps/app-antd/package.json +++ b/apps/vben5/apps/app-antd/package.json @@ -46,6 +46,7 @@ "@abp/text-templating": "workspace:*", "@abp/ui": "workspace:*", "@abp/webhooks": "workspace:*", + "@abp/wechat": "workspace:*", "@vben-core/shadcn-ui": "workspace:*", "@vben/access": "workspace:*", "@vben/common-ui": "workspace:*", diff --git a/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json b/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json index 277f4585d..49dced4c6 100644 --- a/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json +++ b/apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json @@ -142,5 +142,9 @@ "title": "Object storage", "containers": "Containers", "objects": "Files" + }, + "wechat": { + "title": "WeChat", + "settings": "Settings" } } diff --git a/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json b/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json index 0665783bc..16bb7ec01 100644 --- a/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json +++ b/apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json @@ -142,5 +142,9 @@ "title": "对象存储", "containers": "容器管理", "objects": "文件管理" + }, + "wechat": { + "title": "微信集成", + "settings": "微信设置" } } diff --git a/apps/vben5/apps/app-antd/src/views/account/my-settings/index.vue b/apps/vben5/apps/app-antd/src/views/account/my-settings/index.vue index 29ccab460..5dda522cc 100644 --- a/apps/vben5/apps/app-antd/src/views/account/my-settings/index.vue +++ b/apps/vben5/apps/app-antd/src/views/account/my-settings/index.vue @@ -1,15 +1,98 @@ diff --git a/apps/vben5/packages/@abp/account/src/api/index.ts b/apps/vben5/packages/@abp/account/src/api/index.ts index 9f94ff5ed..3810e2eb2 100644 --- a/apps/vben5/packages/@abp/account/src/api/index.ts +++ b/apps/vben5/packages/@abp/account/src/api/index.ts @@ -1,4 +1,5 @@ export { useAccountApi } from './useAccountApi'; +export { useExternalLoginsApi } from './useExternalLoginsApi'; export { useMySessionApi } from './useMySessionApi'; export { useProfileApi } from './useProfileApi'; export { useScanQrCodeApi } from './useScanQrCodeApi'; diff --git a/apps/vben5/packages/@abp/account/src/api/useExternalLoginsApi.ts b/apps/vben5/packages/@abp/account/src/api/useExternalLoginsApi.ts new file mode 100644 index 000000000..ff2b0122f --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/api/useExternalLoginsApi.ts @@ -0,0 +1,58 @@ +import type { + ExternalLoginResultDto, + RemoveExternalLoginInput, + WorkWeixinLoginBindInput, +} from '../types/external-logins'; + +import { useRequest } from '@abp/request'; + +export function useExternalLoginsApi() { + const { cancel, request } = useRequest(); + + /** + * 绑定企业微信 + * @param input 绑定参数 + * @returns { Promise } + */ + async function bindWorkWeixinApi( + input: WorkWeixinLoginBindInput, + ): Promise { + return await request(`/api/account/oauth/work-weixin/bind`, { + method: 'POST', + data: input, + }); + } + + /** + * 获取外部登录提供者列表 + * @returns 外部登录提供者列表 + */ + async function getExternalLoginsApi(): Promise { + return await request( + `/api/account/external-logins`, + { + method: 'GET', + }, + ); + } + + /** + * 移除外部登录提供者 + * @returns { Promise } + */ + async function removeExternalLoginApi( + input: RemoveExternalLoginInput, + ): Promise { + return await request(`/api/account/external-logins/remove`, { + method: 'DELETE', + params: input, + }); + } + + return { + cancel, + bindWorkWeixinApi, + getExternalLoginsApi, + removeExternalLoginApi, + }; +} diff --git a/apps/vben5/packages/@abp/account/src/components/MySetting.vue b/apps/vben5/packages/@abp/account/src/components/MySetting.vue index 9266f6f8c..848cf6630 100644 --- a/apps/vben5/packages/@abp/account/src/components/MySetting.vue +++ b/apps/vben5/packages/@abp/account/src/components/MySetting.vue @@ -1,4 +1,5 @@ diff --git a/apps/vben5/packages/@abp/account/src/components/components/SecuritySettings.vue b/apps/vben5/packages/@abp/account/src/components/components/SecuritySettings.vue index 65ac3940b..ce65c2368 100644 --- a/apps/vben5/packages/@abp/account/src/components/components/SecuritySettings.vue +++ b/apps/vben5/packages/@abp/account/src/components/components/SecuritySettings.vue @@ -86,13 +86,8 @@ onMounted(onGet); - - + :title="$t('abp.account.settings.security.password')" + /> diff --git a/apps/vben5/packages/@abp/account/src/types/bind.ts b/apps/vben5/packages/@abp/account/src/types/bind.ts new file mode 100644 index 000000000..b85215d3d --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/types/bind.ts @@ -0,0 +1,17 @@ +import type { ButtonType } from 'ant-design-vue/lib/button'; + +interface BindButton { + click: () => Promise | void; + title: string; + type?: ButtonType; +} + +interface BindItem { + buttons?: BindButton[]; + description?: string; + enable?: boolean; + slot?: string; + title: string; +} + +export type { BindItem }; diff --git a/apps/vben5/packages/@abp/account/src/types/external-logins.ts b/apps/vben5/packages/@abp/account/src/types/external-logins.ts new file mode 100644 index 000000000..2d8ce8587 --- /dev/null +++ b/apps/vben5/packages/@abp/account/src/types/external-logins.ts @@ -0,0 +1,32 @@ +interface UserLoginInfoDto { + loginProvider: string; + providerDisplayName: string; + providerKey: string; +} + +interface ExternalLoginInfoDto { + displayName: string; + name: string; +} + +interface WorkWeixinLoginBindInput { + code: string; +} + +interface ExternalLoginResultDto { + externalLogins: ExternalLoginInfoDto[]; + userLogins: UserLoginInfoDto[]; +} + +interface RemoveExternalLoginInput { + loginProvider: string; + providerKey: string; +} + +export type { + ExternalLoginInfoDto, + ExternalLoginResultDto, + RemoveExternalLoginInput, + UserLoginInfoDto, + WorkWeixinLoginBindInput, +}; diff --git a/apps/vben5/packages/@abp/account/src/types/index.ts b/apps/vben5/packages/@abp/account/src/types/index.ts index 1dd5f3324..0f182a66b 100644 --- a/apps/vben5/packages/@abp/account/src/types/index.ts +++ b/apps/vben5/packages/@abp/account/src/types/index.ts @@ -1,4 +1,6 @@ export * from './account'; +export * from './bind'; +export * from './external-logins'; export * from './profile'; export * from './token'; export * from './user'; diff --git a/apps/vben5/packages/@abp/core/src/utils/index.ts b/apps/vben5/packages/@abp/core/src/utils/index.ts index 4c7bf48a5..3c3ccf781 100644 --- a/apps/vben5/packages/@abp/core/src/utils/index.ts +++ b/apps/vben5/packages/@abp/core/src/utils/index.ts @@ -5,3 +5,4 @@ export * from './mitt'; export * from './regex'; export * from './string'; export * from './tree'; +export * from './uuid'; diff --git a/apps/vben5/packages/@abp/core/src/utils/uuid.ts b/apps/vben5/packages/@abp/core/src/utils/uuid.ts new file mode 100644 index 000000000..81c49a09d --- /dev/null +++ b/apps/vben5/packages/@abp/core/src/utils/uuid.ts @@ -0,0 +1,42 @@ +const hexList: string[] = []; +for (let i = 0; i <= 15; i++) { + hexList[i] = i.toString(16); +} + +export function buildUUID(): string { + let uuid = ''; + for (let i = 1; i <= 36; i++) { + switch (i) { + case 9: + case 14: + case 19: + case 24: { + uuid += '-'; + + break; + } + case 15: { + uuid += 4; + + break; + } + case 20: { + uuid += hexList[(Math.random() * 4) | 8]; + + break; + } + default: { + uuid += hexList[Math.trunc(Math.random() * 16)]; + } + } + } + return uuid.replaceAll('-', ''); +} + +let unique = 0; +export function buildShortUUID(prefix = ''): string { + const time = Date.now(); + const random = Math.floor(Math.random() * 1_000_000_000); + unique++; + return `${prefix}_${random}${unique}${String(time)}`; +} diff --git a/apps/vben5/packages/@abp/settings/src/components/index.ts b/apps/vben5/packages/@abp/settings/src/components/index.ts index aaa211b75..53dbe96f7 100644 --- a/apps/vben5/packages/@abp/settings/src/components/index.ts +++ b/apps/vben5/packages/@abp/settings/src/components/index.ts @@ -1,3 +1,4 @@ export { default as SettingDefinitionTable } from './definitions/SettingDefinitionTable.vue'; +export { default as SettingForm } from './settings/SettingForm.vue'; export { default as SystemSetting } from './settings/SystemSetting.vue'; export { default as UserSetting } from './settings/UserSetting.vue'; diff --git a/apps/vben5/packages/@abp/wechat/package.json b/apps/vben5/packages/@abp/wechat/package.json new file mode 100644 index 000000000..28d20c24a --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/package.json @@ -0,0 +1,40 @@ +{ + "name": "@abp/wechat", + "version": "9.2.0", + "homepage": "https://github.com/colinin/abp-next-admin", + "bugs": "https://github.com/colinin/abp-next-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/colinin/abp-next-admin.git", + "directory": "packages/@abp/wechat" + }, + "license": "MIT", + "type": "module", + "sideEffects": [ + "**/*.css" + ], + "exports": { + ".": { + "types": "./src/index.ts", + "default": "./src/index.ts" + } + }, + "dependencies": { + "@abp/core": "workspace:*", + "@abp/features": "workspace:*", + "@abp/request": "workspace:*", + "@abp/settings": "workspace:*", + "@abp/ui": "workspace:*", + "@ant-design/icons-vue": "catalog:", + "@vben/access": "workspace:*", + "@vben/common-ui": "workspace:*", + "@vben/hooks": "workspace:*", + "@vben/icons": "workspace:*", + "@vben/layouts": "workspace:*", + "@vben/locales": "workspace:*", + "@wecom/jssdk": "catalog:", + "ant-design-vue": "catalog:", + "dayjs": "catalog:", + "vue": "catalog:*" + } +} diff --git a/apps/vben5/packages/@abp/wechat/src/api/index.ts b/apps/vben5/packages/@abp/wechat/src/api/index.ts new file mode 100644 index 000000000..745447658 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/api/index.ts @@ -0,0 +1,2 @@ +export { userWorkWeixinJsSdkApi } from './userWorkWeixinJsSdkApi'; +export { useWechatSettingsApi } from './useWechatSettingsApi'; diff --git a/apps/vben5/packages/@abp/wechat/src/api/useWechatSettingsApi.ts b/apps/vben5/packages/@abp/wechat/src/api/useWechatSettingsApi.ts new file mode 100644 index 000000000..9f9aa2a19 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/api/useWechatSettingsApi.ts @@ -0,0 +1,40 @@ +import type { ListResultDto } from '@abp/core'; +import type { SettingGroup } from '@abp/settings'; + +import { useRequest } from '@abp/request'; + +export function useWechatSettingsApi() { + const { cancel, request } = useRequest(); + + /** + * 获取全局设置 + * @returns 设置数据传输对象列表 + */ + function getGlobalSettingsApi(): Promise> { + return request>( + `/api/wechat/setting-management/by-global`, + { + method: 'GET', + }, + ); + } + + /** + * 获取租户设置 + * @returns 设置数据传输对象列表 + */ + function getTenantSettingsApi(): Promise> { + return request>( + `/api/wechat/setting-management/by-current-tenant`, + { + method: 'GET', + }, + ); + } + + return { + cancel, + getGlobalSettingsApi, + getTenantSettingsApi, + }; +} diff --git a/apps/vben5/packages/@abp/wechat/src/api/userWorkWeixinJsSdkApi.ts b/apps/vben5/packages/@abp/wechat/src/api/userWorkWeixinJsSdkApi.ts new file mode 100644 index 000000000..804fa7105 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/api/userWorkWeixinJsSdkApi.ts @@ -0,0 +1,22 @@ +import type { AgentConfigDto } from '../types/js-sdk'; + +import { useRequest } from '@abp/request'; + +export function userWorkWeixinJsSdkApi() { + const { cancel, request } = useRequest(); + + /** + * 获取企业微信应用配置 + * @returns 企业微信应用配置Dto + */ + function getAgentConfigApi(): Promise { + return request(`/api/wechat/work/jssdk/agent-config`, { + method: 'GET', + }); + } + + return { + cancel, + getAgentConfigApi, + }; +} 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 new file mode 100644 index 000000000..e752a0700 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/components/bind-user/index.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/apps/vben5/packages/@abp/wechat/src/components/index.ts b/apps/vben5/packages/@abp/wechat/src/components/index.ts new file mode 100644 index 000000000..8e84134b5 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/components/index.ts @@ -0,0 +1,2 @@ +export { default as WechatWorkUserBinder } from './bind-user/index.vue'; +export { default as WechatSettings } from './settings/index.vue'; diff --git a/apps/vben5/packages/@abp/wechat/src/components/settings/index.vue b/apps/vben5/packages/@abp/wechat/src/components/settings/index.vue new file mode 100644 index 000000000..e1f3e30a6 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/components/settings/index.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/apps/vben5/packages/@abp/wechat/src/index.ts b/apps/vben5/packages/@abp/wechat/src/index.ts new file mode 100644 index 000000000..0ef464305 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/index.ts @@ -0,0 +1,2 @@ +export * from './api'; +export * from './components'; diff --git a/apps/vben5/packages/@abp/wechat/src/types/js-sdk.ts b/apps/vben5/packages/@abp/wechat/src/types/js-sdk.ts new file mode 100644 index 000000000..44031b6b5 --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/src/types/js-sdk.ts @@ -0,0 +1,6 @@ +interface AgentConfigDto { + agentId: string; + corpId: string; +} + +export type { AgentConfigDto }; diff --git a/apps/vben5/packages/@abp/wechat/tsconfig.json b/apps/vben5/packages/@abp/wechat/tsconfig.json new file mode 100644 index 000000000..ce1a891fb --- /dev/null +++ b/apps/vben5/packages/@abp/wechat/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/web.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/apps/vben5/pnpm-workspace.yaml b/apps/vben5/pnpm-workspace.yaml index b599ab73f..517e67b0e 100644 --- a/apps/vben5/pnpm-workspace.yaml +++ b/apps/vben5/pnpm-workspace.yaml @@ -73,6 +73,7 @@ catalog: '@vueuse/core': ^13.1.0 '@vueuse/integrations': ^13.1.0 '@vueuse/motion': ^3.0.3 + '@wecom/jssdk': ^2.3.1 ant-design-vue: ^4.2.6 archiver: ^7.0.1 autoprefixer: ^10.4.21