feature/zoujing #5
11
global.d.ts
vendored
11
global.d.ts
vendored
@@ -73,17 +73,6 @@ declare global {
|
|||||||
setFrameless: (route?: string) => Promise<void>,
|
setFrameless: (route?: string) => Promise<void>,
|
||||||
loadPage: (page: string) => Promise<void>
|
loadPage: (page: string) => Promise<void>
|
||||||
},
|
},
|
||||||
tabs: {
|
|
||||||
create: (url?: string) => Promise<TabInfo>,
|
|
||||||
list: () => Promise<TabInfo[]>,
|
|
||||||
navigate: (tabId: string, url: string) => Promise<void>,
|
|
||||||
reload: (tabId: string) => Promise<void>,
|
|
||||||
back: (tabId: string) => Promise<void>,
|
|
||||||
forward: (tabId: string) => Promise<void>,
|
|
||||||
switch: (tabId: string) => Promise<void>,
|
|
||||||
close: (tabId: string) => Promise<void>,
|
|
||||||
on: (event: 'tab-updated' | 'tab-created' | 'tab-closed' | 'tab-switched', handler: (payload: any) => void) => () => void
|
|
||||||
},
|
|
||||||
readFile: (filePath: string) => Promise<{success: boolean, data?: string, error?: string}>,
|
readFile: (filePath: string) => Promise<{success: boolean, data?: string, error?: string}>,
|
||||||
logger: {
|
logger: {
|
||||||
debug: (message: string, ...meta?: any[]) => void;
|
debug: (message: string, ...meta?: any[]) => void;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { app, BrowserWindow } from 'electron'
|
import { app, BrowserWindow } from 'electron'
|
||||||
import { CONFIG_KEYS } from '@common/constants'
|
import { CONFIG_KEYS } from '@common/constants'
|
||||||
|
import { setupMainWindow } from './wins';
|
||||||
import started from 'electron-squirrel-startup'
|
import started from 'electron-squirrel-startup'
|
||||||
import configManager from '@main/service/config-service'
|
import configManager from '@main/service/config-service'
|
||||||
import logManager from '@main/service/logger'
|
import logManager from '@main/service/logger'
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
||||||
if (started) {
|
if (started) {
|
||||||
@@ -18,32 +18,8 @@ process.on('unhandledRejection', (reason, promise) => {
|
|||||||
logManager.error('unhandledRejection', reason, promise);
|
logManager.error('unhandledRejection', reason, promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
const createWindow = () => {
|
|
||||||
// Create the browser window.
|
|
||||||
const mainWindow = new BrowserWindow({
|
|
||||||
width: 1920,
|
|
||||||
height: 1080,
|
|
||||||
autoHideMenuBar: true,
|
|
||||||
webPreferences: {
|
|
||||||
preload: path.join(__dirname, "preload.js"),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// and load the index.html of the app.
|
|
||||||
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
|
||||||
mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL);
|
|
||||||
} else {
|
|
||||||
mainWindow.loadFile(
|
|
||||||
path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the DevTools.
|
|
||||||
mainWindow.webContents.openDevTools();
|
|
||||||
};
|
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
createWindow();
|
setupMainWindow();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Quit when all windows are closed, except on macOS. There, it's common
|
// Quit when all windows are closed, except on macOS. There, it's common
|
||||||
@@ -60,6 +36,6 @@ app.on('window-all-closed', () => {
|
|||||||
// dock icon is clicked and there are no other windows open.
|
// dock icon is clicked and there are no other windows open.
|
||||||
app.on('activate', () => {
|
app.on('activate', () => {
|
||||||
if (BrowserWindow.getAllWindows().length === 0) {
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
createWindow();
|
setupMainWindow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -219,9 +219,9 @@ class WindowService {
|
|||||||
|
|
||||||
private _loadPage(window: BrowserWindow, pageName: string) {
|
private _loadPage(window: BrowserWindow, pageName: string) {
|
||||||
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
||||||
return window.loadURL(`${MAIN_WINDOW_VITE_DEV_SERVER_URL}/html/${pageName}.html`);
|
return window.loadURL(`${MAIN_WINDOW_VITE_DEV_SERVER_URL}/${pageName}.html`);
|
||||||
}
|
}
|
||||||
window.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/html/${pageName}.html`));
|
window.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/${pageName}.html`));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _loadWindowTemplate(window: BrowserWindow, name: WindowNames) {
|
private _loadWindowTemplate(window: BrowserWindow, name: WindowNames) {
|
||||||
|
|||||||
162
src/main/wins/index.ts
Normal file
162
src/main/wins/index.ts
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
import type { BrowserWindow } from 'electron'
|
||||||
|
import { ipcMain } from 'electron';
|
||||||
|
import { WINDOW_NAMES, MAIN_WIN_SIZE, IPC_EVENTS, MENU_IDS, CONVERSATION_ITEM_MENU_IDS, CONVERSATION_LIST_MENU_IDS, MESSAGE_ITEM_MENU_IDS, CONFIG_KEYS } from '@common/constants'
|
||||||
|
import { createProvider } from '../providers'
|
||||||
|
import { windowManager } from '@main/service/window-service'
|
||||||
|
import { menuManager } from '@main/service/menu-service'
|
||||||
|
import { logManager } from '@main/service/logger'
|
||||||
|
import { configManager } from '@main/service/config-service'
|
||||||
|
import { trayManager } from '@main/service/tray-service'
|
||||||
|
import { TabManager } from '@service/tab-manager'
|
||||||
|
|
||||||
|
const handleTray = (minimizeToTray: boolean) => {
|
||||||
|
if (minimizeToTray) {
|
||||||
|
trayManager.create();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
trayManager.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
const registerMenus = (window: BrowserWindow) => {
|
||||||
|
|
||||||
|
const conversationItemMenuItemClick = (id: string) => {
|
||||||
|
logManager.logUserOperation(`${IPC_EVENTS.SHOW_CONTEXT_MENU}:${MENU_IDS.CONVERSATION_ITEM}-${id}`)
|
||||||
|
window.webContents.send(`${IPC_EVENTS.SHOW_CONTEXT_MENU}:${MENU_IDS.CONVERSATION_ITEM}`, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
menuManager.register(MENU_IDS.CONVERSATION_ITEM, [
|
||||||
|
{
|
||||||
|
id: CONVERSATION_ITEM_MENU_IDS.PIN,
|
||||||
|
label: 'menu.conversation.pinConversation',
|
||||||
|
click: () => conversationItemMenuItemClick(CONVERSATION_ITEM_MENU_IDS.PIN)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: CONVERSATION_ITEM_MENU_IDS.RENAME,
|
||||||
|
label: 'menu.conversation.renameConversation',
|
||||||
|
click: () => conversationItemMenuItemClick(CONVERSATION_ITEM_MENU_IDS.RENAME)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: CONVERSATION_ITEM_MENU_IDS.DEL,
|
||||||
|
label: 'menu.conversation.delConversation',
|
||||||
|
click: () => conversationItemMenuItemClick(CONVERSATION_ITEM_MENU_IDS.DEL)
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const conversationListMenuItemClick = (id: string) => {
|
||||||
|
logManager.logUserOperation(`${IPC_EVENTS.SHOW_CONTEXT_MENU}:${MENU_IDS.CONVERSATION_LIST}-${id}`)
|
||||||
|
window.webContents.send(`${IPC_EVENTS.SHOW_CONTEXT_MENU}:${MENU_IDS.CONVERSATION_LIST}`, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
menuManager.register(MENU_IDS.CONVERSATION_LIST, [
|
||||||
|
{
|
||||||
|
id: CONVERSATION_LIST_MENU_IDS.NEW_CONVERSATION,
|
||||||
|
label: 'menu.conversation.newConversation',
|
||||||
|
click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.NEW_CONVERSATION)
|
||||||
|
},
|
||||||
|
{ type: 'separator' },
|
||||||
|
{
|
||||||
|
id: CONVERSATION_LIST_MENU_IDS.SORT_BY, label: 'menu.conversation.sortBy', submenu: [
|
||||||
|
{ id: CONVERSATION_LIST_MENU_IDS.SORT_BY_CREATE_TIME, label: 'menu.conversation.sortByCreateTime', type: 'radio', checked: false, click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.SORT_BY_CREATE_TIME) },
|
||||||
|
{ id: CONVERSATION_LIST_MENU_IDS.SORT_BY_UPDATE_TIME, label: 'menu.conversation.sortByUpdateTime', type: 'radio', checked: false, click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.SORT_BY_UPDATE_TIME) },
|
||||||
|
{ id: CONVERSATION_LIST_MENU_IDS.SORT_BY_NAME, label: 'menu.conversation.sortByName', type: 'radio', checked: false, click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.SORT_BY_NAME) },
|
||||||
|
{ id: CONVERSATION_LIST_MENU_IDS.SORT_BY_MODEL, label: 'menu.conversation.sortByModel', type: 'radio', checked: false, click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.SORT_BY_MODEL) },
|
||||||
|
{ type: 'separator' },
|
||||||
|
{ id: CONVERSATION_LIST_MENU_IDS.SORT_ASCENDING, label: 'menu.conversation.sortAscending', type: 'radio', checked: false, click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.SORT_ASCENDING) },
|
||||||
|
{ id: CONVERSATION_LIST_MENU_IDS.SORT_DESCENDING, label: 'menu.conversation.sortDescending', type: 'radio', checked: false, click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.SORT_DESCENDING) },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: CONVERSATION_LIST_MENU_IDS.BATCH_OPERATIONS,
|
||||||
|
label: 'menu.conversation.batchOperations',
|
||||||
|
click: () => conversationListMenuItemClick(CONVERSATION_LIST_MENU_IDS.BATCH_OPERATIONS)
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const messageItemMenuItemClick = (id: string) => {
|
||||||
|
logManager.logUserOperation(`${IPC_EVENTS.SHOW_CONTEXT_MENU}:${MENU_IDS.MESSAGE_ITEM}-${id}`)
|
||||||
|
window.webContents.send(`${IPC_EVENTS.SHOW_CONTEXT_MENU}:${MENU_IDS.MESSAGE_ITEM}`, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
menuManager.register(MENU_IDS.MESSAGE_ITEM, [
|
||||||
|
{
|
||||||
|
id: MESSAGE_ITEM_MENU_IDS.COPY,
|
||||||
|
label: 'menu.message.copyMessage',
|
||||||
|
click: () => messageItemMenuItemClick(MESSAGE_ITEM_MENU_IDS.COPY)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: MESSAGE_ITEM_MENU_IDS.SELECT,
|
||||||
|
label: 'menu.message.selectMessage',
|
||||||
|
click: () => messageItemMenuItemClick(MESSAGE_ITEM_MENU_IDS.SELECT)
|
||||||
|
},
|
||||||
|
{ type: 'separator' },
|
||||||
|
{
|
||||||
|
id: MESSAGE_ITEM_MENU_IDS.DELETE,
|
||||||
|
label: 'menu.message.deleteMessage',
|
||||||
|
click: () => messageItemMenuItemClick(MESSAGE_ITEM_MENU_IDS.DELETE)
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setupMainWindow() {
|
||||||
|
windowManager.onWindowCreate(WINDOW_NAMES.MAIN, (mainWindow) => {
|
||||||
|
let minimizeToTray = configManager.get(CONFIG_KEYS.MINIMIZE_TO_TRAY);
|
||||||
|
|
||||||
|
configManager.onConfigChange((config) => {
|
||||||
|
if (minimizeToTray === config[CONFIG_KEYS.MINIMIZE_TO_TRAY]) return;
|
||||||
|
minimizeToTray = config[CONFIG_KEYS.MINIMIZE_TO_TRAY];
|
||||||
|
handleTray(minimizeToTray);
|
||||||
|
});
|
||||||
|
|
||||||
|
handleTray(minimizeToTray);
|
||||||
|
registerMenus(mainWindow);
|
||||||
|
|
||||||
|
const tabManager = new TabManager(mainWindow)
|
||||||
|
tabManager.enable()
|
||||||
|
|
||||||
|
mainWindow.on('closed', () => {
|
||||||
|
tabManager.destroy()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
windowManager.create(WINDOW_NAMES.MAIN, MAIN_WIN_SIZE);
|
||||||
|
|
||||||
|
ipcMain.on(IPC_EVENTS.START_A_DIALOGUE, async (_event, props: CreateDialogueProps) => {
|
||||||
|
const { providerName, messages, messageId, selectedModel } = props;
|
||||||
|
const mainWindow = windowManager.get(WINDOW_NAMES.MAIN);
|
||||||
|
|
||||||
|
if (!mainWindow) {
|
||||||
|
throw new Error('mainWindow not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const provider = createProvider(providerName);
|
||||||
|
const chunks = await provider?.chat(messages, selectedModel);
|
||||||
|
|
||||||
|
if (!chunks) {
|
||||||
|
throw new Error('chunks or stream not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
for await (const chunk of chunks) {
|
||||||
|
const chunkContent = {
|
||||||
|
messageId,
|
||||||
|
data: chunk
|
||||||
|
}
|
||||||
|
mainWindow.webContents.send(IPC_EVENTS.START_A_DIALOGUE + 'back' + messageId, chunkContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
const errorContent = {
|
||||||
|
messageId,
|
||||||
|
data: {
|
||||||
|
isEnd: true,
|
||||||
|
isError: true,
|
||||||
|
result: error instanceof Error ? error.message : String(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mainWindow.webContents.send(IPC_EVENTS.START_A_DIALOGUE + 'back' + messageId, errorContent);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -20,22 +20,6 @@ const api: WindowApi = {
|
|||||||
loadPage: (page: string) => ipcRenderer.invoke(IPC_EVENTS.APP_LOAD_PAGE, page)
|
loadPage: (page: string) => ipcRenderer.invoke(IPC_EVENTS.APP_LOAD_PAGE, page)
|
||||||
},
|
},
|
||||||
|
|
||||||
tabs: {
|
|
||||||
create: (url?: string) => ipcRenderer.invoke(IPC_EVENTS.TAB_CREATE, url),
|
|
||||||
list: () => ipcRenderer.invoke(IPC_EVENTS.TAB_LIST),
|
|
||||||
navigate: (tabId: string, url: string) => ipcRenderer.invoke(IPC_EVENTS.TAB_NAVIGATE, { tabId, url }),
|
|
||||||
reload: (tabId: string) => ipcRenderer.invoke(IPC_EVENTS.TAB_RELOAD, tabId),
|
|
||||||
back: (tabId: string) => ipcRenderer.invoke(IPC_EVENTS.TAB_BACK, tabId),
|
|
||||||
forward: (tabId: string) => ipcRenderer.invoke(IPC_EVENTS.TAB_FORWARD, tabId),
|
|
||||||
switch: (tabId: string) => ipcRenderer.invoke(IPC_EVENTS.TAB_SWITCH, tabId),
|
|
||||||
close: (tabId: string) => ipcRenderer.invoke(IPC_EVENTS.TAB_CLOSE, tabId),
|
|
||||||
on: (event: 'tab-updated' | 'tab-created' | 'tab-closed' | 'tab-switched', handler: (payload: any) => void) => {
|
|
||||||
const listener = (_e: any, payload: any) => handler(payload)
|
|
||||||
ipcRenderer.on(event, listener)
|
|
||||||
return () => ipcRenderer.removeListener(event, listener)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 通过 IPC 调用主进程
|
// 通过 IPC 调用主进程
|
||||||
readFile: (filePath: string) => ipcRenderer.invoke(IPC_EVENTS.READ_FILE, filePath),
|
readFile: (filePath: string) => ipcRenderer.invoke(IPC_EVENTS.READ_FILE, filePath),
|
||||||
|
|
||||||
|
|||||||
@@ -21,107 +21,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { menus, type MenuItem } from '@constant/menus'
|
import { menus, type MenuItem } from '@constant/menus'
|
||||||
|
|
||||||
const currentId = ref(1)
|
const currentId = ref(1)
|
||||||
const tabMap = new Map<number, string>()
|
const router = useRouter()
|
||||||
const cleanupListeners: (() => void)[] = []
|
|
||||||
|
|
||||||
const getHtmlPath = (menuUrl: string) => {
|
|
||||||
const cleanUrl = menuUrl.startsWith('/') ? menuUrl.slice(1) : menuUrl
|
|
||||||
let filename = ''
|
|
||||||
switch (cleanUrl) {
|
|
||||||
case 'home':
|
|
||||||
filename = 'home.html'
|
|
||||||
break
|
|
||||||
case 'knowledge':
|
|
||||||
filename = 'knowledge.html'
|
|
||||||
break
|
|
||||||
case 'task':
|
|
||||||
filename = 'task.html'
|
|
||||||
break
|
|
||||||
case 'setting':
|
|
||||||
filename = 'setting.html'
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
filename = 'home.html'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (import.meta.env.DEV) {
|
|
||||||
return `/html/${filename}`
|
|
||||||
}
|
|
||||||
return filename
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
if (window.api && window.api.tabs) {
|
|
||||||
const cleanupClosed = window.api.tabs.on('tab-closed', (payload: any) => {
|
|
||||||
const { tabId } = payload
|
|
||||||
for (const [menuId, id] of tabMap.entries()) {
|
|
||||||
if (id === tabId) {
|
|
||||||
tabMap.delete(menuId)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (cleanupClosed) cleanupListeners.push(cleanupClosed)
|
|
||||||
|
|
||||||
const cleanupCreated = window.api.tabs.on('tab-created', (tab: any) => {
|
|
||||||
for (const menu of menus) {
|
|
||||||
const targetHtml = getHtmlPath(menu.url)
|
|
||||||
if (tab.url.includes(targetHtml)) {
|
|
||||||
tabMap.set(menu.id, tab.id)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (cleanupCreated) cleanupListeners.push(cleanupCreated)
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tabs = await window.api.tabs.list()
|
|
||||||
if (tabs && tabs.length > 0) {
|
|
||||||
for (const tab of tabs) {
|
|
||||||
for (const menu of menus) {
|
|
||||||
const targetHtml = getHtmlPath(menu.url)
|
|
||||||
if (tab.url.includes(targetHtml)) {
|
|
||||||
tabMap.set(menu.id, tab.id)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to sync tabs', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
cleanupListeners.forEach(fn => fn())
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleClick = async (item: MenuItem) => {
|
const handleClick = async (item: MenuItem) => {
|
||||||
console.log("🚀 ~ handleClick ~ item:", item)
|
console.log("🚀 ~ handleClick ~ item:", item)
|
||||||
currentId.value = item.id
|
currentId.value = item.id
|
||||||
|
router.push(item.url)
|
||||||
const existingTabId = tabMap.get(item.id)
|
|
||||||
if (existingTabId) {
|
|
||||||
await window.api.tabs.switch(existingTabId)
|
|
||||||
} else {
|
|
||||||
const htmlFile = getHtmlPath(item.url)
|
|
||||||
const targetUrl = new URL(htmlFile, window.location.href).href
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tabInfo = await window.api.tabs.create(targetUrl)
|
|
||||||
if (tabInfo && tabInfo.id) {
|
|
||||||
tabMap.set(item.id, tabInfo.id)
|
|
||||||
await window.api.tabs.switch(tabInfo.id)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to create tab', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import locale from 'element-plus/es/locale/lang/zh-cn'
|
|||||||
|
|
||||||
// 引入 i18n 插件
|
// 引入 i18n 插件
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
// import './permission'
|
import './permission'
|
||||||
|
|
||||||
// 样式文件隔离
|
// 样式文件隔离
|
||||||
import "./styles/index.css";
|
import "./styles/index.css";
|
||||||
|
|||||||
@@ -5,12 +5,36 @@ const routes = [
|
|||||||
path: '/',
|
path: '/',
|
||||||
redirect: '/home'
|
redirect: '/home'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/login",
|
||||||
|
component: () => import("@renderer/views/login/index.vue"),
|
||||||
|
name: "Login",
|
||||||
|
meta: { requiresAuth: true },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/home",
|
path: "/home",
|
||||||
component: () => import("@renderer/views/home/index.vue"),
|
component: () => import("@renderer/views/home/index.vue"),
|
||||||
name: "Home",
|
name: "Home",
|
||||||
meta: { requiresAuth: true },
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/task",
|
||||||
|
component: () => import("@renderer/views/task/index.vue"),
|
||||||
|
name: "Task",
|
||||||
|
meta: { requiresAuth: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/knowledge",
|
||||||
|
component: () => import("@renderer/views/knowledge/index.vue"),
|
||||||
|
name: "Knowledge",
|
||||||
|
meta: { requiresAuth: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/setting",
|
||||||
|
component: () => import("@renderer/views/setting/index.vue"),
|
||||||
|
name: "Setting",
|
||||||
|
meta: { requiresAuth: true },
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ const getVerifyCode = async () => {
|
|||||||
|
|
||||||
onMounted(() => getVerifyCode())
|
onMounted(() => getVerifyCode())
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await formRef.value.validate().catch(() => { }); // 表单校验
|
const valid = await formRef.value.validate().catch(() => { }); // 表单校验
|
||||||
@@ -136,7 +137,7 @@ const onSubmit = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
userStore.login(form).then(() => {
|
userStore.login(form).then(() => {
|
||||||
window.api.app.loadPage('index');
|
router.push({ path: '/home' })
|
||||||
})
|
})
|
||||||
} finally {
|
} finally {
|
||||||
getVerifyCode()
|
getVerifyCode()
|
||||||
|
|||||||
Reference in New Issue
Block a user