mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-13 15:55:43 +08:00
feat 开放平台登录
This commit is contained in:
1
public/icons/weCom.js
Normal file
1
public/icons/weCom.js
Normal file
@@ -0,0 +1 @@
|
||||
!function(e){var t,n,o,c,i,a='<svg><symbol id="wecom" viewBox="0 0 1024 1024"><path d="M700.8256 701.2864c26.88 26.9312 59.392 43.1104 95.4368 53.248l12.1344 3.1232c25.2928 4.608 38.5536 27.648 39.68 51.2 0 27.648-20.1216 51.2-47.7696 55.2448-26.4192 3.4304-54.0672-13.2608-59.8016-39.7312-8.0384-40.8064-25.344-76.4928-55.2448-106.3936-3.4304-3.4816-1.1264-10.9568-2.304-16.6912l13.4656-1.024c2.048 0 3.584 0.256 4.4032 1.024z m48.896-521.216c56.32 59.8016 87.4496 130.56 88.576 212.8384a109.2096 109.2096 0 0 0-45.4656-9.728h-2.304a109.2096 109.2096 0 0 0-104.0896 96.6144 120.2688 120.2688 0 0 0 0 28.7744c-20.1728 20.1216-44.9024 32.768-75.3664 37.9392h-0.6144a105.1648 105.1648 0 0 0-44.288 184.6784 416.3584 416.3584 0 0 1-106.4448 17.8688 481.3824 481.3824 0 0 1-137.472-13.2608 50.0224 50.0224 0 0 0-22.4256 2.304l-104.1408 51.2c-13.2608 6.912-25.344 8.0384-36.864-1.1264-10.9056-8.0896-12.032-20.1728-10.9056-34.56 4.608-28.7232 8.0896-57.4976 10.9568-86.272a31.1296 31.1296 0 0 0-8.0896-18.944c-45.4144-45.5168-84.5312-95.5392-104.0896-158.8224-36.864-125.44-3.4816-232.96 87.4496-322.7648C300.3904 3.9936 590.848 11.4688 749.7216 180.0704z m207.104 414.7712c28.7744 3.4816 50.0224 26.4704 50.0224 55.2448 0 27.648-16.6912 50.0224-44.288 55.2448-33.792 6.144-64.3072 20.48-89.7024 42.496l-9.216 8.704c-5.7856 5.7344-14.3872 10.9056-20.1728 2.304-2.304-4.608-1.1264-15.5648 2.304-18.9952a186.0096 186.0096 0 0 0 51.2-100.7104 54.784 54.784 0 0 1 59.8528-44.288z m-215.1936-51.7632c-1.1264 5.7344 1.1776 14.336-2.304 17.8176-28.7232 28.7744-44.288 63.2832-52.3264 103.0144-5.7856 28.7232-32.256 45.4144-59.8528 40.8064-27.648-4.608-48.3328-28.7744-48.3328-55.808 0-24.1664 17.8688-46.592 41.984-51.2a190.4128 190.4128 0 0 0 103.0144-52.3264c3.4304-3.4816 12.0832-2.304 17.8176-2.304z m51.2-108.1856c25.344 0 48.896 16.6912 54.1184 43.1616 6.8608 39.68 24.1664 74.24 52.3264 102.9632 3.4816 3.4816 1.1776 13.2608 2.304 18.9952-6.912 0-15.5136 2.304-18.944-1.1264-28.8256-29.952-64.512-45.4656-104.192-54.0672a53.6576 53.6576 0 0 1-40.8064-58.7264c3.9936-28.7232 26.4704-50.0224 55.1936-51.2z" ></path></symbol></svg>',d=(d=document.getElementsByTagName("script"))[d.length-1].getAttribute("data-injectcss"),l=function(e,t){t.parentNode.insertBefore(e,t)};if(d&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(e){console&&console.log(e)}}function s(){i||(i=!0,o())}function r(){try{c.documentElement.doScroll("left")}catch(e){return void setTimeout(r,50)}s()}t=function(){var e,t=document.createElement("div");t.innerHTML=a,a=null,(t=t.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",t=t,(e=document.body).firstChild?l(t,e.firstChild):e.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),t()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(o=t,c=e.document,i=!1,r(),c.onreadystatechange=function(){"complete"==c.readyState&&(c.onreadystatechange=null,s())})}(window);
|
||||
@@ -1,79 +1,74 @@
|
||||
<template>
|
||||
<LoginFormTitle v-show="getShow" class="enter-x" />
|
||||
<a-form
|
||||
class="p-4 enter-x"
|
||||
:model="form"
|
||||
:validate-trigger="['blur', 'change']"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
v-show="getShow"
|
||||
@keypress.enter="handleLogin"
|
||||
>
|
||||
<a-form-item name="account" class="enter-x">
|
||||
<a-input size="large" v-model:value="form.account" placeholder="账号/手机号/邮箱" class="fix-auto-fill" />
|
||||
</a-form-item>
|
||||
<a-form-item name="password" class="enter-x">
|
||||
<a-input-password size="large" visibilityToggle v-model:value="form.password" placeholder="密码" />
|
||||
</a-form-item>
|
||||
<a-spin :spinning="loading">
|
||||
<a-form
|
||||
class="p-4 enter-x"
|
||||
:model="form"
|
||||
:validate-trigger="['blur', 'change']"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
v-show="getShow"
|
||||
@keypress.enter="handleLogin"
|
||||
>
|
||||
<a-form-item name="account" class="enter-x">
|
||||
<a-input size="large" v-model:value="form.account" placeholder="账号/手机号/邮箱" class="fix-auto-fill" />
|
||||
</a-form-item>
|
||||
<a-form-item name="password" class="enter-x">
|
||||
<a-input-password size="large" visibilityToggle v-model:value="form.password" placeholder="密码" />
|
||||
</a-form-item>
|
||||
|
||||
<a-row :span="12" class="enter-x" v-if="loginType.captcha">
|
||||
<a-col :span="16">
|
||||
<a-form-item name="captcha" class="enter-x">
|
||||
<a-input size="large" placeholder="验证码" v-model:value="form.captcha" style="min-width: 100px" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8" style="text-align: right">
|
||||
<a-form-item :style="{ 'text-align': 'right', 'margin-left': '20px' }" class="enter-x">
|
||||
<img style="margin-top: 2px" :src="captchaData" @click="getCaptcha" alt="验证码" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :span="12" class="enter-x" v-if="loginType.captcha">
|
||||
<a-col :span="16">
|
||||
<a-form-item name="captcha" class="enter-x">
|
||||
<a-input size="large" placeholder="验证码" v-model:value="form.captcha" style="min-width: 100px" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8" style="text-align: right">
|
||||
<a-form-item :style="{ 'text-align': 'right', 'margin-left': '20px' }" class="enter-x">
|
||||
<img style="margin-top: 2px" :src="captchaData" @click="getCaptcha" alt="验证码" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row class="enter-x">
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-checkbox v-model:checked="rememberMe" size="small"> 记住我 </a-checkbox>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item :style="{ 'text-align': 'right' }">
|
||||
<!-- 没有逻辑,你需要自己处理 -->
|
||||
<a-button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)"> 忘记密码? </a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row class="enter-x">
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-checkbox v-model:checked="rememberMe" size="small"> 记住我 </a-checkbox>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item :style="{ 'text-align': 'right' }">
|
||||
<!-- 没有逻辑,你需要自己处理 -->
|
||||
<a-button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)"> 忘记密码? </a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item class="enter-x">
|
||||
<a-button type="primary" size="large" block @click="handleLogin" :loading="loading"> 登录 </a-button>
|
||||
</a-form-item>
|
||||
<a-row class="enter-x">
|
||||
<a-col :md="8" :xs="24">
|
||||
<a-button block @click="setLoginState(LoginStateEnum.MOBILE)"> 手机登录 </a-button>
|
||||
</a-col>
|
||||
<a-col :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2">
|
||||
<a-button block @click="setLoginState(LoginStateEnum.QR_CODE)"> 二维码登录 </a-button>
|
||||
</a-col>
|
||||
<a-col :md="6" :xs="24">
|
||||
<a-button block @click="setLoginState(LoginStateEnum.REGISTER)"> 注册 </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider class="enter-x">其他登录方式</a-divider>
|
||||
|
||||
<div class="flex justify-evenly enter-x" :class="`${prefixCls}-sign-in-way`">
|
||||
<GithubFilled />
|
||||
<WechatFilled />
|
||||
<AlipayCircleFilled />
|
||||
<GoogleCircleFilled />
|
||||
<TwitterCircleFilled />
|
||||
</div>
|
||||
</a-form>
|
||||
<a-form-item class="enter-x">
|
||||
<a-button type="primary" size="large" block @click="handleLogin"> 登录 </a-button>
|
||||
</a-form-item>
|
||||
<a-row class="enter-x">
|
||||
<a-col :md="8" :xs="24">
|
||||
<a-button block @click="setLoginState(LoginStateEnum.MOBILE)"> 手机登录 </a-button>
|
||||
</a-col>
|
||||
<a-col :md="8" :xs="24" class="!my-2 !md:my-0 xs:mx-0 md:mx-2">
|
||||
<a-button block @click="setLoginState(LoginStateEnum.QR_CODE)"> 二维码登录 </a-button>
|
||||
</a-col>
|
||||
<a-col :md="6" :xs="24">
|
||||
<a-button block @click="setLoginState(LoginStateEnum.REGISTER)"> 注册 </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider class="enter-x">其他登录方式</a-divider>
|
||||
<div class="flex justify-evenly enter-x" :class="`${prefixCls}-sign-in-way`">
|
||||
<third-login @loginLoading="loading = true" @loginFinish="loading = false" />
|
||||
</div>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, unref, computed, onMounted } from 'vue'
|
||||
|
||||
import { GithubFilled, WechatFilled, AlipayCircleFilled, GoogleCircleFilled, TwitterCircleFilled } from '@ant-design/icons-vue'
|
||||
import LoginFormTitle from './LoginFormTitle.vue'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { useUserStore } from '/@/store/modules/user'
|
||||
@@ -85,6 +80,7 @@
|
||||
import { findLoginTypeByCode, LoginType } from '/@/api/common/LoginAssist'
|
||||
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
|
||||
import { LoginParams } from '/@/api/sys/model/userModel'
|
||||
import ThirdLogin from '/@/views/login/third/ThirdLogin.vue'
|
||||
|
||||
const { notification } = useMessage()
|
||||
const { prefixCls } = useDesign('login')
|
||||
@@ -138,6 +134,7 @@
|
||||
findLoginTypeByCode(form.loginType).then(({ data }) => {
|
||||
loginType = data
|
||||
if (loginType && loginType.captcha && loginType.enable) {
|
||||
console.log(loginType)
|
||||
getCaptcha()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ export const DING_TALK = 'dingTalk'
|
||||
export const WE_CHAT = 'weChat'
|
||||
// 微信(开放平台)
|
||||
export const WE_CHAT_OPEN = 'weChatOpen'
|
||||
// 微信
|
||||
// 企业微信
|
||||
export const WE_COM = 'weCom'
|
||||
// QQ
|
||||
export const QQ = 'qq'
|
||||
|
||||
66
src/views/login/third/ThirdLogin.vue
Normal file
66
src/views/login/third/ThirdLogin.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<a @click="onThirdLogin(DING_TALK)" title="钉钉"><DingdingOutlined /></a>
|
||||
<a @click="onThirdLogin(WE_COM)" title="企业微信"> <icon-font class="item-icon" type="wecom" /></a>
|
||||
<a @click="onThirdLogin(WE_CHAT_OPEN)" title="微信"><WechatFilled /></a>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { DingdingOutlined, WechatFilled, createFromIconfontCN } from '@ant-design/icons-vue'
|
||||
import { $ref } from 'vue/macros'
|
||||
import { getAppEnvConfig } from '/@/utils/env'
|
||||
import { useUserStore } from '/@/store/modules/user'
|
||||
import { LoginParams } from '/@/api/sys/model/userModel'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { DING_TALK, WE_CHAT_OPEN, WE_COM } from './OpenIdLoginType'
|
||||
const IconFont = createFromIconfontCN({
|
||||
scriptUrl: '/icons/weCom.js',
|
||||
})
|
||||
|
||||
const emits = defineEmits(['loginFinish', 'loginLoading'])
|
||||
|
||||
const userStore = useUserStore()
|
||||
const { notification } = useMessage()
|
||||
|
||||
const { VITE_GLOB_API_URL, VITE_GLOB_APP_CLIENT } = getAppEnvConfig()
|
||||
let currentLoginType = $ref<string>()
|
||||
/**
|
||||
* 调起登录
|
||||
*/
|
||||
function onThirdLogin(loginTpe) {
|
||||
currentLoginType = loginTpe
|
||||
const url = VITE_GLOB_API_URL + `/auth/third/toLoginUrl/${loginTpe}`
|
||||
open(
|
||||
url,
|
||||
`login ${loginTpe}`,
|
||||
'height=600, width=500, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=n o, status=no',
|
||||
)
|
||||
// 监听回调
|
||||
addEventListener('message', authCodeCallback, false)
|
||||
|
||||
/**
|
||||
* 认证码回调
|
||||
*/
|
||||
async function authCodeCallback(event) {
|
||||
// 回调后就进行解绑事件, 防止重复接收消息
|
||||
window.removeEventListener('message', authCodeCallback)
|
||||
const data = event.data
|
||||
emits('loginLoading')
|
||||
const token = await userStore
|
||||
.login({
|
||||
...data,
|
||||
client: VITE_GLOB_APP_CLIENT,
|
||||
loginType: currentLoginType,
|
||||
} as LoginParams)
|
||||
.finally(() => emits('loginFinish'))
|
||||
if (token) {
|
||||
notification.success({
|
||||
message: '登录成功',
|
||||
description: '欢迎回来',
|
||||
duration: 3,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -31,7 +31,7 @@
|
||||
</template>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, unref, computed, onMounted } from 'vue'
|
||||
import { reactive, ref, unref, computed, onMounted, watch } from 'vue'
|
||||
import LoginFormTitle from '../LoginFormTitle.vue'
|
||||
import { StrengthMeter } from '/@/components/StrengthMeter'
|
||||
import { useLoginState, LoginStateEnum } from '../useLogin'
|
||||
@@ -43,7 +43,19 @@
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
|
||||
const { handleBackLogin, getLoginState } = useLoginState()
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER)
|
||||
const getShow = computed(() => {
|
||||
const f = unref(getLoginState) === LoginStateEnum.REGISTER
|
||||
if (f) {
|
||||
getCaptcha()
|
||||
}
|
||||
return f
|
||||
})
|
||||
watch(
|
||||
() => getShow,
|
||||
(value) => {
|
||||
console.log(value)
|
||||
},
|
||||
)
|
||||
|
||||
const { createMessage } = useMessage()
|
||||
|
||||
@@ -66,10 +78,6 @@
|
||||
captcha: [{ required: true, message: '请输入验证码!' }],
|
||||
} as Record<string, Rule[]>
|
||||
|
||||
onMounted(() => {
|
||||
getCaptcha()
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
*/
|
||||
|
||||
8
types/config.d.ts
vendored
8
types/config.d.ts
vendored
@@ -149,15 +149,15 @@ export interface GlobConfig {
|
||||
shortName: string
|
||||
}
|
||||
export interface GlobEnvConfig {
|
||||
// Site title
|
||||
// 项目名称
|
||||
VITE_GLOB_APP_TITLE: string
|
||||
// Service interface url
|
||||
// 接口地址
|
||||
VITE_GLOB_API_URL: string
|
||||
// Service interface url prefix
|
||||
// 接口前缀
|
||||
VITE_GLOB_API_URL_PREFIX?: string
|
||||
// Project abbreviation
|
||||
VITE_GLOB_APP_SHORT_NAME: string
|
||||
// Upload url
|
||||
// 上传接口
|
||||
VITE_GLOB_UPLOAD_URL?: string
|
||||
// 终端类型
|
||||
VITE_GLOB_APP_CLIENT: string
|
||||
|
||||
Reference in New Issue
Block a user