diff --git a/components.d.ts b/components.d.ts index 585e5bd..a9f9b8a 100644 --- a/components.d.ts +++ b/components.d.ts @@ -15,14 +15,18 @@ declare module 'vue' { NButton: typeof import('naive-ui')['NButton'] NCard: typeof import('naive-ui')['NCard'] NCode: typeof import('naive-ui')['NCode'] + NCollapse: typeof import('naive-ui')['NCollapse'] + NCollapseItem: typeof import('naive-ui')['NCollapseItem'] NDivider: typeof import('naive-ui')['NDivider'] NDrawer: typeof import('naive-ui')['NDrawer'] NDrawerContent: typeof import('naive-ui')['NDrawerContent'] NEl: typeof import('naive-ui')['NEl'] + NEllipsis: typeof import('naive-ui')['NEllipsis'] NEmpty: typeof import('naive-ui')['NEmpty'] NForm: typeof import('naive-ui')['NForm'] NFormItem: typeof import('naive-ui')['NFormItem'] NGi: typeof import('naive-ui')['NGi'] + NGradientText: typeof import('naive-ui')['NGradientText'] NGrid: typeof import('naive-ui')['NGrid'] NGridItem: typeof import('naive-ui')['NGridItem'] NH1: typeof import('naive-ui')['NH1'] @@ -31,33 +35,38 @@ declare module 'vue' { NH4: typeof import('naive-ui')['NH4'] NH5: typeof import('naive-ui')['NH5'] NIcon: typeof import('naive-ui')['NIcon'] + NImage: typeof import('naive-ui')['NImage'] NInput: typeof import('naive-ui')['NInput'] NLayout: typeof import('naive-ui')['NLayout'] NLayoutContent: typeof import('naive-ui')['NLayoutContent'] NLayoutHeader: typeof import('naive-ui')['NLayoutHeader'] NLayoutSider: typeof import('naive-ui')['NLayoutSider'] + NLi: typeof import('naive-ui')['NLi'] NList: typeof import('naive-ui')['NList'] NListItem: typeof import('naive-ui')['NListItem'] NMenu: typeof import('naive-ui')['NMenu'] NModal: typeof import('naive-ui')['NModal'] NNumberAnimation: typeof import('naive-ui')['NNumberAnimation'] NP: typeof import('naive-ui')['NP'] + NQrCode: typeof import('naive-ui')['NQrCode'] + NRadio: typeof import('naive-ui')['NRadio'] NRadioButton: typeof import('naive-ui')['NRadioButton'] NRadioGroup: typeof import('naive-ui')['NRadioGroup'] NScrollbar: typeof import('naive-ui')['NScrollbar'] NSelect: typeof import('naive-ui')['NSelect'] + NSkeleton: typeof import('naive-ui')['NSkeleton'] NSpace: typeof import('naive-ui')['NSpace'] NSpin: typeof import('naive-ui')['NSpin'] NStatistic: typeof import('naive-ui')['NStatistic'] NStep: typeof import('naive-ui')['NStep'] NSteps: typeof import('naive-ui')['NSteps'] - NTab: typeof import('naive-ui')['NTab'] NTabPane: typeof import('naive-ui')['NTabPane'] NTabs: typeof import('naive-ui')['NTabs'] NTag: typeof import('naive-ui')['NTag'] NText: typeof import('naive-ui')['NText'] NThing: typeof import('naive-ui')['NThing'] NTooltip: typeof import('naive-ui')['NTooltip'] + NUl: typeof import('naive-ui')['NUl'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] TheDialog: typeof import('./src/components/TheDialog.vue')['default'] diff --git a/package.json b/package.json index 670f628..1cd6130 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "format": "prettier --write src/" }, "dependencies": { + "@chongying-star/vaptcha-typescript": "^1.1.0", + "@chongying-star/vue-vaptcha": "^1.0.0-beta.1", "@vicons/carbon": "^0.13.0", "@vicons/fa": "^0.12.0", "@vicons/fluent": "^0.12.0", @@ -56,7 +58,7 @@ "naive-ui": "2.38.2", "vfonts": "^0.1.0", "typescript": "~5.6.3", - "vite": "^6.0.5", + "vite": "^6.0.7", "vite-plugin-vue-devtools": "^7.6.8", "vue-tsc": "^2.1.10" } diff --git a/src/api/v2/auth/login.api.ts b/src/api/v2/auth/login.api.ts index 5dd35d5..fd30e4f 100644 --- a/src/api/v2/auth/login.api.ts +++ b/src/api/v2/auth/login.api.ts @@ -2,11 +2,19 @@ import { post } from '@/utils/request' import base from '@/api/base' -const login = async (username: number, password: string, captcha_response_token: string) => { +const login = async ( + username: number, + password: string, + captcha_id: string, + captcha_token: string, + captcha_server: string | undefined +) => { const rs = post(`${base.api_v2_url}/auth/login`, { username: username, password: password, - captcha_response_token: captcha_response_token + captcha_id: captcha_id, + captcha_token: captcha_token, + captcha_server: captcha_server }) return base.buildResponse(await rs) } diff --git a/src/api/v2/captcha.api.ts b/src/api/v2/captcha.api.ts new file mode 100644 index 0000000..c7648a8 --- /dev/null +++ b/src/api/v2/captcha.api.ts @@ -0,0 +1,12 @@ +import base from '@/api/base' +//@ts-ignore +import { get, post } from '@/utils/request' + +const captcha = async (action: string) => { + const rs = get(`${base.api_v2_url}/captcha`, { + action: action + }) + return base.buildResponse(await rs) +} + +export default captcha diff --git a/src/api/v2/index.ts b/src/api/v2/index.ts index aee516d..04598f0 100644 --- a/src/api/v2/index.ts +++ b/src/api/v2/index.ts @@ -10,6 +10,7 @@ import email from './email' import notice from './notice' import minecraft from './minecraft' import app from './app' +import captcha from './captcha.api' export default { user: user, @@ -23,5 +24,6 @@ export default { icp: icp, notice: notice, minecraft: minecraft, - app: app + app: app, + captcha: captcha } diff --git a/src/views/auth/LoginView.vue b/src/views/auth/LoginView.vue index 0d73af7..56da351 100644 --- a/src/views/auth/LoginView.vue +++ b/src/views/auth/LoginView.vue @@ -15,7 +15,7 @@ type="text" v-model:value="model.username" placeholder="用户名" - @keyup.enter="showTurnstile = true" + @keyup.enter="loadCaptcha" /> @@ -23,7 +23,7 @@ type="password" v-model:value="model.password" placeholder="密码" - @keyup.enter="showTurnstile = true" + @keyup.enter="loadCaptcha" />
@@ -43,7 +43,7 @@ > 没有账户?去注册 - 登录 + 登录 + + +
@@ -94,7 +108,10 @@ import Notification from '@/utils/notification' import logger from '@/utils/logger' import api from '@/api' import { getUrlKey } from '@/utils/request' + import VueTurnstile from 'vue-turnstile' +import '@chongying-star/vue-vaptcha/style.css' +import { VaptchaButton } from '@chongying-star/vue-vaptcha' const message = new Message() const notification = new Notification() @@ -104,8 +121,13 @@ const ldb = useLoadingBar() const qqLoginLoading = ref(false) // const oauthLogin_loading = ref(false) -let token = ref('') -let showTurnstile = ref(false) +let captchaPreData, + showTurnstile = ref(false), + showVAPTCHA = ref(false) +let turnstileToken = ref('') +let vaptchaToken = ref(''), + vaptchaServer = ref(''), + vaptchaScene = 0 const model = ref([ { @@ -122,13 +144,67 @@ if (redirectQuery !== null) { logger.info('Redirect after login: ' + redirect) } -watch(token, (newToken, _) => { +watch(turnstileToken, (newToken, _) => { showTurnstile.value = false - login(newToken) + login({ + id: captchaPreData.id, + token: newToken + }) +}) +watch(vaptchaToken, (newToken, _) => { + showVAPTCHA.value = false + login({ + id: captchaPreData.id, + token: newToken, + server: vaptchaServer.value + }) }) +let vaptchaInserted = false + +async function loadCaptcha() { + ldb.start() + let rs + try { + rs = await api.v2.captcha('login') + } catch (e) { + message.error('请求验证码数据失败:' + e) + logger.error(e) + ldb.error() + } + if (rs.status === 200) { + captchaPreData = { + id: rs.data.id, + type: rs.data.type + } + console.log(captchaPreData) + switch (rs.data.type) { + case 'turnstile': + showTurnstile.value = true + break + case 'vaptcha': + if (!vaptchaInserted) { + const script = document.createElement('script') + script.src = 'https://v-cn.vaptcha.com/v3.js' + document.head.appendChild(script) + script.onload = () => { + showVAPTCHA.value = true + } + vaptchaInserted = true + } else showVAPTCHA.value = true + break + default: + message.error('后端返回数据错误') + ldb.error() + } + } else { + message.error(rs.message) + ldb.error() + } +} + // 登录 -async function login(turnstileToken) { +async function login(captchaData) { ldb.start() if ( model.value.username === null || @@ -142,7 +218,13 @@ async function login(turnstileToken) { } let rs try { - rs = await api.v2.auth.login(model.value.username, model.value.password, turnstileToken) + rs = await api.v2.auth.login( + model.value.username, + model.value.password, + captchaData.id, + captchaData.token, + captchaData.server + ) } catch (e) { message.error('请求失败: ' + e) }