mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
feat: Wecom and dingtalk support
This commit is contained in:
committed by
fit2cloud-chenyw
parent
d362df945f
commit
9112d2f6f0
@@ -0,0 +1,37 @@
|
||||
"""060_platform_token_ddl
|
||||
|
||||
Revision ID: b40e41c67db3
|
||||
Revises: db1a95567cbb
|
||||
Create Date: 2026-01-04 15:50:31.550287
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel.sql.sqltypes
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'b40e41c67db3'
|
||||
down_revision = 'db1a95567cbb'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('sys_platform_token',
|
||||
sa.Column('id', sa.BigInteger(), nullable=False),
|
||||
sa.Column('token', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False),
|
||||
sa.Column('create_time', sa.BigInteger(), nullable=False),
|
||||
sa.Column('exp_time', sa.BigInteger(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_sys_platform_token_id'), 'sys_platform_token', ['id'], unique=False)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_sys_platform_token_id'), table_name='sys_platform_token')
|
||||
op.drop_table('sys_platform_token')
|
||||
# ### end Alembic commands ###
|
||||
@@ -36,6 +36,8 @@ wlist = [
|
||||
"/system/authentication/platform/status",
|
||||
"/system/authentication/login/*",
|
||||
"/system/authentication/sso/*",
|
||||
"/system/platform/sso/*",
|
||||
"/system/platform/client/*",
|
||||
"/system/parameter/login"
|
||||
]
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ dependencies = [
|
||||
"pyyaml (>=6.0.2,<7.0.0)",
|
||||
"fastapi-mcp (>=0.3.4,<0.4.0)",
|
||||
"tabulate>=0.9.0",
|
||||
"sqlbot-xpack>=0.0.4.0,<0.0.5.0",
|
||||
"sqlbot-xpack>=0.0.5.0,<0.0.6.0",
|
||||
"fastapi-cache2>=0.2.2",
|
||||
"sqlparse>=0.5.3",
|
||||
"redis>=6.2.0",
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="logo_wechat-work">
|
||||
<g id="Group-12">
|
||||
<g id="Mask group">
|
||||
<mask id="mask0_3392_197358" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="32" y="36" width="8" height="9">
|
||||
<g id="Group">
|
||||
<path id="Vector" d="M32.3412 36.5092C32.1151 36.7344 32.1011 37.0917 32.2974 37.3342C32.3106 37.3507 32.3251 37.3668 32.3412 37.3829C32.368 37.4097 32.3973 37.4328 32.4274 37.4543C32.4876 37.5104 32.5474 37.5681 32.606 37.6267C33.7623 38.7834 34.4891 40.2061 34.7873 41.6977C34.7923 41.7815 34.8014 41.8652 34.8154 41.9485C34.8298 42.0401 34.8492 42.1313 34.8736 42.2212C34.9878 42.6403 35.2093 43.0367 35.5385 43.3659C36.5475 44.3749 38.1835 44.3749 39.1921 43.3659C40.2011 42.3569 40.2011 40.7213 39.1921 39.7123C38.8365 39.3563 38.4026 39.127 37.9463 39.0218C37.8956 39.0103 37.844 38.9999 37.7925 38.9917C37.7409 38.983 37.6889 38.9756 37.6361 38.9698C36.1074 38.6852 34.6458 37.9518 33.4636 36.7691C33.3782 36.6841 33.2953 36.5971 33.2153 36.5088L33.2149 36.5092C33.094 36.3888 32.936 36.3281 32.778 36.3281C32.6196 36.3281 32.4616 36.3888 32.3412 36.5092Z" fill="#FB6500"/>
|
||||
</g>
|
||||
</mask>
|
||||
<g mask="url(#mask0_3392_197358)">
|
||||
<path id="Fill-10" fill-rule="evenodd" clip-rule="evenodd" d="M31.8882 44.3949H40.2217V36.0557H31.8882V44.3949Z" fill="#FB6500"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-15">
|
||||
<g id="Mask group_2">
|
||||
<mask id="mask1_3392_197358" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="39" y="31" width="9" height="9">
|
||||
<g id="Group_2">
|
||||
<path id="Vector_2" d="M42.8446 32.4235C42.4891 32.7799 42.2597 33.2135 42.1545 33.6697C42.143 33.7205 42.1326 33.772 42.1236 33.8236C42.1153 33.8756 42.1079 33.9275 42.1025 33.9799C41.8179 35.5083 41.0845 36.9702 39.9018 38.1529C39.8164 38.2378 39.7294 38.3207 39.6415 38.4008L39.6419 38.4012C39.4006 38.6425 39.4006 39.0336 39.6419 39.2749C39.8672 39.5005 40.224 39.515 40.4669 39.3186C40.483 39.3054 40.4995 39.291 40.5152 39.2749C40.542 39.2481 40.5655 39.2192 40.587 39.1891C40.6431 39.1284 40.7 39.069 40.7594 39.01C41.9157 37.8538 43.3384 37.127 44.83 36.8291C44.9142 36.8242 44.9979 36.8151 45.0813 36.8011C45.1728 36.7866 45.2636 36.7672 45.3535 36.7421C45.7734 36.6278 46.1695 36.4071 46.4986 36.0779C47.5076 35.0689 47.5076 33.4334 46.4986 32.4235C45.9941 31.919 45.3329 31.667 44.6716 31.667C44.0104 31.667 43.3491 31.919 42.8446 32.4235Z" fill="#3880E7"/>
|
||||
</g>
|
||||
</mask>
|
||||
<g mask="url(#mask1_3392_197358)">
|
||||
<path id="Fill-13" fill-rule="evenodd" clip-rule="evenodd" d="M39.189 39.7285H47.5282V31.395H39.189V39.7285Z" fill="#0082EF"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-18">
|
||||
<g id="Mask group_3">
|
||||
<mask id="mask2_3392_197358" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="34" y="24" width="9" height="9">
|
||||
<g id="Group_3">
|
||||
<path id="Vector_3" d="M35.5569 25.1178C34.5487 26.1268 34.5487 27.7628 35.5569 28.7718C35.9125 29.1274 36.346 29.3571 36.8023 29.4619C36.8538 29.4735 36.9054 29.4838 36.957 29.4924C37.0089 29.5011 37.0609 29.5085 37.1129 29.5139C38.6421 29.7989 40.1032 30.532 41.2858 31.7146C41.3712 31.7996 41.4541 31.8875 41.5346 31.9749C41.7763 32.2162 42.1669 32.2162 42.4087 31.9749C42.6343 31.7493 42.6483 31.3925 42.452 31.1499C42.438 31.133 42.4239 31.1165 42.4087 31.1012C42.3819 31.074 42.3522 31.0509 42.3225 31.0303C42.2618 30.9733 42.2024 30.9156 42.1434 30.857C40.9868 29.7008 40.2603 28.278 39.9617 26.786C39.9575 26.7022 39.9481 26.6185 39.9349 26.5356C39.9204 26.444 39.9002 26.3528 39.8763 26.2625C39.7612 25.8434 39.5401 25.4474 39.2113 25.1178C38.7068 24.6133 38.0452 24.3608 37.3839 24.3608C36.7227 24.3608 36.0614 24.6133 35.5569 25.1178Z" fill="#2DBC00"/>
|
||||
</g>
|
||||
</mask>
|
||||
<g mask="url(#mask2_3392_197358)">
|
||||
<path id="Fill-16" fill-rule="evenodd" clip-rule="evenodd" d="M34.5278 32.4281H42.8609V24.0889H34.5278V32.4281Z" fill="#2DBC00"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-21">
|
||||
<g id="Mask group_4">
|
||||
<mask id="mask3_3392_197358" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="27" y="29" width="9" height="8">
|
||||
<g id="Group_4">
|
||||
<path id="Vector_4" d="M34.282 29.1643C34.2655 29.1783 34.249 29.1923 34.2338 29.2084C34.2065 29.2352 34.1834 29.2637 34.162 29.2942C34.1059 29.3545 34.0485 29.4139 33.9895 29.4729C32.8333 30.6295 31.4105 31.3564 29.9185 31.6538C29.8348 31.6587 29.751 31.6682 29.6677 31.6818C29.5761 31.6959 29.485 31.7161 29.395 31.7408C28.9755 31.8551 28.5795 32.0762 28.2499 32.405C27.2409 33.4144 27.2409 35.0504 28.2499 36.0594C29.2593 37.0684 30.8949 37.0684 31.9043 36.0594C32.2595 35.7042 32.4897 35.2702 32.5949 34.814C32.606 34.7624 32.6167 34.7109 32.6246 34.6593C32.6336 34.6073 32.6402 34.5554 32.6464 34.5034C32.9315 32.9746 33.6645 31.5131 34.8472 30.33C34.9325 30.2451 35.0196 30.1626 35.1079 30.0821L35.1074 30.0817C35.3484 29.8404 35.3484 29.4493 35.1074 29.2084C34.9866 29.0876 34.8286 29.0273 34.6702 29.0273C34.5324 29.0273 34.395 29.0731 34.282 29.1643Z" fill="#FFCC00"/>
|
||||
</g>
|
||||
</mask>
|
||||
<g mask="url(#mask3_3392_197358)">
|
||||
<path id="Fill-19" fill-rule="evenodd" clip-rule="evenodd" d="M27.2202 37.0879H35.5595V28.7544H27.2202V37.0879Z" fill="#FFCC00"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-24">
|
||||
<g id="Mask group_5">
|
||||
<mask id="mask4_3392_197358" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="6" width="38" height="36">
|
||||
<g id="Group_5">
|
||||
<path id="Vector_5" d="M18.6615 6.83487C14.0204 7.33936 9.8025 9.32518 6.7846 12.4256C5.59327 13.6495 4.62264 15.017 3.8991 16.49C2.91733 18.4882 2.41943 20.6098 2.41943 22.7952C2.41943 25.6089 3.2758 28.3831 4.89613 30.8185C5.71661 32.0523 7.05809 33.6062 8.29272 34.701V34.7035L7.73501 39.0881C7.71274 39.1479 7.68881 39.2069 7.6752 39.27C7.66241 39.3269 7.6587 39.3863 7.65251 39.4453C7.64921 39.4898 7.63931 39.5336 7.63931 39.5798C7.63931 39.6284 7.64921 39.6746 7.65375 39.7229C7.72718 40.4444 8.32861 41.0099 9.06948 41.0099C9.32771 41.0099 9.56655 40.9361 9.77528 40.8161C9.78188 40.8123 9.7893 40.809 9.79549 40.8053C9.82643 40.7872 9.85737 40.7715 9.88666 40.7509L11.2191 40.0822L15.1903 38.089C16.3317 38.4169 17.4644 38.626 18.6586 38.7572C19.435 38.8426 20.2225 38.8863 21.0009 38.8863C21.7937 38.8863 22.6162 38.8385 23.4441 38.7444C25.0731 38.5592 26.6398 38.1834 28.1269 37.6501C27.9661 37.596 27.8081 37.5267 27.655 37.4393C26.745 36.9191 26.2744 35.9291 26.3676 34.9494C25.305 35.2868 24.1949 35.5289 23.0481 35.6593C22.3518 35.7385 21.6629 35.7785 21.0009 35.7785C20.3495 35.7785 19.6907 35.7422 19.0406 35.6708C18.9053 35.6564 18.77 35.6349 18.6347 35.6168C17.742 35.498 16.8601 35.3157 16.0075 35.0665C15.8342 35.0112 15.6498 34.9828 15.4617 34.9828C15.1672 34.9828 14.8821 35.0607 14.5934 35.2105C14.5558 35.2299 14.5183 35.246 14.4808 35.2678L11.2191 37.1901L11.078 37.2738L11.0743 37.2755C11.0033 37.3167 10.9637 37.3324 10.9274 37.3324C10.8074 37.3324 10.7104 37.2314 10.7104 37.1068L10.8363 36.599C10.8717 36.4645 10.9216 36.276 10.981 36.0462C11.052 35.7769 11.1349 35.46 11.2191 35.1408C11.3119 34.7877 11.4047 34.4317 11.4839 34.1297C11.5169 34.0121 11.5503 33.8711 11.5503 33.7127C11.5503 33.2742 11.3412 32.8604 10.9918 32.6063C10.814 32.4751 10.6366 32.3374 10.4501 32.1856C10.1647 31.9525 9.89119 31.7103 9.62843 31.4612C8.88962 30.7603 8.24116 29.9956 7.69583 29.1759C6.41334 27.2474 5.73476 25.0591 5.73476 22.8472C5.73476 21.1303 6.12747 19.4613 6.90133 17.8851C7.48008 16.7082 8.25849 15.6122 9.21674 14.628C11.6976 12.0787 15.1866 10.4443 19.0406 10.0256C19.7105 9.95302 20.3706 9.91548 21.0009 9.91548C21.6625 9.91548 22.351 9.95549 23.0481 10.0351C26.8841 10.4707 30.3524 12.1137 32.8147 14.6601C33.7684 15.6469 34.5431 16.7454 35.1173 17.9251C35.8788 19.4906 36.2649 21.1468 36.2649 22.8472C36.2649 23.0233 36.2538 23.1999 36.2455 23.376C37.2401 22.7672 38.5547 22.8864 39.4169 23.7477C39.4602 23.7918 39.4969 23.8393 39.5361 23.8851C39.5641 23.5229 39.5806 23.1595 39.5806 22.7952C39.5806 20.63 39.0906 18.5253 38.1245 16.5404C37.4067 15.0632 36.4406 13.6928 35.2547 12.4656C32.2586 9.36767 28.0638 7.37154 23.4441 6.846C22.6146 6.75195 21.7925 6.7041 21.0009 6.7041C20.2456 6.7041 19.4589 6.74783 18.6615 6.83487Z" fill="#0082EF"/>
|
||||
</g>
|
||||
</mask>
|
||||
<g mask="url(#mask4_3392_197358)">
|
||||
<path id="Fill-22" fill-rule="evenodd" clip-rule="evenodd" d="M2.14697 41.2821H39.8531V6.43213H2.14697V41.2821Z" fill="#0082EF"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div id="de2-dingtalk-qr" :class="{ 'de2-dingtalk-qr': !isBind }" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { loadScript } from '@/utils/RemoteJs'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { getSQLBotAddr } from '@/utils/utils'
|
||||
import { ref } from 'vue'
|
||||
import { queryClientInfo } from './platformUtils'
|
||||
interface DingtalkQrInfo {
|
||||
client_id: string
|
||||
state: string
|
||||
redirect_uri: string
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
isBind: propTypes.bool.def(false),
|
||||
})
|
||||
const origin = ref(7)
|
||||
const remoteJsUrl = 'https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js'
|
||||
const jsId = 'de-dingtalk-qr-id'
|
||||
const init = () => {
|
||||
loadScript(remoteJsUrl, jsId).then(() => {
|
||||
queryClientInfo(origin.value).then((res: any) => {
|
||||
const data = formatQrResult(res)
|
||||
loadQr(data.client_id, data.state, data.redirect_uri)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const formatQrResult = (data: any): DingtalkQrInfo => {
|
||||
const result = { client_id: null, state: null, redirect_uri: null } as unknown as DingtalkQrInfo
|
||||
result.client_id = data.client_id
|
||||
result.state = 'fit2cloud-dingtalk-qr'
|
||||
result.redirect_uri = data.redirect_uri || getSQLBotAddr()
|
||||
if (props.isBind) {
|
||||
result.state += '_de_bind'
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const loadQr = (client_id: string, STATE: string, REDIRECT_URI: string) => {
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
window.DTFrameLogin(
|
||||
{
|
||||
id: 'de2-dingtalk-qr',
|
||||
width: 280,
|
||||
height: 300,
|
||||
},
|
||||
{
|
||||
redirect_uri: encodeURIComponent(REDIRECT_URI),
|
||||
client_id: client_id,
|
||||
scope: 'openid',
|
||||
response_type: 'code',
|
||||
state: STATE,
|
||||
prompt: 'consent',
|
||||
},
|
||||
(loginResult: any) => {
|
||||
const { redirectUrl, authCode } = loginResult
|
||||
// 这里可以直接进行重定向
|
||||
window.location.href = redirectUrl
|
||||
// 也可以在不跳转页面的情况下,使用code进行授权
|
||||
console.log(authCode)
|
||||
},
|
||||
(errorMsg: any) => {
|
||||
// 这里一般需要展示登录失败的具体原因,可以使用toast等轻提示
|
||||
console.error(`errorMsg of errorCbk: ${errorMsg}`)
|
||||
}
|
||||
)
|
||||
}
|
||||
init()
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.de2-dingtalk-qr {
|
||||
margin-top: -36px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<!-- <div v-if="loginCategory.qrcode" :class="{ 'de-qr-hidden': !qrStatus }">
|
||||
<div v-if="loginCategory.qrcode" :class="{ 'de-qr-hidden': !qrStatus }">
|
||||
<QrTab
|
||||
v-if="qrStatus"
|
||||
:wecom="loginCategory.wecom"
|
||||
@@ -7,7 +7,7 @@
|
||||
:lark="loginCategory.lark"
|
||||
:larksuite="loginCategory.larksuite"
|
||||
/>
|
||||
</div> -->
|
||||
</div>
|
||||
<LdapLoginForm v-if="isLdap" />
|
||||
<el-divider v-if="anyEnable" class="de-other-login-divider">{{
|
||||
t('login.other_login')
|
||||
@@ -54,13 +54,11 @@
|
||||
import { ref, onMounted, nextTick, computed } from 'vue'
|
||||
import QrcodeLdap from './QrcodeLdap.vue'
|
||||
import LdapLoginForm from './LdapLoginForm.vue'
|
||||
/* import Oidc from './Oidc.vue'
|
||||
import Oauth2 from './Oauth2.vue'
|
||||
import Saml2 from './Saml2.vue' */
|
||||
|
||||
import Oidc from './Oidc.vue'
|
||||
import Cas from './Cas.vue'
|
||||
import Oauth2 from './Oauth2.vue'
|
||||
// import QrTab from './QrTab.vue'
|
||||
import QrTab from './QrTab.vue'
|
||||
import { request } from '@/utils/request'
|
||||
import { useCache } from '@/utils/useCache'
|
||||
|
||||
@@ -197,6 +195,8 @@ const init = (cb?: () => void) => {
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
const list: any[] = res as any[]
|
||||
/* list.push({ name: 'qrcode', enable: true })
|
||||
list.push({ name: 'wecom', enable: true }) */
|
||||
list.forEach((item: { name: keyof LoginCategory; enable: boolean }) => {
|
||||
loginCategory.value[item.name] = item.enable
|
||||
if (item.enable) {
|
||||
@@ -416,6 +416,72 @@ const oidcLogin = () => {
|
||||
}, 1500)
|
||||
})
|
||||
}
|
||||
const wecomLogin = () => {
|
||||
const urlParams = getUrlParams()
|
||||
request
|
||||
.post('/system/platform/sso/6', urlParams)
|
||||
.then((res: any) => {
|
||||
const token = res.access_token
|
||||
// const platform_info = res.platform_info
|
||||
if (token && isPlatformClient()) {
|
||||
wsCache.set('de-platform-client', true)
|
||||
}
|
||||
userStore.setToken(token)
|
||||
userStore.setExp(res.exp)
|
||||
userStore.setTime(Date.now())
|
||||
userStore.setPlatformInfo({
|
||||
flag: 'wecom',
|
||||
// data: platform_info ? JSON.stringify(platform_info) : '',
|
||||
origin: 6,
|
||||
})
|
||||
const queryRedirectPath = getCurLocation()
|
||||
router.push({ path: queryRedirectPath })
|
||||
})
|
||||
.catch((e: any) => {
|
||||
userStore.setToken('')
|
||||
setTimeout(() => {
|
||||
// logoutHandler(true, true)
|
||||
platformLoginMsg.value = e?.message || e
|
||||
setTimeout(() => {
|
||||
window.location.href =
|
||||
window.location.origin + window.location.pathname + window.location.hash
|
||||
}, 2000)
|
||||
}, 1500)
|
||||
})
|
||||
}
|
||||
const dingtalkLogin = () => {
|
||||
const urlParams = getUrlParams()
|
||||
request
|
||||
.post('/system/platform/sso/7', urlParams)
|
||||
.then((res: any) => {
|
||||
const token = res.access_token
|
||||
// const platform_info = res.platform_info
|
||||
if (token && isPlatformClient()) {
|
||||
wsCache.set('de-platform-client', true)
|
||||
}
|
||||
userStore.setToken(token)
|
||||
userStore.setExp(res.exp)
|
||||
userStore.setTime(Date.now())
|
||||
userStore.setPlatformInfo({
|
||||
flag: 'dingtalk',
|
||||
// data: platform_info ? JSON.stringify(platform_info) : '',
|
||||
origin: 7,
|
||||
})
|
||||
const queryRedirectPath = getCurLocation()
|
||||
router.push({ path: queryRedirectPath })
|
||||
})
|
||||
.catch((e: any) => {
|
||||
userStore.setToken('')
|
||||
setTimeout(() => {
|
||||
// logoutHandler(true, true)
|
||||
platformLoginMsg.value = e?.message || e
|
||||
setTimeout(() => {
|
||||
window.location.href =
|
||||
window.location.origin + window.location.pathname + window.location.hash
|
||||
}, 2000)
|
||||
}, 1500)
|
||||
})
|
||||
}
|
||||
/* const platformLogin = (origin: number) => {
|
||||
const url = '/system/authentication/sso/cas'
|
||||
request
|
||||
@@ -591,6 +657,10 @@ onMounted(() => {
|
||||
oauth2Login()
|
||||
} else if (state?.includes('oidc')) {
|
||||
oidcLogin()
|
||||
} else if (state?.includes('wecom')) {
|
||||
wecomLogin()
|
||||
} else if (state?.includes('dingtalk')) {
|
||||
dingtalkLogin()
|
||||
} else {
|
||||
auto2Platform()
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { loadScript } from '@/utils/RemoteJs'
|
||||
import { getQueryString } from '@/utils/utils'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
// import { useI18n } from 'vue-i18n'
|
||||
import { i18n } from '@/i18n'
|
||||
import { queryClientInfo } from './platformUtils'
|
||||
declare global {
|
||||
interface Window {
|
||||
tt: any
|
||||
@@ -26,7 +27,7 @@ export interface LoginCategory {
|
||||
const t = i18n.global.t
|
||||
const flagArray = ['dingtalk', 'lark', 'larksuite']
|
||||
const urlArray = [
|
||||
'https://g.alicdn.com/dingding/dingtalk-jsapi/3.0.25/dingtalk.open.js',
|
||||
'https://g.alicdn.com/dingding/dingtalk-jsapi/3.1.0/dingtalk.open.js',
|
||||
'https://lf1-cdn-tos.bytegoofy.com/goofy/lark/op/h5-js-sdk-1.5.26.js',
|
||||
'https://lf1-cdn-tos.bytegoofy.com/goofy/lark/op/h5-js-sdk-1.5.16.js',
|
||||
]
|
||||
@@ -49,12 +50,7 @@ export const loadClient = (category: LoginCategory) => {
|
||||
.catch(() => {})
|
||||
return false
|
||||
}
|
||||
if (
|
||||
!type ||
|
||||
!flagArray.includes(type) ||
|
||||
!category[type as keyof LoginCategory] ||
|
||||
(type === 'dingtalk' && !corpid)
|
||||
) {
|
||||
if (!type || !flagArray.includes(type) || !category[type as keyof LoginCategory]) {
|
||||
return false
|
||||
}
|
||||
const index = flagArray.indexOf(type)
|
||||
@@ -62,7 +58,7 @@ export const loadClient = (category: LoginCategory) => {
|
||||
const awaitMethod = loadScript(urlArray[index], jsId)
|
||||
awaitMethod
|
||||
.then(() => {
|
||||
if (index === 0 && corpid) {
|
||||
if (index === 0) {
|
||||
dingtalkClientRequest(corpid)
|
||||
}
|
||||
if (index === 1) {
|
||||
@@ -78,12 +74,17 @@ export const loadClient = (category: LoginCategory) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const dingtalkClientRequest = (id?: string) => {
|
||||
const dingtalkClientRequest = async (id: string | null) => {
|
||||
const dd = window['dd']
|
||||
if (id && dd?.runtime?.permission?.requestAuthCode) {
|
||||
dd.runtime.permission.requestAuthCode({
|
||||
corpId: id,
|
||||
if (dd?.requestAuthCode) {
|
||||
const clientInfoRes = await queryClientInfo(7)
|
||||
const corpId = id || clientInfoRes['corpid']
|
||||
const client_id = clientInfoRes['client_id']
|
||||
dd.requestAuthCode({
|
||||
corpId: corpId,
|
||||
clientId: client_id,
|
||||
onSuccess: function (result: any) {
|
||||
ElMessage.success(JSON.stringify(result))
|
||||
const code = result.code
|
||||
const state = `fit2cloud-dingtalk-client`
|
||||
toUrl(`?code=${code}&state=${state}`)
|
||||
@@ -102,8 +103,8 @@ const larkClientRequest = async () => {
|
||||
ElMessage.error('load remote lark js error')
|
||||
return
|
||||
}
|
||||
const res = await queryAppid('lark')
|
||||
if (!res?.data?.appId) {
|
||||
const res = await queryClientInfo(8)
|
||||
if (!res?.appId) {
|
||||
ElMessage.error('get appId error')
|
||||
return
|
||||
}
|
||||
@@ -150,7 +151,7 @@ const larksuiteClientRequest = async () => {
|
||||
ElMessage.error('load remote lark js error')
|
||||
return
|
||||
}
|
||||
const res = await queryAppid('larksuite')
|
||||
const res = await queryClientInfo(9)
|
||||
if (!res?.data?.appId) {
|
||||
ElMessage.error('get appId error')
|
||||
return
|
||||
@@ -173,11 +174,6 @@ const larksuiteClientRequest = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
const queryAppid = (type: string) => {
|
||||
const url = `/${type}/qrinfo`
|
||||
return request.get(url)
|
||||
}
|
||||
|
||||
const toUrl = (url: string) => {
|
||||
const { origin, pathname } = window.location
|
||||
window.location.href = origin + pathname + url
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane
|
||||
v-if="props.wecom"
|
||||
:label="t('user.wechat_for_business')"
|
||||
name="wecom"
|
||||
></el-tab-pane>
|
||||
<el-tab-pane v-if="props.dingtalk" :label="t('user.dingtalk')" name="dingtalk"></el-tab-pane>
|
||||
<el-tab-pane v-if="props.lark" :label="t('user.feishu')" name="lark"></el-tab-pane>
|
||||
<el-tab-pane
|
||||
v-if="props.larksuite"
|
||||
:label="t('system.international_feishu')"
|
||||
name="larksuite"
|
||||
></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-if="activeName === 'wecom'" class="login-qrcode">
|
||||
<div class="title">
|
||||
<el-icon>
|
||||
<Icon name="logo_wechat-work"><logo_wechatWork class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
{{ t('user.wechat_for_business') }}
|
||||
</div>
|
||||
<div class="qrcode">
|
||||
<wecom-qr v-if="activeName === 'wecom'" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="activeName === 'dingtalk'" class="login-qrcode">
|
||||
<div class="title">
|
||||
<el-icon>
|
||||
<Icon name="logo_dingtalk"><logo_dingtalk class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
{{ t('user.dingtalk') }}
|
||||
</div>
|
||||
<div class="qrcode">
|
||||
<dingtalk-qr v-if="activeName === 'dingtalk'" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="activeName === 'lark'" class="login-qrcode">
|
||||
<div class="title">
|
||||
<el-icon>
|
||||
<Icon name="logo_lark"><logo_lark class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
{{ t('threshold.lark') }}
|
||||
</div>
|
||||
<div class="qrcode">
|
||||
<lark-qr v-if="activeName === 'lark'" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="activeName === 'larksuite'" class="login-qrcode">
|
||||
<div class="title">
|
||||
<el-icon>
|
||||
<Icon name="logo_lark"><logo_lark class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
{{ t('system.international_feishu') }}
|
||||
</div>
|
||||
<div class="qrcode">
|
||||
<larksuite-qr v-if="activeName === 'larksuite'" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import logo_wechatWork from '@/assets/svg/logo_wechat-work.svg'
|
||||
import logo_dingtalk from '@/assets/svg/logo_dingtalk.svg'
|
||||
import logo_lark from '@/assets/svg/logo_lark.svg'
|
||||
import { ref } from 'vue'
|
||||
/* import LarkQr from './LarkQr.vue'
|
||||
import LarksuiteQr from './LarksuiteQr.vue' */
|
||||
import DingtalkQr from './DingtalkQr.vue'
|
||||
import WecomQr from './WecomQr.vue'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const activeName = ref('')
|
||||
const props = defineProps({
|
||||
wecom: propTypes.bool.def(false),
|
||||
lark: propTypes.bool.def(false),
|
||||
dingtalk: propTypes.bool.def(false),
|
||||
larksuite: propTypes.bool.def(false),
|
||||
})
|
||||
const initActive = () => {
|
||||
const qrArray = ['wecom', 'dingtalk', 'lark', 'larksuite'] as const
|
||||
for (let i = 0; i < qrArray.length; i++) {
|
||||
const key = qrArray[i]
|
||||
if (props[key as keyof typeof props]) {
|
||||
activeName.value = key
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
const handleClick = () => {}
|
||||
initActive()
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.login-qrcode {
|
||||
height: 340px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
.qrcode {
|
||||
max-width: 286px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 24px 0 12px 0;
|
||||
font-family: var(--de-custom_font, 'PingFang');
|
||||
font-size: 18px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 26px;
|
||||
height: 26px;
|
||||
.ed-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div id="sqlbot-wecom-qr" :class="isBind ? 'sqlbot-wecom-bind-qr' : 'sqlbot-wecom-qr'" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { loadScript } from '@/utils/RemoteJs'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { onUnmounted, ref } from 'vue'
|
||||
import { getLocale, getSQLBotAddr } from '@/utils/utils'
|
||||
import { queryClientInfo } from './platformUtils'
|
||||
interface WecomInfo {
|
||||
corp_id: string
|
||||
agent_id: string
|
||||
state: string
|
||||
redirect_uri: string
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
isBind: propTypes.bool.def(false),
|
||||
})
|
||||
const origin = ref(6)
|
||||
// const emit = defineEmits(['finish'])
|
||||
let wwLogin = null as any
|
||||
const remoteJsUrl = 'https://wwcdn.weixin.qq.com/node/open/js/wecom-jssdk-2.3.3.js'
|
||||
const jsId = 'sqlbot-wecom-qr-id'
|
||||
const init = () => {
|
||||
loadScript(remoteJsUrl, jsId).then(() => {
|
||||
queryClientInfo(origin.value).then((res) => {
|
||||
const data = formatQrResult(res)
|
||||
loadQr(data.corp_id, data.agent_id, data.state, data.redirect_uri)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const formatQrResult = (data: any): WecomInfo => {
|
||||
const result = {
|
||||
corp_id: null,
|
||||
agent_id: null,
|
||||
state: null,
|
||||
redirect_uri: null,
|
||||
} as unknown as WecomInfo
|
||||
result.corp_id = data.corp_id
|
||||
result.agent_id = data.agent_id
|
||||
result.state = data.state || 'fit2cloud-wecom-qr'
|
||||
result.redirect_uri = data.redirect_uri || getSQLBotAddr()
|
||||
if (props.isBind) {
|
||||
result.state += '_sqlbot_bind'
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const loadQr = (CORP_ID: string, AGENT_ID: string, STATE: string, REDIRECT_URI: string) => {
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undef
|
||||
wwLogin = ww.createWWLoginPanel({
|
||||
el: '#sqlbot-wecom-qr',
|
||||
params: {
|
||||
login_type: 'CorpApp',
|
||||
appid: CORP_ID,
|
||||
agentid: AGENT_ID,
|
||||
redirect_uri: REDIRECT_URI,
|
||||
state: STATE,
|
||||
redirect_type: 'callback',
|
||||
lang: getLocale() === 'en' ? 'en' : 'zh',
|
||||
},
|
||||
onCheckWeComLogin({ isWeComLogin }: { isWeComLogin: boolean }) {
|
||||
console.log(isWeComLogin)
|
||||
},
|
||||
onLoginSuccess({ code }: { code: string }) {
|
||||
window.location.href = REDIRECT_URI + `?code=${code}&state=${STATE}`
|
||||
},
|
||||
onLoginFail(err: any) {
|
||||
console.log(err)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
if (wwLogin) {
|
||||
wwLogin.unmount()
|
||||
}
|
||||
})
|
||||
init()
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.sqlbot-wecom-qr {
|
||||
margin-top: -55px;
|
||||
}
|
||||
.sqlbot-wecom-bind-qr {
|
||||
margin-top: -20px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,5 @@
|
||||
import { request } from '@/utils/request'
|
||||
export const queryClientInfo = (origin: number) => {
|
||||
const url = `/system/platform/client/${origin}`
|
||||
return request.get(url)
|
||||
}
|
||||
Reference in New Issue
Block a user