diff --git a/ui/package.json b/ui/package.json index e8f21d5c7..e6067f69c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -18,6 +18,7 @@ "@logicflow/core": "^1.2.27", "@logicflow/extension": "^1.2.27", "@vueuse/core": "^10.9.0", + "@wecom/jssdk": "^2.1.0", "axios": "^0.28.0", "codemirror": "^6.0.1", "cropperjs": "^1.6.2", diff --git a/ui/src/api/platform-source.ts b/ui/src/api/platform-source.ts new file mode 100644 index 000000000..defcc840f --- /dev/null +++ b/ui/src/api/platform-source.ts @@ -0,0 +1,28 @@ +import { Result } from '@/request/Result' +import { get, post, del, put } from '@/request/index' +import type { pageRequest } from '@/api/type/common' +import { type Ref } from 'vue' + +const prefix = '/platform' +const getPlatformInfo: (loading?: Ref) => Promise> = (loading) => { + return get(`${prefix}/source`, undefined, loading) +} + +const updateConfig: (data: any, loading?: Ref) => Promise> = ( + data, + loading +) => { + return post(`${prefix}/source`, data, undefined, loading) +} + +const validateConnection: (data: any, loading?: Ref) => Promise> = ( + data, + loading +) => { + return put(`${prefix}/source`, data, undefined, loading) +} +export default { + getPlatformInfo, + updateConfig, + validateConnection +} diff --git a/ui/src/api/user.ts b/ui/src/api/user.ts index 558c781a8..b0aca1e4a 100644 --- a/ui/src/api/user.ts +++ b/ui/src/api/user.ts @@ -1,14 +1,14 @@ -import {Result} from '@/request/Result' -import {get, post} from '@/request/index' +import { Result } from '@/request/Result' +import { get, post } from '@/request/index' import type { - LoginRequest, - RegisterRequest, - CheckCodeRequest, - ResetPasswordRequest, - User, - ResetCurrentUserPasswordRequest + LoginRequest, + RegisterRequest, + CheckCodeRequest, + ResetPasswordRequest, + User, + ResetCurrentUserPasswordRequest } from '@/api/type/user' -import type {Ref} from 'vue' +import type { Ref } from 'vue' /** * 登录 @@ -17,15 +17,15 @@ import type {Ref} from 'vue' * @param loading 接口加载器 * @returns 认证数据 */ -const login: (auth_type: string, request: LoginRequest, loading?: Ref) => Promise> = ( - auth_type, - request, - loading -) => { - if (auth_type !== '') { - return post(`/${auth_type}/login`, request, undefined, loading) - } - return post('/user/login', request, undefined, loading) +const login: ( + auth_type: string, + request: LoginRequest, + loading?: Ref +) => Promise> = (auth_type, request, loading) => { + if (auth_type !== '') { + return post(`/${auth_type}/login`, request, undefined, loading) + } + return post('/user/login', request, undefined, loading) } /** * 登出 @@ -33,7 +33,7 @@ const login: (auth_type: string, request: LoginRequest, loading?: Ref) * @returns */ const logout: (loading?: Ref) => Promise> = (loading) => { - return post('/user/logout', undefined, undefined, loading) + return post('/user/logout', undefined, undefined, loading) } /** @@ -43,10 +43,10 @@ const logout: (loading?: Ref) => Promise> = (loading) = * @returns */ const register: (request: RegisterRequest, loading?: Ref) => Promise> = ( - request, - loading + request, + loading ) => { - return post('/user/register', request, undefined, loading) + return post('/user/register', request, undefined, loading) } /** @@ -56,10 +56,10 @@ const register: (request: RegisterRequest, loading?: Ref) => Promise) => Promise> = ( - request, - loading + request, + loading ) => { - return post('/user/check_code', request, undefined, loading) + return post('/user/check_code', request, undefined, loading) } /** @@ -69,11 +69,11 @@ const checkCode: (request: CheckCodeRequest, loading?: Ref) => Promise< * @returns */ const sendEmit: ( - email: string, - type: 'register' | 'reset_password', - loading?: Ref + email: string, + type: 'register' | 'reset_password', + loading?: Ref ) => Promise> = (email, type, loading) => { - return post('/user/send_email', {email, type}, undefined, loading) + return post('/user/send_email', { email, type }, undefined, loading) } /** * 发送邮件到当前用户 @@ -81,7 +81,7 @@ const sendEmit: ( * @returns */ const sendEmailToCurrent: (loading?: Ref) => Promise> = (loading) => { - return post('/user/current/send_email', undefined, undefined, loading) + return post('/user/current/send_email', undefined, undefined, loading) } /** * 修改当前用户密码 @@ -90,10 +90,10 @@ const sendEmailToCurrent: (loading?: Ref) => Promise> = * @returns */ const resetCurrentUserPassword: ( - request: ResetCurrentUserPasswordRequest, - loading?: Ref + request: ResetCurrentUserPasswordRequest, + loading?: Ref ) => Promise> = (request, loading) => { - return post('/user/current/reset_password', request, undefined, loading) + return post('/user/current/reset_password', request, undefined, loading) } /** * 获取用户基本信息 @@ -101,7 +101,7 @@ const resetCurrentUserPassword: ( * @returns 用户基本信息 */ const profile: (loading?: Ref) => Promise> = (loading) => { - return get('/user', undefined, loading) + return get('/user', undefined, loading) } /** @@ -111,10 +111,10 @@ const profile: (loading?: Ref) => Promise> = (loading) => * @returns */ const resetPassword: ( - request: ResetPasswordRequest, - loading?: Ref + request: ResetPasswordRequest, + loading?: Ref ) => Promise> = (request, loading) => { - return post('/user/re_password', request, undefined, loading) + return post('/user/re_password', request, undefined, loading) } /** @@ -123,17 +123,17 @@ const resetPassword: ( * email_or_username */ const getUserList: (email_or_username: string, loading?: Ref) => Promise> = ( - email_or_username, - loading + email_or_username, + loading ) => { - return get('/user/list', {email_or_username}, loading) + return get('/user/list', { email_or_username }, loading) } /** * 获取profile */ const getProfile: (loading?: Ref) => Promise> = (loading) => { - return get('/profile', undefined, loading) + return get('/profile', undefined, loading) } /** @@ -142,31 +142,55 @@ const getProfile: (loading?: Ref) => Promise> = (loading) = * @param valid_count 校验数量: 5 | 50 | 2 */ const getValid: ( - valid_type: string, - valid_count: number, - loading?: Ref + valid_type: string, + valid_count: number, + loading?: Ref ) => Promise> = (valid_type, valid_count, loading) => { - return get(`/valid/${valid_type}/${valid_count}`, undefined, loading) + return get(`/valid/${valid_type}/${valid_count}`, undefined, loading) } /** * 获取登录方式 */ const getAuthType: (loading?: Ref) => Promise> = (loading) => { - return get('auth/types', undefined, loading) + return get('auth/types', undefined, loading) +} + +/** + * 获取二维码类型 + */ +const getQrType: (loading?: Ref) => Promise> = (loading) => { + return get('qr_type', undefined, loading) +} + +const getDingCallback: (code: string, loading?: Ref) => Promise> = ( + code, + loading +) => { + return get('dingtalk', { code }, loading) +} + +const getWecomCallback: (code: string, loading?: Ref) => Promise> = ( + code, + loading +) => { + return get('wecom', { code }, loading) } export default { - login, - register, - sendEmit, - checkCode, - profile, - resetPassword, - sendEmailToCurrent, - resetCurrentUserPassword, - logout, - getUserList, - getProfile, - getValid, - getAuthType + login, + register, + sendEmit, + checkCode, + profile, + resetPassword, + sendEmailToCurrent, + resetCurrentUserPassword, + logout, + getUserList, + getProfile, + getValid, + getAuthType, + getDingCallback, + getQrType, + getWecomCallback } diff --git a/ui/src/assets/icon_qr_outlined.svg b/ui/src/assets/icon_qr_outlined.svg new file mode 100644 index 000000000..1d3cf4343 --- /dev/null +++ b/ui/src/assets/icon_qr_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/src/components/icons/index.ts b/ui/src/components/icons/index.ts index d241b2113..590806840 100644 --- a/ui/src/components/icons/index.ts +++ b/ui/src/components/icons/index.ts @@ -1206,5 +1206,26 @@ export const iconMap: any = { ) ]) } + }, + 'app-invisible': { + iconReader: () => { + return h('i', [ + h( + 'svg', + { + style: { height: '100%', width: '100%' }, + viewBox: '0 0 1024 1024', + version: '1.1', + xmlns: 'http://www.w3.org/2000/svg' + }, + [ + h('path', { + d: 'M512 640c-28.032 0-55.466667-2.218667-82.090667-6.4l-21.248 79.274667a21.333333 21.333333 0 0 1-26.154666 15.061333L341.333333 716.885333a21.333333 21.333333 0 0 1-15.061333-26.112l20.821333-77.653333a473.770667 473.770667 0 0 1-97.152-45.653333l-67.84 67.84a21.333333 21.333333 0 0 1-30.122666 0l-30.165334-30.208a21.333333 21.333333 0 0 1 0-30.165334l59.733334-59.733333A386.389333 386.389333 0 0 1 104.789333 416.426667a37.76 37.76 0 0 1 7.594667-45.397334c10.496-9.514667 17.877333-16 24.32-22.442666a170.24 170.24 0 0 0 1.834667-1.92c9.301333-9.6 25.173333-6.016 30.634666 6.186666C222.336 471.936 349.568 554.666667 512 554.666667c155.648 0 285.866667-80.512 338.090667-190.976 1.365333-2.858667 2.901333-6.485333 4.437333-10.325334a18.346667 18.346667 0 0 1 29.866667-6.613333l27.392 27.434667a36.565333 36.565333 0 0 1 6.997333 42.666666c-1.792 3.456-3.541333 6.698667-5.034667 9.301334a390.4 390.4 0 0 1-76.928 94.293333l54.442667 54.485333a21.333333 21.333333 0 0 1 0 30.165334l-30.165333 30.165333a21.333333 21.333333 0 0 1-30.165334 0l-63.658666-63.658667a475.306667 475.306667 0 0 1-90.282667 41.514667l20.778667 77.653333a21.333333 21.333333 0 0 1-15.061334 26.112l-41.216 11.093334a21.333333 21.333333 0 0 1-26.154666-15.104l-21.248-79.317334c-26.581333 4.266667-54.058667 6.442667-82.090667 6.442667z', + fill: 'currentColor' + }) + ] + ) + ]) + } } } diff --git a/ui/src/stores/modules/user.ts b/ui/src/stores/modules/user.ts index aac61f8f2..af4f5589c 100644 --- a/ui/src/stores/modules/user.ts +++ b/ui/src/stores/modules/user.ts @@ -129,6 +129,20 @@ const useUserStore = defineStore({ return this.profile() }) }, + async dingCallback(code: string) { + return UserApi.getDingCallback(code).then((ok) => { + this.token = ok.data + localStorage.setItem('token', ok.data) + return this.profile() + }) + }, + async wecomCallback(code: string) { + return UserApi.getWecomCallback(code).then((ok) => { + this.token = ok.data + localStorage.setItem('token', ok.data) + return this.profile() + }) + }, async logout() { return UserApi.logout().then(() => { @@ -140,6 +154,11 @@ const useUserStore = defineStore({ return UserApi.getAuthType().then((ok) => { return ok.data }) + }, + async getQrType() { + return UserApi.getQrType().then((ok) => { + return ok.data + }) } } }) diff --git a/ui/src/styles/element-plus.scss b/ui/src/styles/element-plus.scss index c41ae212b..4e80e7f9f 100644 --- a/ui/src/styles/element-plus.scss +++ b/ui/src/styles/element-plus.scss @@ -274,6 +274,12 @@ padding: 0 14px; } +.el-tabs__nav-wrap:after { + height: 1px; +} +.el-tabs__active-bar { + height: 3px; +} .el-drawer { .el-drawer__header { padding: 16px 24px; diff --git a/ui/src/views/application-workflow/index.vue b/ui/src/views/application-workflow/index.vue index daa522760..836508359 100644 --- a/ui/src/views/application-workflow/index.vue +++ b/ui/src/views/application-workflow/index.vue @@ -285,9 +285,6 @@ onBeforeUnmount(() => { .el-tabs__nav-wrap { padding: 0 16px; } - .el-tabs__nav-wrap:after { - height: 1px; - } } } diff --git a/ui/src/views/authentication/component/CAS.vue b/ui/src/views/authentication/component/CAS.vue index dc74065b3..4f790db66 100644 --- a/ui/src/views/authentication/component/CAS.vue +++ b/ui/src/views/authentication/component/CAS.vue @@ -1,36 +1,40 @@ + + diff --git a/ui/src/views/authentication/component/LDAP.vue b/ui/src/views/authentication/component/LDAP.vue index f4d444495..f4c26926b 100644 --- a/ui/src/views/authentication/component/LDAP.vue +++ b/ui/src/views/authentication/component/LDAP.vue @@ -1,61 +1,65 @@ + + diff --git a/ui/src/views/authentication/index.vue b/ui/src/views/authentication/index.vue index 7c89263e0..484f915eb 100644 --- a/ui/src/views/authentication/index.vue +++ b/ui/src/views/authentication/index.vue @@ -4,13 +4,7 @@ @@ -22,6 +16,7 @@ import { useRouter } from 'vue-router' import LDAP from './component/LDAP.vue' import CAS from './component/CAS.vue' import OIDC from './component/OIDC.vue' +import SCAN from './component/SCAN.vue' import { t } from '@/locales' import useStore from '@/stores' @@ -44,6 +39,11 @@ const tabList = [ label: t('login.oidc.title'), name: 'OIDC', component: OIDC + }, + { + label: '扫码登录', + name: 'SCAN', + component: SCAN } ] @@ -62,12 +62,9 @@ onMounted(() => { min-width: 700px; height: calc(100vh - var(--app-header-height) - var(--app-view-padding) * 2 - 70px); box-sizing: border-box; - .form-container { + :deep(.form-container) { width: 70%; margin: 0 auto; - :deep(.el-checkbox__label) { - font-weight: 400; - } } } diff --git a/ui/src/views/login/components/QrCodeTab.vue b/ui/src/views/login/components/QrCodeTab.vue new file mode 100644 index 000000000..896c91944 --- /dev/null +++ b/ui/src/views/login/components/QrCodeTab.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/ui/src/views/login/components/dingtalkQrCode.vue b/ui/src/views/login/components/dingtalkQrCode.vue new file mode 100644 index 000000000..be29e4d80 --- /dev/null +++ b/ui/src/views/login/components/dingtalkQrCode.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/ui/src/views/login/components/larkQrCode.vue b/ui/src/views/login/components/larkQrCode.vue new file mode 100644 index 000000000..72e6d9bb6 --- /dev/null +++ b/ui/src/views/login/components/larkQrCode.vue @@ -0,0 +1,59 @@ + + + + diff --git a/ui/src/views/login/components/wecomQrCode.vue b/ui/src/views/login/components/wecomQrCode.vue new file mode 100644 index 000000000..114efcc8e --- /dev/null +++ b/ui/src/views/login/components/wecomQrCode.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/ui/src/views/login/index.vue b/ui/src/views/login/index.vue index d51931b5a..a90a86c39 100644 --- a/ui/src/views/login/index.vue +++ b/ui/src/views/login/index.vue @@ -1,52 +1,58 @@