✨ qq oauth2 login complete
This commit is contained in:
@@ -2,13 +2,13 @@
|
|||||||
VITE_NODE_ENV='development'
|
VITE_NODE_ENV='development'
|
||||||
|
|
||||||
# 开发环境
|
# 开发环境
|
||||||
VITE_APP_BASE_API='/api'
|
VITE_APP_BASE_API='/sys'
|
||||||
|
|
||||||
# 页面 title 前缀
|
# 页面 title 前缀
|
||||||
VITE_APP_TITLE=开发环境
|
VITE_APP_TITLE=开发环境
|
||||||
|
|
||||||
# 网络请求公用地址
|
# 网络请求公用地址
|
||||||
VITE_API_BASE_URL='http://127.0.0.1:8080'
|
VITE_API_BASE_URL='http://127.0.0.1:80'
|
||||||
|
|
||||||
VITE_TITLE_NAME='五味子云相册'
|
VITE_TITLE_NAME='五味子云相册'
|
||||||
|
|
||||||
@@ -16,4 +16,5 @@ VITE_TITLE_NAME='五味子云相册'
|
|||||||
VITE_APP_TOKEN_KEY='Bearer'
|
VITE_APP_TOKEN_KEY='Bearer'
|
||||||
|
|
||||||
# the websocket url
|
# the websocket url
|
||||||
VITE_WEB_SOCKET_URL='ws://127.0.0.1:8080/api/ws/gws'
|
#VITE_WEB_SOCKET_URL='ws://127.0.0.1:80/api/ws/gws'
|
||||||
|
VITE_WEB_SOCKET_URL='wss://landaiqing.cn/api/ws/gws'
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
VITE_NODE_ENV='production'
|
VITE_NODE_ENV='production'
|
||||||
# 生产环境
|
# 生产环境
|
||||||
VITE_APP_BASE_API='/api'
|
VITE_APP_BASE_API='/sys'
|
||||||
|
|
||||||
# 页面 title 前缀
|
# 页面 title 前缀
|
||||||
VITE_APP_TITLE=生产环境
|
VITE_APP_TITLE=生产环境
|
||||||
|
|
||||||
# 网络请求公用地址
|
# 网络请求公用地址
|
||||||
VITE_API_BASE_URL='http://1.95.0.111:5050'
|
VITE_API_BASE_URL='http://127.0.0.1:80'
|
||||||
|
|
||||||
VITE_TITLE_NAME='五味子云相册'
|
VITE_TITLE_NAME='五味子云相册'
|
||||||
|
|
||||||
@@ -15,4 +15,5 @@ VITE_TITLE_NAME='五味子云相册'
|
|||||||
VITE_APP_TOKEN_KEY='Bearer'
|
VITE_APP_TOKEN_KEY='Bearer'
|
||||||
|
|
||||||
# the websocket url
|
# the websocket url
|
||||||
VITE_WEB_SOCKET_URL='ws://127.0.0.1:8080/api/ws/gws'
|
#VITE_WEB_SOCKET_URL='ws://127.0.0.1:80/api/ws/gws'
|
||||||
|
VITE_WEB_SOCKET_URL='wss://landaiqing.cn/api/ws/gws'
|
||||||
|
6
components.d.ts
vendored
6
components.d.ts
vendored
@@ -12,7 +12,6 @@ declare module 'vue' {
|
|||||||
ACard: typeof import('ant-design-vue/es')['Card']
|
ACard: typeof import('ant-design-vue/es')['Card']
|
||||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
||||||
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
|
|
||||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||||
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
|
||||||
AFlex: typeof import('ant-design-vue/es')['Flex']
|
AFlex: typeof import('ant-design-vue/es')['Flex']
|
||||||
@@ -23,17 +22,14 @@ declare module 'vue' {
|
|||||||
AMenu: typeof import('ant-design-vue/es')['Menu']
|
AMenu: typeof import('ant-design-vue/es')['Menu']
|
||||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
||||||
AQrcode: typeof import('ant-design-vue/es')['QRCode']
|
AQrcode: typeof import('ant-design-vue/es')['QRCode']
|
||||||
ArrowRightOutlined: typeof import('@ant-design/icons-vue')['ArrowRightOutlined']
|
|
||||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
||||||
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
|
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
BoxDog: typeof import('./src/components/BoxDog/BoxDog.vue')['default']
|
BoxDog: typeof import('./src/components/BoxDog/BoxDog.vue')['default']
|
||||||
Card3D: typeof import('./src/components/Card3D/Card3D.vue')['default']
|
Card3D: typeof import('./src/components/Card3D/Card3D.vue')['default']
|
||||||
Clouds: typeof import('./src/components/Clouds/Clouds.vue')['default']
|
Clouds: typeof import('./src/components/Clouds/Clouds.vue')['default']
|
||||||
DownOutlined: typeof import('@ant-design/icons-vue')['DownOutlined']
|
|
||||||
DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default']
|
DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default']
|
||||||
EffectsCard: typeof import('./src/components/EffectsCard/EffectsCard.vue')['default']
|
EffectsCard: typeof import('./src/components/EffectsCard/EffectsCard.vue')['default']
|
||||||
ForgetPage: typeof import('./src/views/Forget/ForgetPage.vue')['default']
|
ForgetPage: typeof import('./src/views/Forget/ForgetPage.vue')['default']
|
||||||
@@ -42,6 +38,7 @@ declare module 'vue' {
|
|||||||
LockOutlined: typeof import('@ant-design/icons-vue')['LockOutlined']
|
LockOutlined: typeof import('@ant-design/icons-vue')['LockOutlined']
|
||||||
LoginFooter: typeof import('./src/views/Login/LoginFooter.vue')['default']
|
LoginFooter: typeof import('./src/views/Login/LoginFooter.vue')['default']
|
||||||
LoginPage: typeof import('./src/views/Login/LoginPage.vue')['default']
|
LoginPage: typeof import('./src/views/Login/LoginPage.vue')['default']
|
||||||
|
MainPage: typeof import('./src/views/Main/MainPage.vue')['default']
|
||||||
NotFound: typeof import('./src/views/404/NotFound.vue')['default']
|
NotFound: typeof import('./src/views/404/NotFound.vue')['default']
|
||||||
QqOutlined: typeof import('@ant-design/icons-vue')['QqOutlined']
|
QqOutlined: typeof import('@ant-design/icons-vue')['QqOutlined']
|
||||||
QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default']
|
QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default']
|
||||||
@@ -50,7 +47,6 @@ declare module 'vue' {
|
|||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
SafetyOutlined: typeof import('@ant-design/icons-vue')['SafetyOutlined']
|
SafetyOutlined: typeof import('@ant-design/icons-vue')['SafetyOutlined']
|
||||||
TabletOutlined: typeof import('@ant-design/icons-vue')['TabletOutlined']
|
TabletOutlined: typeof import('@ant-design/icons-vue')['TabletOutlined']
|
||||||
TestI18n: typeof import('./src/views/TestI18n.vue')['default']
|
|
||||||
TestTheme: typeof import('./src/views/TestTheme.vue')['default']
|
TestTheme: typeof import('./src/views/TestTheme.vue')['default']
|
||||||
UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined']
|
UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined']
|
||||||
WechatOutlined: typeof import('@ant-design/icons-vue')['WechatOutlined']
|
WechatOutlined: typeof import('@ant-design/icons-vue')['WechatOutlined']
|
||||||
|
@@ -6,7 +6,7 @@ $modes: (
|
|||||||
infoColor: #000
|
infoColor: #000
|
||||||
),
|
),
|
||||||
"dark": (
|
"dark": (
|
||||||
bgColor: #000,
|
bgColor: rgba(15, 15, 16, 0.63),
|
||||||
infoColor: #fff
|
infoColor: #fff
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@@ -16,7 +16,27 @@
|
|||||||
<label for="toggle-box-checkbox" class="toggle-box-label-left"></label>
|
<label for="toggle-box-checkbox" class="toggle-box-label-left"></label>
|
||||||
<label for="toggle-box-checkbox" class="toggle-box-label"></label>
|
<label for="toggle-box-checkbox" class="toggle-box-label"></label>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="margin-right: 20px;">
|
||||||
|
<ADropdown>
|
||||||
|
<template #overlay>
|
||||||
|
<AMenu @click="(e: any)=>{
|
||||||
|
changeTheme(e.key)
|
||||||
|
}">
|
||||||
|
<AMenuItem v-for="(color, name) in variables" :key="name" :value="color">
|
||||||
|
<div
|
||||||
|
v-bind:style="{ backgroundColor: name as string, width: '20px', height: '20px', borderRadius: '20%' }">
|
||||||
|
</div>
|
||||||
|
</AMenuItem>
|
||||||
|
</AMenu>
|
||||||
|
</template>
|
||||||
|
<AButton type="text" size="large">
|
||||||
|
<div
|
||||||
|
v-bind:style="{ backgroundColor: app.themeName, width: '20px', height: '20px', borderRadius: '20%' }">
|
||||||
|
</div>
|
||||||
|
</AButton>
|
||||||
|
</ADropdown>
|
||||||
|
|
||||||
|
</div>
|
||||||
<div style="margin-right: 20px;">
|
<div style="margin-right: 20px;">
|
||||||
<ADropdown>
|
<ADropdown>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
@@ -34,6 +54,7 @@
|
|||||||
</ADropdown>
|
</ADropdown>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<AButton @click="router.push('/login')" type="primary" size="large" style="margin-right: 10px;">
|
<AButton @click="router.push('/login')" type="primary" size="large" style="margin-right: 10px;">
|
||||||
{{ t("landing.immediately") }}
|
{{ t("landing.immediately") }}
|
||||||
</AButton>
|
</AButton>
|
||||||
@@ -49,6 +70,7 @@ import useStore from "@/store/index.ts";
|
|||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import {DownOutlined} from '@ant-design/icons-vue';
|
import {DownOutlined} from '@ant-design/icons-vue';
|
||||||
import {useI18n} from "vue-i18n";
|
import {useI18n} from "vue-i18n";
|
||||||
|
import variables from "@/assets/styles/colors.module.scss";
|
||||||
|
|
||||||
const lang = useStore().lang;
|
const lang = useStore().lang;
|
||||||
const {t, locale} = useI18n();
|
const {t, locale} = useI18n();
|
||||||
@@ -59,6 +81,10 @@ async function changeLang(language: any) {
|
|||||||
locale.value = language;
|
locale.value = language;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function changeTheme(theme: any) {
|
||||||
|
app.setThemeName(theme);
|
||||||
|
}
|
||||||
|
|
||||||
const app = useStore().theme;
|
const app = useStore().theme;
|
||||||
const isDarkMode = ref<boolean>(app.darkMode === "dark");
|
const isDarkMode = ref<boolean>(app.darkMode === "dark");
|
||||||
|
|
||||||
|
11
src/router/modules/main_router.ts
Normal file
11
src/router/modules/main_router.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export default [
|
||||||
|
{
|
||||||
|
path: '/main',
|
||||||
|
name: 'main',
|
||||||
|
component: () => import('@/views/Main/MainPage.vue'),
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true,
|
||||||
|
title: '主页'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
@@ -1,11 +0,0 @@
|
|||||||
export default [
|
|
||||||
{
|
|
||||||
path: '/test2',
|
|
||||||
name: 'test2',
|
|
||||||
component: () => import('@/views/TestI18n.vue'),
|
|
||||||
meta: {
|
|
||||||
requiresAuth: true,
|
|
||||||
title: '测试'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
@@ -3,20 +3,21 @@
|
|||||||
import {createRouter, createWebHistory, Router, RouteRecordRaw} from 'vue-router';
|
import {createRouter, createWebHistory, Router, RouteRecordRaw} from 'vue-router';
|
||||||
import login from './modules/login';
|
import login from './modules/login';
|
||||||
import test from "@/router/modules/test.ts";
|
import test from "@/router/modules/test.ts";
|
||||||
import test2 from "@/router/modules/testI18n.ts";
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
import {message} from "ant-design-vue";
|
import {message} from "ant-design-vue";
|
||||||
import {close, start} from '@/components/Nprogress/nprogress.ts';
|
import {close, start} from '@/components/Nprogress/nprogress.ts';
|
||||||
import notFound from "@/router/modules/notFound.ts";
|
import notFound from "@/router/modules/notFound.ts";
|
||||||
import landing from "@/router/modules/landing.ts";
|
import landing from "@/router/modules/landing.ts";
|
||||||
|
import mainRouter from "@/router/modules/main_router.ts";
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
...login,
|
...login,
|
||||||
...notFound,
|
...notFound,
|
||||||
...landing,
|
...landing,
|
||||||
|
...mainRouter,
|
||||||
...test,
|
...test,
|
||||||
...test2,
|
|
||||||
{
|
{
|
||||||
path: '/:pathMatch(.*)',
|
path: '/:pathMatch(.*)',
|
||||||
redirect: '/404',
|
redirect: '/404',
|
||||||
@@ -29,7 +30,7 @@ const router: Router = createRouter({
|
|||||||
routes
|
routes
|
||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, _from, next) => {
|
||||||
start();
|
start();
|
||||||
if (to.meta.requiresAuth) {
|
if (to.meta.requiresAuth) {
|
||||||
const user = useStore().user;
|
const user = useStore().user;
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
router.push('/qrlogin')
|
router.push('/qrlogin')
|
||||||
}" class="login-form-bottom-button" :icon="h(QrcodeOutlined)">{{ t("login.qrLogin") }}
|
}" class="login-form-bottom-button" :icon="h(QrcodeOutlined)">{{ t("login.qrLogin") }}
|
||||||
</AButton>
|
</AButton>
|
||||||
<AButton class="login-form-bottom-button" :icon="h(QqOutlined)"></AButton>
|
<AButton @click="openQQUrl" class="login-form-bottom-button" :icon="h(QqOutlined)"></AButton>
|
||||||
<AButton @click="openGiteeUrl" class="login-form-bottom-button"
|
<AButton @click="openGiteeUrl" class="login-form-bottom-button"
|
||||||
style="display: flex; align-items: center;justify-content: center;">
|
style="display: flex; align-items: center;justify-content: center;">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {GithubOutlined, QqOutlined, QrcodeOutlined} from "@ant-design/icons-vue";
|
import {GithubOutlined, QqOutlined, QrcodeOutlined} from "@ant-design/icons-vue";
|
||||||
import {useI18n} from "vue-i18n";
|
import {useI18n} from "vue-i18n";
|
||||||
import {h, onMounted, ref} from "vue";
|
import {h, onBeforeMount, ref} from "vue";
|
||||||
import {useRouter} from 'vue-router';
|
import {useRouter} from 'vue-router';
|
||||||
import {getGithubUrl} from "@/api/oauth/github.ts";
|
import {getGithubUrl} from "@/api/oauth/github.ts";
|
||||||
import {getGiteeUrl} from "@/api/oauth/gitee.ts";
|
import {getGiteeUrl} from "@/api/oauth/gitee.ts";
|
||||||
@@ -117,6 +117,9 @@ const openGithubUrl = () => {
|
|||||||
user.user.expiresAt = expires_at;
|
user.user.expiresAt = expires_at;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
window.removeEventListener("message", messageHandler);
|
window.removeEventListener("message", messageHandler);
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -146,12 +149,47 @@ const openGiteeUrl = () => {
|
|||||||
user.user.expiresAt = expires_at;
|
user.user.expiresAt = expires_at;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
window.removeEventListener("message", messageHandler);
|
window.removeEventListener("message", messageHandler);
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener("message", messageHandler);
|
window.addEventListener("message", messageHandler);
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
/**
|
||||||
|
* Open the QQ OAuth page in a new window
|
||||||
|
*/
|
||||||
|
const openQQUrl = () => {
|
||||||
|
const iWidth = 800; //弹出窗口的宽度;
|
||||||
|
const iHeight = 500; //弹出窗口的高度;
|
||||||
|
//window.screen.height获得屏幕的高,window.screen.width获得屏幕的宽
|
||||||
|
const iTop = (window.screen.height - 30 - iHeight) / 2; //获得窗口的垂直位置;
|
||||||
|
const iLeft = (window.screen.width - 10 - iWidth) / 2; //获得窗口的水平位置;
|
||||||
|
window.open(qqRedirectUrl.value, 'newwindow', 'height=' + iHeight + ',innerHeight=' + iHeight + ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft + ',toolbar=no,menubar=no,scrollbars=auto,resizable=no,location=no,status=no');
|
||||||
|
|
||||||
|
const messageHandler = (e: any) => {
|
||||||
|
if (typeof e.data === 'string') {
|
||||||
|
const data: any = JSON.parse(e.data);
|
||||||
|
if (data.code === 0 && data.data) {
|
||||||
|
const user = useStore().user;
|
||||||
|
const {access_token, refresh_token, uid, expires_at} = data.data;
|
||||||
|
user.user.accessToken = access_token;
|
||||||
|
user.user.refreshToken = refresh_token;
|
||||||
|
user.user.uid = uid;
|
||||||
|
user.user.expiresAt = expires_at;
|
||||||
|
message.success(t('login.loginSuccess'));
|
||||||
|
window.removeEventListener("message", messageHandler);
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("message", messageHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
getGithubRedirectUrl();
|
getGithubRedirectUrl();
|
||||||
getGiteeRedirectUrl();
|
getGiteeRedirectUrl();
|
||||||
getQQRedirectUrl();
|
getQQRedirectUrl();
|
||||||
|
@@ -355,6 +355,9 @@ async function phoneLoginSubmit() {
|
|||||||
userStore.user.refreshToken = refresh_token;
|
userStore.user.refreshToken = refresh_token;
|
||||||
userStore.user.expiresAt = expires_at;
|
userStore.user.expiresAt = expires_at;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
} else {
|
} else {
|
||||||
message.error(res.message);
|
message.error(res.message);
|
||||||
}
|
}
|
||||||
@@ -433,6 +436,9 @@ async function checkAccountLoginCaptcha(angle: number) {
|
|||||||
userStore.user.refreshToken = refresh_token;
|
userStore.user.refreshToken = refresh_token;
|
||||||
userStore.user.expiresAt = expires_at;
|
userStore.user.expiresAt = expires_at;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
} else {
|
} else {
|
||||||
message.error(t('login.loginError'));
|
message.error(t('login.loginError'));
|
||||||
}
|
}
|
||||||
|
21
src/views/Main/MainPage.vue
Normal file
21
src/views/Main/MainPage.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Welcome to Main Page</h1>
|
||||||
|
<AButton @click="handleClick">获取用户数据</AButton>
|
||||||
|
{{ data }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {useRequest} from "alova/client";
|
||||||
|
import {getUserInfo} from "@/api/user";
|
||||||
|
|
||||||
|
const {data, send} = useRequest(getUserInfo, {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
const handleClick = () => {
|
||||||
|
send();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@@ -138,6 +138,9 @@ onMounted(async () => {
|
|||||||
user.user.expiresAt = expires_at;
|
user.user.expiresAt = expires_at;
|
||||||
status.value = 'scanned';
|
status.value = 'scanned';
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
router.push('/login')
|
router.push('/login')
|
||||||
}" class="qrlogin-form-bottom-button" :icon="h(TabletOutlined)">{{ t("login.phoneLoginAndRegister") }}
|
}" class="qrlogin-form-bottom-button" :icon="h(TabletOutlined)">{{ t("login.phoneLoginAndRegister") }}
|
||||||
</AButton>
|
</AButton>
|
||||||
<AButton class="qrlogin-form-bottom-button" :icon="h(QqOutlined)"></AButton>
|
<AButton @click="openQQUrl" class="qrlogin-form-bottom-button" :icon="h(QqOutlined)"></AButton>
|
||||||
<AButton @click="openGiteeUrl" class="qrlogin-form-bottom-button"
|
<AButton @click="openGiteeUrl" class="qrlogin-form-bottom-button"
|
||||||
style="display: flex; align-items: center;justify-content: center;">
|
style="display: flex; align-items: center;justify-content: center;">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {GithubOutlined, QqOutlined, TabletOutlined} from "@ant-design/icons-vue";
|
import {GithubOutlined, QqOutlined, TabletOutlined} from "@ant-design/icons-vue";
|
||||||
import {useI18n} from "vue-i18n";
|
import {useI18n} from "vue-i18n";
|
||||||
import {h, onMounted, ref} from "vue";
|
import {h, onBeforeMount, ref} from "vue";
|
||||||
import {useRouter} from 'vue-router';
|
import {useRouter} from 'vue-router';
|
||||||
import {getGithubUrl} from "@/api/oauth/github.ts";
|
import {getGithubUrl} from "@/api/oauth/github.ts";
|
||||||
import {getGiteeUrl} from "@/api/oauth/gitee.ts";
|
import {getGiteeUrl} from "@/api/oauth/gitee.ts";
|
||||||
@@ -118,6 +118,9 @@ const openGithubUrl = () => {
|
|||||||
user.user.expiresAt = expires_at;
|
user.user.expiresAt = expires_at;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
window.removeEventListener("message", messageHandler);
|
window.removeEventListener("message", messageHandler);
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -147,12 +150,48 @@ const openGiteeUrl = () => {
|
|||||||
user.user.expiresAt = expires_at;
|
user.user.expiresAt = expires_at;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
window.removeEventListener("message", messageHandler);
|
window.removeEventListener("message", messageHandler);
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener("message", messageHandler);
|
window.addEventListener("message", messageHandler);
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the QQ OAuth page in a new window
|
||||||
|
*/
|
||||||
|
const openQQUrl = () => {
|
||||||
|
const iWidth = 800; //弹出窗口的宽度;
|
||||||
|
const iHeight = 500; //弹出窗口的高度;
|
||||||
|
//window.screen.height获得屏幕的高,window.screen.width获得屏幕的宽
|
||||||
|
const iTop = (window.screen.height - 30 - iHeight) / 2; //获得窗口的垂直位置;
|
||||||
|
const iLeft = (window.screen.width - 10 - iWidth) / 2; //获得窗口的水平位置;
|
||||||
|
window.open(qqRedirectUrl.value, 'newwindow', 'height=' + iHeight + ',innerHeight=' + iHeight + ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft + ',toolbar=no,menubar=no,scrollbars=auto,resizable=no,location=no,status=no');
|
||||||
|
|
||||||
|
const messageHandler = (e: any) => {
|
||||||
|
if (typeof e.data === 'string') {
|
||||||
|
const data: any = JSON.parse(e.data);
|
||||||
|
if (data.code === 0 && data.data) {
|
||||||
|
const user = useStore().user;
|
||||||
|
const {access_token, refresh_token, uid, expires_at} = data.data;
|
||||||
|
user.user.accessToken = access_token;
|
||||||
|
user.user.refreshToken = refresh_token;
|
||||||
|
user.user.uid = uid;
|
||||||
|
user.user.expiresAt = expires_at;
|
||||||
|
message.success(t('login.loginSuccess'));
|
||||||
|
window.removeEventListener("message", messageHandler);
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push('/main');
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("message", messageHandler);
|
||||||
|
};
|
||||||
|
onBeforeMount(() => {
|
||||||
getGithubRedirectUrl();
|
getGithubRedirectUrl();
|
||||||
getGiteeRedirectUrl();
|
getGiteeRedirectUrl();
|
||||||
getQQRedirectUrl();
|
getQQRedirectUrl();
|
||||||
|
@@ -1,43 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="test">
|
|
||||||
<AButton @click="handleClick"> {{ t('login.title') }}</AButton>
|
|
||||||
<AButton @click="changeLang('zh')"> 切换中文</AButton>
|
|
||||||
<AButton @click="changeLang('en')"> 切换英文</AButton>
|
|
||||||
|
|
||||||
<ADatePicker/>
|
|
||||||
<ATimePicker/>
|
|
||||||
{{ data }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script setup lang="ts">
|
|
||||||
import {useRequest} from "alova/client";
|
|
||||||
import {getUserInfo} from "@/api/user";
|
|
||||||
import {useI18n} from "vue-i18n";
|
|
||||||
import useStore from "@/store";
|
|
||||||
|
|
||||||
const {t, locale} = useI18n();
|
|
||||||
const {data, send} = useRequest(getUserInfo, {
|
|
||||||
immediate: false
|
|
||||||
});
|
|
||||||
const handleClick = () => {
|
|
||||||
send();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const lang = useStore().lang;
|
|
||||||
|
|
||||||
async function changeLang(language: any) {
|
|
||||||
lang.lang = language;
|
|
||||||
locale.value = language;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import "@/assets/styles/theme.scss";
|
|
||||||
|
|
||||||
.test {
|
|
||||||
@include useTheme {
|
|
||||||
background: getModeVar('primary');
|
|
||||||
color: getColor('info');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
Reference in New Issue
Block a user