From 593e5dd6702909388263225e07f6bc801c8febe0 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Sun, 28 Dec 2025 16:31:57 +0800 Subject: [PATCH] feat: add login kv by web --- packages/kv-login/package.json | 6 +- packages/kv-login/src/modules/login-handle.ts | 22 +++++- packages/kv-login/src/pages/kv-login.ts | 37 ++++++---- pnpm-lock.yaml | 67 +++++++++++++++++++ 4 files changed, 117 insertions(+), 15 deletions(-) diff --git a/packages/kv-login/package.json b/packages/kv-login/package.json index 51a7b64..c3d31d7 100644 --- a/packages/kv-login/package.json +++ b/packages/kv-login/package.json @@ -19,7 +19,7 @@ ], "author": "abearxiong (https://www.xiongxiao.me)", "license": "MIT", - "packageManager": "pnpm@10.24.0", + "packageManager": "pnpm@10.26.2", "publishConfig": { "access": "public" }, @@ -27,7 +27,8 @@ "dependencies": { "@kevisual/context": "^0.0.4", "@kevisual/query-login": "^0.0.7", - "lit-html": "^3.3.1", + "crypto-js": "^4.2.0", + "lit-html": "^3.3.2", "qrcode": "^1.5.4" }, "exports": { @@ -36,6 +37,7 @@ }, "types": "./types/index.d.ts", "devDependencies": { + "@kevisual/api": "^0.0.8", "@types/bun": "^1.3.5" } } \ No newline at end of file diff --git a/packages/kv-login/src/modules/login-handle.ts b/packages/kv-login/src/modules/login-handle.ts index b5ac59f..359ecab 100644 --- a/packages/kv-login/src/modules/login-handle.ts +++ b/packages/kv-login/src/modules/login-handle.ts @@ -2,9 +2,11 @@ import { query } from './query.ts'; import { createMessage } from '../pages/kv-message.ts'; import { WX_MP_APP_ID } from '../pages/kv-login.ts'; import { emit } from './mitt.ts'; +import { Query } from '@kevisual/query'; +import { QueryLoginBrowser } from '@kevisual/api/login' export const message = createMessage(); type LoginOpts = { - loginMethod: 'password' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket', + loginMethod: 'password' | 'web' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket', data: any, el: HTMLElement } @@ -40,10 +42,28 @@ export const loginHandle = async (opts: LoginOpts) => { case 'wechat': await loginByWeChat(data) break + case 'web': + await loginByWeb(data) + break default: console.warn('未知的登录方式:', loginMethod) } } +const loginByWeb = async (data: {}) => { + const url = new URL("https://kevisual.cn/api/router"); + const query = new Query({ url: "https://kevisual.cn/api/router" }) + const login = new QueryLoginBrowser({ query }) + // @ts-ignore + const res = login.loginWithWeb(url.origin, {}) + console.log('打开网页登录:', res) + window.open(res.url, '_blank'); + const status = await login.pollLoginStatus(res); + if (status) { + redirectHome() + } else { + message.error('网页登录失败,请重试') + } +} /** * 使用用户名和密码登录 * @param data diff --git a/packages/kv-login/src/pages/kv-login.ts b/packages/kv-login/src/pages/kv-login.ts index 4044627..2632e14 100644 --- a/packages/kv-login/src/pages/kv-login.ts +++ b/packages/kv-login/src/pages/kv-login.ts @@ -1,10 +1,11 @@ import { render, html } from 'lit-html' import { unsafeHTML } from 'lit-html/directives/unsafe-html.js' -import { loginHandle, checkWechat, getQrCode, checkMpQrCodeLogin } from '../modules/login-handle.ts' +import { loginHandle, checkWechat, getQrCode, checkMpQrCodeLogin, redirectHome } from '../modules/login-handle.ts' import { setWxerwma } from '../modules/wx/ws-login.ts'; import { useCreateLoginQRCode } from '../modules/wx-mp/qr.ts'; import { eventEmitter } from '../modules/mitt.ts'; import { useContextKey } from '@kevisual/context' + export const loginEmitter = useContextKey('login-emitter', eventEmitter); export const WX_MP_APP_ID = "wxff97d569b1db16b6"; interface LoginMethod { @@ -17,29 +18,31 @@ const wxmpSvg = `` const phone = `` const pwd = `` - +const web = `` const icons: any = { pwd, + web, phone, wxmpSvg, wxOpenSvg } const DefaultLoginMethods: LoginMethod[] = [ { id: 'password', name: '密码登录', icon: 'pwd' }, + { id: 'web', name: '网页登录', icon: 'web' }, { id: 'wechat', name: '微信登录', icon: 'wxmpSvg', appid: "wx9378885c8390e09b" }, { id: 'wechat-mp', name: '微信公众号', icon: 'wxOpenSvg', appid: WX_MP_APP_ID }, { id: 'wechat-mp-ticket', name: '微信公众号', icon: 'wxOpenSvg' }, { id: 'phone', name: '手机号登录', icon: 'phone' } ] -const LoginMethods = ['password', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket'] as const; -type LoginMethods = 'password' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket'; +const LoginMethods = ['password', 'web', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket'] as const; +type LoginMethods = 'password' | 'web' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket'; const getLoginMethodByDomain = (): LoginMethod[] => { let domain = window.location.host let methods: LoginMethods[] = [] - const has51015 = domain.includes('51015'); - if (has51015) { - domain = 'localhost:51015' + const has51 = domain.includes('localhost') && (domain.endsWith('51515') || domain.endsWith('51015')); + if (has51) { + domain = 'localhost' } switch (domain) { case 'kevisual.xiongxiao.me': @@ -48,11 +51,11 @@ const getLoginMethodByDomain = (): LoginMethod[] => { case 'kevisual.cn': methods = ['password', 'wechat-mp-ticket', 'wechat',] break; - case 'localhost:51015': - methods = ['password'] + case 'localhost': + methods = ['password', 'web'] break default: - methods = ['password', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket'] + methods = ['password', 'web', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket'] break; } return DefaultLoginMethods.filter(method => methods.includes(method.id)) @@ -161,7 +164,8 @@ class KvLogin extends HTMLElement { username: username?.value || '', password: password?.value || '' } - + case 'web': + return {} case 'phone': const phone = this.shadowRoot.querySelector('#phone') as HTMLInputElement const code = this.shadowRoot.querySelector('#code') as HTMLInputElement @@ -210,7 +214,14 @@ class KvLogin extends HTMLElement { ` } - + private renderWebForm() { + return html` + + ` + } private renderPhoneForm() { return html`