feat: 登录接口对接
This commit is contained in:
10
global.d.ts
vendored
10
global.d.ts
vendored
@@ -88,6 +88,16 @@ declare global {
|
|||||||
|
|
||||||
type ThemeMode = 'dark' | 'light' | 'system';
|
type ThemeMode = 'dark' | 'light' | 'system';
|
||||||
|
|
||||||
|
// form 表单数据类型声明
|
||||||
|
interface LoginForm {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
randomStr: string;
|
||||||
|
code: string;
|
||||||
|
grant_type: string;
|
||||||
|
scope: string;
|
||||||
|
}
|
||||||
|
|
||||||
// 弹窗类型定义
|
// 弹窗类型定义
|
||||||
interface CreateDialogProps {
|
interface CreateDialogProps {
|
||||||
winId?: string;
|
winId?: string;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const api: WindowApi = {
|
|||||||
minimizeWindow: () => ipcRenderer.send(IPC_EVENTS.WINDOW_MINIMIZE),
|
minimizeWindow: () => ipcRenderer.send(IPC_EVENTS.WINDOW_MINIMIZE),
|
||||||
maximizeWindow: () => ipcRenderer.send(IPC_EVENTS.WINDOW_MAXIMIZE),
|
maximizeWindow: () => ipcRenderer.send(IPC_EVENTS.WINDOW_MAXIMIZE),
|
||||||
onWindowMaximized: (callback: (isMaximized: boolean) => void) => ipcRenderer.on(IPC_EVENTS.WINDOW_MAXIMIZE + 'back', (_, isMaximized) => callback(isMaximized)),
|
onWindowMaximized: (callback: (isMaximized: boolean) => void) => ipcRenderer.on(IPC_EVENTS.WINDOW_MAXIMIZE + 'back', (_, isMaximized) => callback(isMaximized)),
|
||||||
isWindowMaximized: () => ipcRenderer.invoke(IPC_EVENTS.WINDOW_MAXIMIZE),
|
isWindowMaximized: () => ipcRenderer.invoke(IPC_EVENTS.IS_WINDOW_MAXIMIZED),
|
||||||
viewIsReady: () => ipcRenderer.send(IPC_EVENTS.RENDERER_IS_READY),
|
viewIsReady: () => ipcRenderer.send(IPC_EVENTS.RENDERER_IS_READY),
|
||||||
|
|
||||||
app: {
|
app: {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { createApp, type Plugin } from "vue";
|
import { createApp, type Plugin } from "vue"
|
||||||
import { createPinia } from "pinia";
|
import { createPinia } from "pinia"
|
||||||
import router from "./router";
|
import errorHandler from "@utils/errorHandler"
|
||||||
import App from "./App.vue";
|
import router from "./router"
|
||||||
|
import App from "./App.vue"
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import locale from 'element-plus/es/locale/lang/zh-cn'
|
import locale from 'element-plus/es/locale/lang/zh-cn'
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
@@ -30,6 +31,7 @@ app.use(router);
|
|||||||
app.use(ElementPlus, { locale })
|
app.use(ElementPlus, { locale })
|
||||||
app.use(components)
|
app.use(components)
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
|
app.use(errorHandler)
|
||||||
|
|
||||||
// 挂载应用到 DOM
|
// 挂载应用到 DOM
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ router.beforeEach((to: any, _from: any, next: any) => {
|
|||||||
} else if (isWhiteList(to.path)) {
|
} else if (isWhiteList(to.path)) {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no token
|
// no token
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import { defineStore } from 'pinia'
|
|
||||||
import { ref, computed } from 'vue'
|
|
||||||
|
|
||||||
export const useCounterStore = defineStore('counter', () => {
|
|
||||||
const count = ref(0)
|
|
||||||
|
|
||||||
const doubleCount = computed(() => count.value * 2)
|
|
||||||
|
|
||||||
function increment() {
|
|
||||||
count.value++
|
|
||||||
}
|
|
||||||
|
|
||||||
function decrement() {
|
|
||||||
count.value--
|
|
||||||
}
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
count.value = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return { count, doubleCount, increment, decrement, reset }
|
|
||||||
})
|
|
||||||
50
src/renderer/store/userinfo.ts
Normal file
50
src/renderer/store/userinfo.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { authOauth2TokenUsingPost } from "@renderer/api"
|
||||||
|
import { getToken, setToken, removeToken } from '@utils/auth'
|
||||||
|
|
||||||
|
export const useUserStore = defineStore('userInfo', {
|
||||||
|
state: () => ({
|
||||||
|
token: getToken(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
/**
|
||||||
|
* 登录方法
|
||||||
|
* @function login
|
||||||
|
* @async
|
||||||
|
* @param {Object} data - 登录数据
|
||||||
|
* @returns {Promise<Object>}
|
||||||
|
*/
|
||||||
|
async login(data: LoginForm) {
|
||||||
|
data.grant_type = 'password';
|
||||||
|
data.scope = 'server';
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
authOauth2TokenUsingPost({body: {...data, clientId: ''}})
|
||||||
|
.then((res: any) => {
|
||||||
|
// 存储token 信息
|
||||||
|
setToken(res.access_token)
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 退出系统
|
||||||
|
logOut() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// logout(this.token).then(() => {
|
||||||
|
// this.token = ''
|
||||||
|
// this.roles = []
|
||||||
|
// this.permissions = []
|
||||||
|
// removeToken()
|
||||||
|
// resolve()
|
||||||
|
// }).catch(error => {
|
||||||
|
// reject(error)
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import type { Plugin } from 'vue'
|
import type { Plugin } from 'vue'
|
||||||
import logger from './logger'
|
import logger from './logger'
|
||||||
|
|
||||||
export const errorHandler: Plugin = (app) => {
|
export const errorHandler: Plugin = (app) => {
|
||||||
app.config.errorHandler = (err, instance, info) => {
|
app.config.errorHandler = (err, instance, info) => {
|
||||||
logger.error('Vue error:', err, instance, info);
|
// 过滤掉无法序列化的 Vue 实例对象
|
||||||
|
logger.error('Vue error:', err, info);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.onerror = (message, source, lineno, colno, error) => {
|
window.onerror = (message, source, lineno, colno, error) => {
|
||||||
|
|||||||
@@ -1,5 +1,67 @@
|
|||||||
|
const safeStringify = (arg: any) => {
|
||||||
|
try {
|
||||||
|
// 处理 Error 对象
|
||||||
|
if (arg instanceof Error) {
|
||||||
|
return {
|
||||||
|
message: arg.message,
|
||||||
|
stack: arg.stack,
|
||||||
|
name: arg.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 简单值直接返回
|
||||||
|
if (typeof arg !== 'object' || arg === null) {
|
||||||
|
return arg
|
||||||
|
}
|
||||||
|
// 处理 Vue 响应式对象(Proxy)
|
||||||
|
if (arg?.__v_isRef || arg?.__v_isReactive || arg?.__v_isReadonly) {
|
||||||
|
// 尝试解包 Proxy/Ref
|
||||||
|
try {
|
||||||
|
const raw = JSON.parse(JSON.stringify(arg))
|
||||||
|
return raw
|
||||||
|
} catch (e) {
|
||||||
|
return '[Vue Reactive Object]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 尝试深拷贝,如果失败则说明包含不可序列化对象
|
||||||
|
const raw = JSON.parse(JSON.stringify(arg))
|
||||||
|
return raw
|
||||||
|
} catch (e) {
|
||||||
|
// 序列化失败,返回字符串描述
|
||||||
|
return String(arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const logger = window.api.logger ?? console;
|
// 缓存原始 console 方法,防止递归调用和保持控制台输出
|
||||||
|
const originalConsole = {
|
||||||
|
debug: console.debug.bind(console),
|
||||||
|
log: console.log.bind(console),
|
||||||
|
info: console.info.bind(console),
|
||||||
|
warn: console.warn.bind(console),
|
||||||
|
error: console.error.bind(console),
|
||||||
|
}
|
||||||
|
|
||||||
|
const createSafeLogger = (originalLogger: any) => {
|
||||||
|
return {
|
||||||
|
debug: (message: string, ...meta: any[]) => {
|
||||||
|
originalConsole.debug(message, ...meta)
|
||||||
|
originalLogger.debug(String(message), ...meta.map(safeStringify))
|
||||||
|
},
|
||||||
|
info: (message: string, ...meta: any[]) => {
|
||||||
|
originalConsole.info(message, ...meta)
|
||||||
|
originalLogger.info(String(message), ...meta.map(safeStringify))
|
||||||
|
},
|
||||||
|
warn: (message: string, ...meta: any[]) => {
|
||||||
|
originalConsole.warn(message, ...meta)
|
||||||
|
originalLogger.warn(String(message), ...meta.map(safeStringify))
|
||||||
|
},
|
||||||
|
error: (message: string, ...meta: any[]) => {
|
||||||
|
originalConsole.error(message, ...meta)
|
||||||
|
originalLogger.error(String(message), ...meta.map(safeStringify))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const logger = window.api.logger ? createSafeLogger(window.api.logger) : console
|
||||||
|
|
||||||
if (window.api.logger) {
|
if (window.api.logger) {
|
||||||
console.debug = logger.debug;
|
console.debug = logger.debug;
|
||||||
|
|||||||
@@ -58,19 +58,20 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 登录按钮 -->
|
<!-- 登录按钮 -->
|
||||||
<button class="w-full py-2 bg-blue-600 text-white rounded-[8px] hover:bg-blue-700 disabled:bg-blue-300"
|
<button type="button"
|
||||||
@click="onSubmit">
|
class="w-full py-2 bg-blue-600 cursor-pointer text-white rounded-[8px] hover:bg-blue-700 disabled:bg-blue-300"
|
||||||
{{ loading ? '登录中…' : '登录' }}
|
:loading="loading" @click="onSubmit">
|
||||||
|
登 录
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- 同意协议 -->
|
<!-- 同意协议 -->
|
||||||
<div class="flex items-center justify-center gap-2 mt-[24px]">
|
<!-- <div class="flex items-center justify-center gap-2 mt-[24px]">
|
||||||
<input type="checkbox" v-model="isAgree" class="w-[14px] h-[14px] rounded-[4px]" />
|
<input type="checkbox" v-model="isAgree" class="w-[14px] h-[14px] rounded-[4px]" />
|
||||||
<span class="text-[14px] text-gray-600">我已同意</span>
|
<span class="text-[14px] text-gray-600">我已同意</span>
|
||||||
<span class="text-[14px] text-sky-600 cursor-pointer">《使用协议》</span>
|
<span class="text-[14px] text-sky-600 cursor-pointer">《使用协议》</span>
|
||||||
<span class="text-[14px] text-gray-600">和</span>
|
<span class="text-[14px] text-gray-600">和</span>
|
||||||
<span class="text-[14px] text-sky-600 cursor-pointer">《隐私协议》</span>
|
<span class="text-[14px] text-sky-600 cursor-pointer">《隐私协议》</span>
|
||||||
</div>
|
</div> -->
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- Copy Right -->
|
<!-- Copy Right -->
|
||||||
@@ -81,27 +82,17 @@
|
|||||||
|
|
||||||
<img class="w-[540px]" src="@assets/images/login/logo.png" />
|
<img class="w-[540px]" src="@assets/images/login/logo.png" />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { authOauth2TokenUsingPost } from "@renderer/api";
|
import { useUserStore } from "@renderer/store/userinfo"
|
||||||
import { RiUser3Fill, RiKey2Fill } from '@remixicon/vue'
|
import { RiUser3Fill, RiKey2Fill } from '@remixicon/vue'
|
||||||
import { generateUUID } from "@utils/generateUUID";
|
import { generateUUID } from "@utils/generateUUID"
|
||||||
import { rule } from '@utils/validate'
|
import { rule } from '@utils/validate'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
// form 表单数据类型声明
|
const form = reactive<LoginForm>({ username: "", password: "", randomStr: '', code: "", grant_type: '', scope: '' });
|
||||||
interface LoginForm {
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
randomStr: string;
|
|
||||||
code: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const form = reactive<LoginForm>({ username: "", password: "", randomStr: '', code: "" });
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const showPwd = ref(false);
|
const showPwd = ref(false);
|
||||||
const isAgree = ref(false);
|
const isAgree = ref(false);
|
||||||
@@ -130,13 +121,10 @@ const onSubmit = async () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// localStorage.setItem("token", "dev-token");
|
userStore.login(form).then(() => {
|
||||||
// const res: any = await authOauth2TokenUsingPost({ body: form });
|
// window.location.href = 'index.html'
|
||||||
// const token = res && (res.token || res.data?.token || res.access_token);
|
console.log(form)
|
||||||
// if (!token) throw new Error("登录失败");
|
})
|
||||||
// localStorage.setItem("token", token);
|
|
||||||
// await (window as any).api.app.setFrameless('/home')
|
|
||||||
router.push('/home');
|
|
||||||
} finally {
|
} finally {
|
||||||
getVerifyCode()
|
getVerifyCode()
|
||||||
loading.value = false; // 登录结束
|
loading.value = false; // 登录结束
|
||||||
|
|||||||
Reference in New Issue
Block a user