Merge branch 'feature/dsw' of https://git.nianxx.cn/duanshuwen/zn-ai
This commit is contained in:
@@ -27,12 +27,12 @@ const config: ForgeConfig = {
|
||||
build: [
|
||||
{
|
||||
// `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
|
||||
entry: 'src/electron/main/main.ts',
|
||||
entry: 'src/main/main.ts',
|
||||
config: 'vite.main.config.ts',
|
||||
target: 'main',
|
||||
},
|
||||
{
|
||||
entry: 'src/electron/preload/preload.ts',
|
||||
entry: 'src/preload.ts',
|
||||
config: 'vite.preload.config.ts',
|
||||
target: 'preload',
|
||||
},
|
||||
|
||||
7
global.d.ts
vendored
Normal file
7
global.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
declare module "@store/*";
|
||||
declare module "@utils/*";
|
||||
declare module "@assets/images/*";
|
||||
declare module "@constant/*";
|
||||
declare module "@remixicon/vue";
|
||||
declare module "vue-router";
|
||||
|
||||
1240
package-lock.json
generated
1240
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@@ -5,7 +5,7 @@
|
||||
"description": "My Electron application description",
|
||||
"main": ".vite/build/main.js",
|
||||
"scripts": {
|
||||
"start": "electron-forge start",
|
||||
"start": "dotenv -e .env -- electron-forge start",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make",
|
||||
"publish": "electron-forge publish",
|
||||
@@ -30,11 +30,10 @@
|
||||
"@electron-forge/plugin-fuses": "^7.10.2",
|
||||
"@electron-forge/plugin-vite": "^7.10.2",
|
||||
"@electron/fuses": "^1.8.0",
|
||||
"@tailwindcss/postcss": "^4.1.14",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"@tailwindcss/vite": "^4.1.17",
|
||||
"@types/electron-squirrel-startup": "^1.0.2",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
@@ -42,15 +41,17 @@
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-vue": "^10.6.0",
|
||||
"postcss": "^8.5.6",
|
||||
"sass-embedded": "^1.89.1",
|
||||
"tailwindcss": "^3.4.18",
|
||||
"typescript": "~4.5.4",
|
||||
"vite": "^7.1.9",
|
||||
"vue-eslint-parser": "^10.2.0"
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.8.3",
|
||||
"unplugin-auto-import": "^20.3.0",
|
||||
"vite": "^7.1.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@remixicon/vue": "^4.7.0",
|
||||
"@vueuse/core": "^14.1.0",
|
||||
"dotenv-cli": "^11.0.0",
|
||||
"electron-log": "^5.4.3",
|
||||
"axios": "^1.12.2",
|
||||
"bytenode": "^1.5.7",
|
||||
"crypto": "^1.0.1",
|
||||
@@ -60,6 +61,8 @@
|
||||
"log4js": "^6.9.1",
|
||||
"pinia": "^2.3.1",
|
||||
"vue": "^3.5.22",
|
||||
"vue-i18n": "^11.1.9",
|
||||
"vue-markdown-render": "^2.3.0",
|
||||
"vue-router": "^4.5.1"
|
||||
}
|
||||
}
|
||||
|
||||
6
shims-vue.d.ts
vendored
6
shims-vue.d.ts
vendored
@@ -1,6 +0,0 @@
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
// 泛型参数:Props类型、Emits类型、Slots类型(默认任意)
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
108
src/common/constants.ts
Normal file
108
src/common/constants.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
// 渲染进程|主进程常量定义
|
||||
|
||||
export enum IPC_EVENTS {
|
||||
EXTERNAL_OPEN = 'external-open',
|
||||
WINDOW_MINIMIZE = 'window-minimize',
|
||||
WINDOW_MAXIMIZE = 'window-maximize',
|
||||
WINDOW_CLOSE = 'window-close',
|
||||
APP_SET_FRAMELESS = 'app:set-frameless',
|
||||
TAB_CREATE = 'tab:create',
|
||||
TAB_LIST = 'tab:list',
|
||||
TAB_NAVIGATE = 'tab:navigate',
|
||||
TAB_RELOAD = 'tab:reload',
|
||||
TAB_BACK = 'tab:back',
|
||||
TAB_FORWARD = 'tab:forward',
|
||||
TAB_SWITCH = 'tab:switch',
|
||||
TAB_CLOSE = 'tab:close',
|
||||
LOG_TO_MAIN = 'log-to-main',
|
||||
READ_FILE = 'read-file',
|
||||
INVOKE = 'ipc:invoke',
|
||||
INVOKE_ASYNC = 'ipc:invokeAsync',
|
||||
APP_MINIMIZE ='app:minimize',
|
||||
APP_MAXIMIZE ='app:maximize',
|
||||
APP_QUIT ='app:quit',
|
||||
FILE_READ = 'file:read',
|
||||
FILE_WRITE = 'file:write',
|
||||
GET_WINDOW_ID='get-window-id',
|
||||
CUSTOM_EVENT ='custom:event',
|
||||
TIME_UPDATE = 'time:update'
|
||||
}
|
||||
|
||||
export const MAIN_WIN_SIZE = {
|
||||
width: 1440,
|
||||
height: 900,
|
||||
minWidth: 1440,
|
||||
minHeight: 900,
|
||||
} as const
|
||||
|
||||
|
||||
// 定义每个通道的参数和返回值类型
|
||||
interface IPCTypings {
|
||||
// 同步通信
|
||||
[IPC_EVENTS.APP_MINIMIZE]: {
|
||||
params: [window:number]
|
||||
return: {success: boolean, error?: string}
|
||||
}
|
||||
[IPC_EVENTS.APP_MAXIMIZE]: {
|
||||
params: [window:number]
|
||||
return: {success: boolean, error?: string}
|
||||
}
|
||||
[IPC_EVENTS.GET_WINDOW_ID]: {
|
||||
params: []
|
||||
return: number
|
||||
}
|
||||
|
||||
// 异步通信
|
||||
[IPC_EVENTS.FILE_READ]: {
|
||||
params: [filePath: string]
|
||||
return: Promise<{success: boolean, data?: string, error?: string}>
|
||||
}
|
||||
[IPC_EVENTS.FILE_WRITE]: {
|
||||
params: [filePath: string, content: string]
|
||||
return: Promise<{success: boolean, error?: string}>
|
||||
}
|
||||
|
||||
// 事件通信
|
||||
[IPC_EVENTS.TIME_UPDATE]: {
|
||||
params: [time: string]
|
||||
return: void
|
||||
}
|
||||
[IPC_EVENTS.CUSTOM_EVENT]: {
|
||||
params: [message: string]
|
||||
return: void
|
||||
}
|
||||
}
|
||||
|
||||
// 定义IPC API 接口
|
||||
export interface WindowApi {
|
||||
invoke<T extends keyof IPCTypings>(channel: T, ...args: IPCTypings[T]['params']): IPCTypings[T]['return'],
|
||||
invokeAsync<T extends keyof IPCTypings>(channel: T, ...args: IPCTypings[T]['params']): IPCTypings[T]['return'],
|
||||
on<T extends keyof IPCTypings>(channel: T, callback: (...args: IPCTypings[T]['params']) => void): () => void
|
||||
send<T extends keyof IPCTypings>(channel: T, ...args: IPCTypings[T]['params']): void,
|
||||
getCurrentWindowId(): number,
|
||||
versions: NodeJS.ProcessVersions,
|
||||
external: {
|
||||
open: (url: string) => void
|
||||
},
|
||||
window: {
|
||||
minimize: () => void,
|
||||
maximize: () => void,
|
||||
close: () => void
|
||||
},
|
||||
app: {
|
||||
setFrameless: (route?: string) => void
|
||||
},
|
||||
tabs: {
|
||||
create: (url?: string) => void,
|
||||
list: () => void,
|
||||
navigate: (tabId: string, url: string) => void,
|
||||
reload: (tabId: string) => void,
|
||||
back: (tabId: string) => void,
|
||||
forward: (tabId: string) => void,
|
||||
switch: (tabId: string) => void,
|
||||
close: (tabId: string) => 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}>,
|
||||
logToMain: (logLevel: string, message: string) => void,
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
const { chromium } = require("playwright");
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch();
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
// 打开百度
|
||||
await page.goto("https://www.baidu.com");
|
||||
|
||||
// 输入搜索关键词并回车
|
||||
await page.fill("textarea#chat-textarea", "Playwright 自动化");
|
||||
await page.keyboard.press("Enter");
|
||||
|
||||
// 等待搜索结果加载
|
||||
await page.waitForSelector("#content_left");
|
||||
|
||||
console.log("百度搜索执行成功");
|
||||
} catch (e) {
|
||||
console.error("自动化执行失败:", e);
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
// 保持几秒以方便观察,再关闭
|
||||
await page.waitForTimeout(2000);
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
@@ -1,247 +0,0 @@
|
||||
const { chromium } = require('playwright');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 录制配置
|
||||
const recordingConfig = {
|
||||
outputFile: 'recorded-steps.json',
|
||||
headless: false, // 显示浏览器窗口
|
||||
slowMo: 100, // 减慢操作速度,便于观察
|
||||
viewport: { width: 1280, height: 720 }
|
||||
};
|
||||
|
||||
// 存储录制的步骤
|
||||
let recordedSteps = [];
|
||||
let recordingStartTime = Date.now();
|
||||
let isRecording = true;
|
||||
|
||||
// 生成时间戳
|
||||
function getTimestamp() {
|
||||
return Date.now() - recordingStartTime;
|
||||
}
|
||||
|
||||
// 记录步骤
|
||||
function recordStep(step) {
|
||||
const stepWithTimestamp = {
|
||||
...step,
|
||||
timestamp: getTimestamp()
|
||||
};
|
||||
recordedSteps.push(stepWithTimestamp);
|
||||
console.log(`📹 录制步骤: ${step.type} - ${step.description}`);
|
||||
}
|
||||
|
||||
// 保存录制的步骤到文件
|
||||
function saveRecordedSteps() {
|
||||
const outputPath = path.join(__dirname, recordingConfig.outputFile);
|
||||
const data = {
|
||||
steps: recordedSteps,
|
||||
metadata: {
|
||||
totalSteps: recordedSteps.length,
|
||||
duration: getTimestamp(),
|
||||
recordedAt: new Date().toISOString()
|
||||
}
|
||||
};
|
||||
|
||||
fs.writeFileSync(outputPath, JSON.stringify(data, null, 2));
|
||||
console.log(`\n✅ 录制完成!共录制 ${recordedSteps.length} 个步骤`);
|
||||
console.log(`📁 录制文件已保存到: ${outputPath}`);
|
||||
}
|
||||
|
||||
// 监听页面事件
|
||||
async function setupPageListeners(page) {
|
||||
// 监听点击事件
|
||||
await page.exposeFunction('__recordClick', (selector, coordinates) => {
|
||||
if (!isRecording) return;
|
||||
|
||||
recordStep({
|
||||
type: 'click',
|
||||
description: `点击元素: ${selector || '未知元素'}`,
|
||||
selector: selector || '',
|
||||
coordinates: coordinates || {}
|
||||
});
|
||||
});
|
||||
|
||||
// 监听输入事件
|
||||
await page.exposeFunction('__recordInput', (selector, text) => {
|
||||
if (!isRecording) return;
|
||||
|
||||
recordStep({
|
||||
type: 'type',
|
||||
description: `输入文本: "${text || ''}"`,
|
||||
selector: selector || '',
|
||||
text: text || ''
|
||||
});
|
||||
});
|
||||
|
||||
// 注入脚本监听用户操作
|
||||
await page.addInitScript(() => {
|
||||
// 监听点击事件
|
||||
document.addEventListener('click', (event) => {
|
||||
const target = event.target;
|
||||
const selector = generateSelector(target);
|
||||
const coordinates = { x: event.clientX, y: event.clientY };
|
||||
|
||||
if (window.__recordClick) {
|
||||
window.__recordClick(selector, coordinates);
|
||||
}
|
||||
}, true);
|
||||
|
||||
// 监听输入事件
|
||||
document.addEventListener('input', (event) => {
|
||||
const target = event.target;
|
||||
const selector = generateSelector(target);
|
||||
const text = target.value || target.textContent || '';
|
||||
|
||||
if (window.__recordInput) {
|
||||
window.__recordInput(selector, text);
|
||||
}
|
||||
}, true);
|
||||
|
||||
// 生成元素选择器
|
||||
function generateSelector(element) {
|
||||
if (!element) return '';
|
||||
|
||||
// 优先使用 ID
|
||||
if (element.id) {
|
||||
return `#${element.id}`;
|
||||
}
|
||||
|
||||
// 使用 class 和标签名
|
||||
const tagName = element.tagName.toLowerCase();
|
||||
if (element.className) {
|
||||
const classes = element.className.split(' ').filter(c => c.trim());
|
||||
if (classes.length > 0) {
|
||||
return `${tagName}.${classes.join('.')}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用属性
|
||||
const attributes = ['name', 'placeholder', 'type'];
|
||||
for (const attr of attributes) {
|
||||
if (element.getAttribute(attr)) {
|
||||
return `${tagName}[${attr}="${element.getAttribute(attr)}"]`;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用路径
|
||||
return getElementPath(element);
|
||||
}
|
||||
|
||||
function getElementPath(element) {
|
||||
const path = [];
|
||||
while (element && element.nodeType === Node.ELEMENT_NODE) {
|
||||
let selector = element.nodeName.toLowerCase();
|
||||
if (element.id) {
|
||||
selector += `#${element.id}`;
|
||||
path.unshift(selector);
|
||||
break;
|
||||
} else {
|
||||
let sibling = element;
|
||||
let nth = 1;
|
||||
while (sibling = sibling.previousElementSibling) {
|
||||
if (sibling.nodeName.toLowerCase() === selector) nth++;
|
||||
}
|
||||
if (nth !== 1) selector += `:nth-of-type(${nth})`;
|
||||
}
|
||||
path.unshift(selector);
|
||||
element = element.parentNode;
|
||||
}
|
||||
return path.join(' > ');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 主录制函数
|
||||
async function startRecording() {
|
||||
console.log('🎬 开始自动化录制...');
|
||||
console.log('请在浏览器中进行操作,系统会自动记录您的操作步骤');
|
||||
console.log('按 Ctrl+C 停止录制并保存结果\n');
|
||||
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
try {
|
||||
// 启动浏览器
|
||||
browser = await chromium.launch({
|
||||
headless: recordingConfig.headless,
|
||||
slowMo: recordingConfig.slowMo
|
||||
});
|
||||
|
||||
// 创建新页面
|
||||
page = await browser.newPage({
|
||||
viewport: recordingConfig.viewport
|
||||
});
|
||||
|
||||
// 设置页面监听器
|
||||
await setupPageListeners(page);
|
||||
|
||||
// 监听页面导航
|
||||
page.on('framenavigated', async (frame) => {
|
||||
if (frame === page.mainFrame() && isRecording) {
|
||||
recordStep({
|
||||
type: 'navigate',
|
||||
description: `导航到: ${frame.url()}`,
|
||||
url: frame.url()
|
||||
});
|
||||
|
||||
// 重新设置监听器
|
||||
await setupPageListeners(page);
|
||||
}
|
||||
});
|
||||
|
||||
// 导航到百度首页作为起始页面
|
||||
console.log('🌐 正在打开百度首页...');
|
||||
await page.goto('https://www.baidu.com');
|
||||
|
||||
recordStep({
|
||||
type: 'navigate',
|
||||
description: '打开百度首页',
|
||||
url: 'https://www.baidu.com'
|
||||
});
|
||||
|
||||
console.log('✅ 录制已启动!请在浏览器中进行操作...');
|
||||
console.log('💡 您可以:');
|
||||
console.log(' - 点击页面元素');
|
||||
console.log(' - 在输入框中输入文本');
|
||||
console.log(' - 导航到其他页面');
|
||||
console.log(' - 按回车键或其他键盘操作');
|
||||
console.log('');
|
||||
console.log('⚠️ 按 Ctrl+C 停止录制并保存结果');
|
||||
|
||||
// 保持浏览器打开,直到用户手动停止
|
||||
await new Promise((resolve) => {
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n🛑 用户停止录制');
|
||||
isRecording = false;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 录制过程中发生错误:', error);
|
||||
} finally {
|
||||
if (browser) {
|
||||
// 保存录制的步骤
|
||||
saveRecordedSteps();
|
||||
await browser.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理程序终止
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n🛑 用户停止录制');
|
||||
saveRecordedSteps();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('\n🛑 程序终止');
|
||||
saveRecordedSteps();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// 启动录制
|
||||
(async () => {
|
||||
await startRecording();
|
||||
})();
|
||||
@@ -1,72 +0,0 @@
|
||||
import { contextBridge, ipcRenderer } from 'electron'
|
||||
import { IPCChannel, IPCAPI } from '@/shared/types/ipc.types'
|
||||
|
||||
const api: IPCAPI = {
|
||||
versions: process.versions,
|
||||
|
||||
external: {
|
||||
open: (url: string) => ipcRenderer.invoke('external-open', url)
|
||||
},
|
||||
|
||||
window: {
|
||||
minimize: () => ipcRenderer.send('window-min'),
|
||||
maximize: () => ipcRenderer.send('window-max'),
|
||||
close: () => ipcRenderer.send('window-close')
|
||||
},
|
||||
|
||||
app: {
|
||||
setFrameless: (route?: string) => ipcRenderer.invoke('app:set-frameless', route)
|
||||
},
|
||||
|
||||
tabs: {
|
||||
create: (url?: string) => ipcRenderer.invoke('tab:create', url),
|
||||
list: () => ipcRenderer.invoke('tab:list'),
|
||||
navigate: (tabId: string, url: string) => ipcRenderer.invoke('tab:navigate', { tabId, url }),
|
||||
reload: (tabId: string) => ipcRenderer.invoke('tab:reload', tabId),
|
||||
back: (tabId: string) => ipcRenderer.invoke('tab:back', tabId),
|
||||
forward: (tabId: string) => ipcRenderer.invoke('tab:forward', tabId),
|
||||
switch: (tabId: string) => ipcRenderer.invoke('tab:switch', tabId),
|
||||
close: (tabId: string) => ipcRenderer.invoke('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 调用主进程
|
||||
readFile: (filePath: string) => ipcRenderer.invoke('read-file', filePath),
|
||||
|
||||
// 同步调用
|
||||
invoke: (channel: IPCChannel, ...args: any[]) => ipcRenderer.sendSync('ipc:invoke', channel, ...args),
|
||||
|
||||
// 异步调用
|
||||
invokeAsync: (channel: IPCChannel, ...args: any[]) => {
|
||||
try {
|
||||
ipcRenderer.invoke('ipc:invokeAsync', channel, ...args)
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 监听主进程消息
|
||||
on: (event: IPCChannel, callback: (...args: any[]) => void) => {
|
||||
const subscription = (_event: any, ...args: any[]) => callback(...args)
|
||||
ipcRenderer.on(event, subscription)
|
||||
return () => ipcRenderer.removeListener(event, subscription)
|
||||
},
|
||||
|
||||
// 发送消息到主进程
|
||||
send: (channel: IPCChannel, ...args: any[]) => ipcRenderer.send(channel, ...args),
|
||||
|
||||
// 获取窗口ID
|
||||
getCurrentWindowId: () => ipcRenderer.sendSync(IPCChannel.GET_WINDOW_ID),
|
||||
|
||||
// 发送日志
|
||||
logToMain: (logLevel: string, message: string) => ipcRenderer.send('log-to-main', logLevel, message),
|
||||
|
||||
// 打开新窗口
|
||||
openNewTab: (url: string) => ipcRenderer.invoke('open-new-tab', url)
|
||||
}
|
||||
|
||||
contextBridge.exposeInMainWorld('ipcAPI', api)
|
||||
@@ -21,6 +21,7 @@ export default function electronBytecode(options?: ElectronBytecodeOptions): Plu
|
||||
|
||||
const outputPath = entryPath.replace(/\.js$/, '.jsc')
|
||||
const backupPath = `${entryPath}.bak`
|
||||
|
||||
fs.copyFileSync(entryPath, backupPath)
|
||||
await bytenode.compileFile({ filename: entryPath, output: outputPath })
|
||||
const stub = [
|
||||
|
||||
69
src/preload.ts
Normal file
69
src/preload.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { contextBridge, ipcRenderer } from 'electron'
|
||||
import { IPC_EVENTS, WindowApi } from '@common/constants';
|
||||
|
||||
const api: WindowApi = {
|
||||
versions: process.versions,
|
||||
|
||||
external: {
|
||||
open: (url: string) => ipcRenderer.invoke('external-open', url)
|
||||
},
|
||||
|
||||
window: {
|
||||
minimize: () => ipcRenderer.send(IPC_EVENTS.WINDOW_MINIMIZE),
|
||||
maximize: () => ipcRenderer.send(IPC_EVENTS.WINDOW_MAXIMIZE),
|
||||
close: () => ipcRenderer.send(IPC_EVENTS.WINDOW_CLOSE)
|
||||
},
|
||||
|
||||
app: {
|
||||
setFrameless: (route?: string) => ipcRenderer.invoke(IPC_EVENTS.APP_SET_FRAMELESS, route)
|
||||
},
|
||||
|
||||
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 调用主进程
|
||||
readFile: (filePath: string) => ipcRenderer.invoke(IPC_EVENTS.READ_FILE, filePath),
|
||||
|
||||
// 同步调用
|
||||
invoke: (channel: IPC_EVENTS, ...args: any[]) => ipcRenderer.sendSync(IPC_EVENTS.INVOKE, channel, ...args),
|
||||
|
||||
// 异步调用
|
||||
invokeAsync: (channel: IPC_EVENTS, ...args: any[]) => {
|
||||
try {
|
||||
ipcRenderer.invoke(IPC_EVENTS.INVOKE_ASYNC, channel, ...args)
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
},
|
||||
|
||||
// 监听主进程消息
|
||||
on: (event: IPC_EVENTS, callback: (...args: any[]) => void) => {
|
||||
const subscription = (_event: any, ...args: any[]) => callback(...args)
|
||||
ipcRenderer.on(event, subscription)
|
||||
return () => ipcRenderer.removeListener(event, subscription)
|
||||
},
|
||||
|
||||
// 发送消息到主进程
|
||||
send: (channel: IPC_EVENTS, ...args: any[]) => ipcRenderer.send(channel, ...args),
|
||||
|
||||
// 获取窗口ID
|
||||
getCurrentWindowId: () => ipcRenderer.sendSync(IPC_EVENTS.GET_WINDOW_ID),
|
||||
|
||||
// 发送日志
|
||||
logToMain: (logLevel: string, message: string) => ipcRenderer.send(IPC_EVENTS.LOG_TO_MAIN, logLevel, message),
|
||||
}
|
||||
|
||||
contextBridge.exposeInMainWorld('api', api)
|
||||
317
src/renderer/auto-imports.d.ts
vendored
Normal file
317
src/renderer/auto-imports.d.ts
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue').EffectScope
|
||||
const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
|
||||
const asyncComputed: typeof import('@vueuse/core').asyncComputed
|
||||
const autoResetRef: typeof import('@vueuse/core').autoResetRef
|
||||
const computed: typeof import('vue').computed
|
||||
const computedAsync: typeof import('@vueuse/core').computedAsync
|
||||
const computedEager: typeof import('@vueuse/core').computedEager
|
||||
const computedInject: typeof import('@vueuse/core').computedInject
|
||||
const computedWithControl: typeof import('@vueuse/core').computedWithControl
|
||||
const controlledComputed: typeof import('@vueuse/core').controlledComputed
|
||||
const controlledRef: typeof import('@vueuse/core').controlledRef
|
||||
const createApp: typeof import('vue').createApp
|
||||
const createEventHook: typeof import('@vueuse/core').createEventHook
|
||||
const createGlobalState: typeof import('@vueuse/core').createGlobalState
|
||||
const createInjectionState: typeof import('@vueuse/core').createInjectionState
|
||||
const createPinia: typeof import('pinia').createPinia
|
||||
const createReactiveFn: typeof import('@vueuse/core').createReactiveFn
|
||||
const createRef: typeof import('@vueuse/core').createRef
|
||||
const createReusableTemplate: typeof import('@vueuse/core').createReusableTemplate
|
||||
const createSharedComposable: typeof import('@vueuse/core').createSharedComposable
|
||||
const createTemplatePromise: typeof import('@vueuse/core').createTemplatePromise
|
||||
const createUnrefFn: typeof import('@vueuse/core').createUnrefFn
|
||||
const customRef: typeof import('vue').customRef
|
||||
const debouncedRef: typeof import('@vueuse/core').debouncedRef
|
||||
const debouncedWatch: typeof import('@vueuse/core').debouncedWatch
|
||||
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
|
||||
const defineComponent: typeof import('vue').defineComponent
|
||||
const defineStore: typeof import('pinia').defineStore
|
||||
const eagerComputed: typeof import('@vueuse/core').eagerComputed
|
||||
const effectScope: typeof import('vue').effectScope
|
||||
const extendRef: typeof import('@vueuse/core').extendRef
|
||||
const getActivePinia: typeof import('pinia').getActivePinia
|
||||
const getCurrentInstance: typeof import('vue').getCurrentInstance
|
||||
const getCurrentScope: typeof import('vue').getCurrentScope
|
||||
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
|
||||
const h: typeof import('vue').h
|
||||
const ignorableWatch: typeof import('@vueuse/core').ignorableWatch
|
||||
const inject: typeof import('vue').inject
|
||||
const injectLocal: typeof import('@vueuse/core').injectLocal
|
||||
const isDefined: typeof import('@vueuse/core').isDefined
|
||||
const isProxy: typeof import('vue').isProxy
|
||||
const isReactive: typeof import('vue').isReactive
|
||||
const isReadonly: typeof import('vue').isReadonly
|
||||
const isRef: typeof import('vue').isRef
|
||||
const isShallow: typeof import('vue').isShallow
|
||||
const makeDestructurable: typeof import('@vueuse/core').makeDestructurable
|
||||
const mapActions: typeof import('pinia').mapActions
|
||||
const mapGetters: typeof import('pinia').mapGetters
|
||||
const mapState: typeof import('pinia').mapState
|
||||
const mapStores: typeof import('pinia').mapStores
|
||||
const mapWritableState: typeof import('pinia').mapWritableState
|
||||
const markRaw: typeof import('vue').markRaw
|
||||
const nextTick: typeof import('vue').nextTick
|
||||
const onActivated: typeof import('vue').onActivated
|
||||
const onBeforeMount: typeof import('vue').onBeforeMount
|
||||
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
|
||||
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
|
||||
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
|
||||
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
|
||||
const onClickOutside: typeof import('@vueuse/core').onClickOutside
|
||||
const onDeactivated: typeof import('vue').onDeactivated
|
||||
const onElementRemoval: typeof import('@vueuse/core').onElementRemoval
|
||||
const onErrorCaptured: typeof import('vue').onErrorCaptured
|
||||
const onKeyStroke: typeof import('@vueuse/core').onKeyStroke
|
||||
const onLongPress: typeof import('@vueuse/core').onLongPress
|
||||
const onMounted: typeof import('vue').onMounted
|
||||
const onRenderTracked: typeof import('vue').onRenderTracked
|
||||
const onRenderTriggered: typeof import('vue').onRenderTriggered
|
||||
const onScopeDispose: typeof import('vue').onScopeDispose
|
||||
const onServerPrefetch: typeof import('vue').onServerPrefetch
|
||||
const onStartTyping: typeof import('@vueuse/core').onStartTyping
|
||||
const onUnmounted: typeof import('vue').onUnmounted
|
||||
const onUpdated: typeof import('vue').onUpdated
|
||||
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
|
||||
const pausableWatch: typeof import('@vueuse/core').pausableWatch
|
||||
const provide: typeof import('vue').provide
|
||||
const provideLocal: typeof import('@vueuse/core').provideLocal
|
||||
const reactify: typeof import('@vueuse/core').reactify
|
||||
const reactifyObject: typeof import('@vueuse/core').reactifyObject
|
||||
const reactive: typeof import('vue').reactive
|
||||
const reactiveComputed: typeof import('@vueuse/core').reactiveComputed
|
||||
const reactiveOmit: typeof import('@vueuse/core').reactiveOmit
|
||||
const reactivePick: typeof import('@vueuse/core').reactivePick
|
||||
const readonly: typeof import('vue').readonly
|
||||
const ref: typeof import('vue').ref
|
||||
const refAutoReset: typeof import('@vueuse/core').refAutoReset
|
||||
const refDebounced: typeof import('@vueuse/core').refDebounced
|
||||
const refDefault: typeof import('@vueuse/core').refDefault
|
||||
const refManualReset: typeof import('@vueuse/core').refManualReset
|
||||
const refThrottled: typeof import('@vueuse/core').refThrottled
|
||||
const refWithControl: typeof import('@vueuse/core').refWithControl
|
||||
const resolveComponent: typeof import('vue').resolveComponent
|
||||
const resolveRef: typeof import('@vueuse/core').resolveRef
|
||||
const setActivePinia: typeof import('pinia').setActivePinia
|
||||
const setMapStoreSuffix: typeof import('pinia').setMapStoreSuffix
|
||||
const shallowReactive: typeof import('vue').shallowReactive
|
||||
const shallowReadonly: typeof import('vue').shallowReadonly
|
||||
const shallowRef: typeof import('vue').shallowRef
|
||||
const storeToRefs: typeof import('pinia').storeToRefs
|
||||
const syncRef: typeof import('@vueuse/core').syncRef
|
||||
const syncRefs: typeof import('@vueuse/core').syncRefs
|
||||
const templateRef: typeof import('@vueuse/core').templateRef
|
||||
const throttledRef: typeof import('@vueuse/core').throttledRef
|
||||
const throttledWatch: typeof import('@vueuse/core').throttledWatch
|
||||
const toRaw: typeof import('vue').toRaw
|
||||
const toReactive: typeof import('@vueuse/core').toReactive
|
||||
const toRef: typeof import('vue').toRef
|
||||
const toRefs: typeof import('vue').toRefs
|
||||
const toValue: typeof import('vue').toValue
|
||||
const triggerRef: typeof import('vue').triggerRef
|
||||
const tryOnBeforeMount: typeof import('@vueuse/core').tryOnBeforeMount
|
||||
const tryOnBeforeUnmount: typeof import('@vueuse/core').tryOnBeforeUnmount
|
||||
const tryOnMounted: typeof import('@vueuse/core').tryOnMounted
|
||||
const tryOnScopeDispose: typeof import('@vueuse/core').tryOnScopeDispose
|
||||
const tryOnUnmounted: typeof import('@vueuse/core').tryOnUnmounted
|
||||
const unref: typeof import('vue').unref
|
||||
const unrefElement: typeof import('@vueuse/core').unrefElement
|
||||
const until: typeof import('@vueuse/core').until
|
||||
const useActiveElement: typeof import('@vueuse/core').useActiveElement
|
||||
const useAnimate: typeof import('@vueuse/core').useAnimate
|
||||
const useArrayDifference: typeof import('@vueuse/core').useArrayDifference
|
||||
const useArrayEvery: typeof import('@vueuse/core').useArrayEvery
|
||||
const useArrayFilter: typeof import('@vueuse/core').useArrayFilter
|
||||
const useArrayFind: typeof import('@vueuse/core').useArrayFind
|
||||
const useArrayFindIndex: typeof import('@vueuse/core').useArrayFindIndex
|
||||
const useArrayFindLast: typeof import('@vueuse/core').useArrayFindLast
|
||||
const useArrayIncludes: typeof import('@vueuse/core').useArrayIncludes
|
||||
const useArrayJoin: typeof import('@vueuse/core').useArrayJoin
|
||||
const useArrayMap: typeof import('@vueuse/core').useArrayMap
|
||||
const useArrayReduce: typeof import('@vueuse/core').useArrayReduce
|
||||
const useArraySome: typeof import('@vueuse/core').useArraySome
|
||||
const useArrayUnique: typeof import('@vueuse/core').useArrayUnique
|
||||
const useAsyncQueue: typeof import('@vueuse/core').useAsyncQueue
|
||||
const useAsyncState: typeof import('@vueuse/core').useAsyncState
|
||||
const useAttrs: typeof import('vue').useAttrs
|
||||
const useBase64: typeof import('@vueuse/core').useBase64
|
||||
const useBattery: typeof import('@vueuse/core').useBattery
|
||||
const useBluetooth: typeof import('@vueuse/core').useBluetooth
|
||||
const useBreakpoints: typeof import('@vueuse/core').useBreakpoints
|
||||
const useBroadcastChannel: typeof import('@vueuse/core').useBroadcastChannel
|
||||
const useBrowserLocation: typeof import('@vueuse/core').useBrowserLocation
|
||||
const useCached: typeof import('@vueuse/core').useCached
|
||||
const useClipboard: typeof import('@vueuse/core').useClipboard
|
||||
const useClipboardItems: typeof import('@vueuse/core').useClipboardItems
|
||||
const useCloned: typeof import('@vueuse/core').useCloned
|
||||
const useColorMode: typeof import('@vueuse/core').useColorMode
|
||||
const useConfirmDialog: typeof import('@vueuse/core').useConfirmDialog
|
||||
const useCountdown: typeof import('@vueuse/core').useCountdown
|
||||
const useCounter: typeof import('@vueuse/core').useCounter
|
||||
const useCssModule: typeof import('vue').useCssModule
|
||||
const useCssVar: typeof import('@vueuse/core').useCssVar
|
||||
const useCssVars: typeof import('vue').useCssVars
|
||||
const useCurrentElement: typeof import('@vueuse/core').useCurrentElement
|
||||
const useCycleList: typeof import('@vueuse/core').useCycleList
|
||||
const useDark: typeof import('@vueuse/core').useDark
|
||||
const useDateFormat: typeof import('@vueuse/core').useDateFormat
|
||||
const useDebounce: typeof import('@vueuse/core').useDebounce
|
||||
const useDebounceFn: typeof import('@vueuse/core').useDebounceFn
|
||||
const useDebouncedRefHistory: typeof import('@vueuse/core').useDebouncedRefHistory
|
||||
const useDeviceMotion: typeof import('@vueuse/core').useDeviceMotion
|
||||
const useDeviceOrientation: typeof import('@vueuse/core').useDeviceOrientation
|
||||
const useDevicePixelRatio: typeof import('@vueuse/core').useDevicePixelRatio
|
||||
const useDevicesList: typeof import('@vueuse/core').useDevicesList
|
||||
const useDisplayMedia: typeof import('@vueuse/core').useDisplayMedia
|
||||
const useDocumentVisibility: typeof import('@vueuse/core').useDocumentVisibility
|
||||
const useDraggable: typeof import('@vueuse/core').useDraggable
|
||||
const useDropZone: typeof import('@vueuse/core').useDropZone
|
||||
const useElementBounding: typeof import('@vueuse/core').useElementBounding
|
||||
const useElementByPoint: typeof import('@vueuse/core').useElementByPoint
|
||||
const useElementHover: typeof import('@vueuse/core').useElementHover
|
||||
const useElementSize: typeof import('@vueuse/core').useElementSize
|
||||
const useElementVisibility: typeof import('@vueuse/core').useElementVisibility
|
||||
const useEventBus: typeof import('@vueuse/core').useEventBus
|
||||
const useEventListener: typeof import('@vueuse/core').useEventListener
|
||||
const useEventSource: typeof import('@vueuse/core').useEventSource
|
||||
const useEyeDropper: typeof import('@vueuse/core').useEyeDropper
|
||||
const useFavicon: typeof import('@vueuse/core').useFavicon
|
||||
const useFetch: typeof import('@vueuse/core').useFetch
|
||||
const useFileDialog: typeof import('@vueuse/core').useFileDialog
|
||||
const useFileSystemAccess: typeof import('@vueuse/core').useFileSystemAccess
|
||||
const useFocus: typeof import('@vueuse/core').useFocus
|
||||
const useFocusWithin: typeof import('@vueuse/core').useFocusWithin
|
||||
const useFps: typeof import('@vueuse/core').useFps
|
||||
const useFullscreen: typeof import('@vueuse/core').useFullscreen
|
||||
const useGamepad: typeof import('@vueuse/core').useGamepad
|
||||
const useGeolocation: typeof import('@vueuse/core').useGeolocation
|
||||
const useId: typeof import('vue').useId
|
||||
const useIdle: typeof import('@vueuse/core').useIdle
|
||||
const useImage: typeof import('@vueuse/core').useImage
|
||||
const useInfiniteScroll: typeof import('@vueuse/core').useInfiniteScroll
|
||||
const useIntersectionObserver: typeof import('@vueuse/core').useIntersectionObserver
|
||||
const useInterval: typeof import('@vueuse/core').useInterval
|
||||
const useIntervalFn: typeof import('@vueuse/core').useIntervalFn
|
||||
const useKeyModifier: typeof import('@vueuse/core').useKeyModifier
|
||||
const useLastChanged: typeof import('@vueuse/core').useLastChanged
|
||||
const useLink: typeof import('vue-router').useLink
|
||||
const useLocalStorage: typeof import('@vueuse/core').useLocalStorage
|
||||
const useMagicKeys: typeof import('@vueuse/core').useMagicKeys
|
||||
const useManualRefHistory: typeof import('@vueuse/core').useManualRefHistory
|
||||
const useMediaControls: typeof import('@vueuse/core').useMediaControls
|
||||
const useMediaQuery: typeof import('@vueuse/core').useMediaQuery
|
||||
const useMemoize: typeof import('@vueuse/core').useMemoize
|
||||
const useMemory: typeof import('@vueuse/core').useMemory
|
||||
const useModel: typeof import('vue').useModel
|
||||
const useMounted: typeof import('@vueuse/core').useMounted
|
||||
const useMouse: typeof import('@vueuse/core').useMouse
|
||||
const useMouseInElement: typeof import('@vueuse/core').useMouseInElement
|
||||
const useMousePressed: typeof import('@vueuse/core').useMousePressed
|
||||
const useMutationObserver: typeof import('@vueuse/core').useMutationObserver
|
||||
const useNavigatorLanguage: typeof import('@vueuse/core').useNavigatorLanguage
|
||||
const useNetwork: typeof import('@vueuse/core').useNetwork
|
||||
const useNow: typeof import('@vueuse/core').useNow
|
||||
const useObjectUrl: typeof import('@vueuse/core').useObjectUrl
|
||||
const useOffsetPagination: typeof import('@vueuse/core').useOffsetPagination
|
||||
const useOnline: typeof import('@vueuse/core').useOnline
|
||||
const usePageLeave: typeof import('@vueuse/core').usePageLeave
|
||||
const useParallax: typeof import('@vueuse/core').useParallax
|
||||
const useParentElement: typeof import('@vueuse/core').useParentElement
|
||||
const usePerformanceObserver: typeof import('@vueuse/core').usePerformanceObserver
|
||||
const usePermission: typeof import('@vueuse/core').usePermission
|
||||
const usePointer: typeof import('@vueuse/core').usePointer
|
||||
const usePointerLock: typeof import('@vueuse/core').usePointerLock
|
||||
const usePointerSwipe: typeof import('@vueuse/core').usePointerSwipe
|
||||
const usePreferredColorScheme: typeof import('@vueuse/core').usePreferredColorScheme
|
||||
const usePreferredContrast: typeof import('@vueuse/core').usePreferredContrast
|
||||
const usePreferredDark: typeof import('@vueuse/core').usePreferredDark
|
||||
const usePreferredLanguages: typeof import('@vueuse/core').usePreferredLanguages
|
||||
const usePreferredReducedMotion: typeof import('@vueuse/core').usePreferredReducedMotion
|
||||
const usePreferredReducedTransparency: typeof import('@vueuse/core').usePreferredReducedTransparency
|
||||
const usePrevious: typeof import('@vueuse/core').usePrevious
|
||||
const useRafFn: typeof import('@vueuse/core').useRafFn
|
||||
const useRefHistory: typeof import('@vueuse/core').useRefHistory
|
||||
const useResizeObserver: typeof import('@vueuse/core').useResizeObserver
|
||||
const useRoute: typeof import('vue-router').useRoute
|
||||
const useRouter: typeof import('vue-router').useRouter
|
||||
const useSSRWidth: typeof import('@vueuse/core').useSSRWidth
|
||||
const useScreenOrientation: typeof import('@vueuse/core').useScreenOrientation
|
||||
const useScreenSafeArea: typeof import('@vueuse/core').useScreenSafeArea
|
||||
const useScriptTag: typeof import('@vueuse/core').useScriptTag
|
||||
const useScroll: typeof import('@vueuse/core').useScroll
|
||||
const useScrollLock: typeof import('@vueuse/core').useScrollLock
|
||||
const useSessionStorage: typeof import('@vueuse/core').useSessionStorage
|
||||
const useShare: typeof import('@vueuse/core').useShare
|
||||
const useSlots: typeof import('vue').useSlots
|
||||
const useSorted: typeof import('@vueuse/core').useSorted
|
||||
const useSpeechRecognition: typeof import('@vueuse/core').useSpeechRecognition
|
||||
const useSpeechSynthesis: typeof import('@vueuse/core').useSpeechSynthesis
|
||||
const useStepper: typeof import('@vueuse/core').useStepper
|
||||
const useStorage: typeof import('@vueuse/core').useStorage
|
||||
const useStorageAsync: typeof import('@vueuse/core').useStorageAsync
|
||||
const useStyleTag: typeof import('@vueuse/core').useStyleTag
|
||||
const useSupported: typeof import('@vueuse/core').useSupported
|
||||
const useSwipe: typeof import('@vueuse/core').useSwipe
|
||||
const useTemplateRef: typeof import('vue').useTemplateRef
|
||||
const useTemplateRefsList: typeof import('@vueuse/core').useTemplateRefsList
|
||||
const useTextDirection: typeof import('@vueuse/core').useTextDirection
|
||||
const useTextSelection: typeof import('@vueuse/core').useTextSelection
|
||||
const useTextareaAutosize: typeof import('@vueuse/core').useTextareaAutosize
|
||||
const useThrottle: typeof import('@vueuse/core').useThrottle
|
||||
const useThrottleFn: typeof import('@vueuse/core').useThrottleFn
|
||||
const useThrottledRefHistory: typeof import('@vueuse/core').useThrottledRefHistory
|
||||
const useTimeAgo: typeof import('@vueuse/core').useTimeAgo
|
||||
const useTimeAgoIntl: typeof import('@vueuse/core').useTimeAgoIntl
|
||||
const useTimeout: typeof import('@vueuse/core').useTimeout
|
||||
const useTimeoutFn: typeof import('@vueuse/core').useTimeoutFn
|
||||
const useTimeoutPoll: typeof import('@vueuse/core').useTimeoutPoll
|
||||
const useTimestamp: typeof import('@vueuse/core').useTimestamp
|
||||
const useTitle: typeof import('@vueuse/core').useTitle
|
||||
const useToNumber: typeof import('@vueuse/core').useToNumber
|
||||
const useToString: typeof import('@vueuse/core').useToString
|
||||
const useToggle: typeof import('@vueuse/core').useToggle
|
||||
const useTransition: typeof import('@vueuse/core').useTransition
|
||||
const useUrlSearchParams: typeof import('@vueuse/core').useUrlSearchParams
|
||||
const useUserMedia: typeof import('@vueuse/core').useUserMedia
|
||||
const useVModel: typeof import('@vueuse/core').useVModel
|
||||
const useVModels: typeof import('@vueuse/core').useVModels
|
||||
const useVibrate: typeof import('@vueuse/core').useVibrate
|
||||
const useVirtualList: typeof import('@vueuse/core').useVirtualList
|
||||
const useWakeLock: typeof import('@vueuse/core').useWakeLock
|
||||
const useWebNotification: typeof import('@vueuse/core').useWebNotification
|
||||
const useWebSocket: typeof import('@vueuse/core').useWebSocket
|
||||
const useWebWorker: typeof import('@vueuse/core').useWebWorker
|
||||
const useWebWorkerFn: typeof import('@vueuse/core').useWebWorkerFn
|
||||
const useWindowFocus: typeof import('@vueuse/core').useWindowFocus
|
||||
const useWindowScroll: typeof import('@vueuse/core').useWindowScroll
|
||||
const useWindowSize: typeof import('@vueuse/core').useWindowSize
|
||||
const watch: typeof import('vue').watch
|
||||
const watchArray: typeof import('@vueuse/core').watchArray
|
||||
const watchAtMost: typeof import('@vueuse/core').watchAtMost
|
||||
const watchDebounced: typeof import('@vueuse/core').watchDebounced
|
||||
const watchDeep: typeof import('@vueuse/core').watchDeep
|
||||
const watchEffect: typeof import('vue').watchEffect
|
||||
const watchIgnorable: typeof import('@vueuse/core').watchIgnorable
|
||||
const watchImmediate: typeof import('@vueuse/core').watchImmediate
|
||||
const watchOnce: typeof import('@vueuse/core').watchOnce
|
||||
const watchPausable: typeof import('@vueuse/core').watchPausable
|
||||
const watchPostEffect: typeof import('vue').watchPostEffect
|
||||
const watchSyncEffect: typeof import('vue').watchSyncEffect
|
||||
const watchThrottled: typeof import('@vueuse/core').watchThrottled
|
||||
const watchTriggerable: typeof import('@vueuse/core').watchTriggerable
|
||||
const watchWithFilter: typeof import('@vueuse/core').watchWithFilter
|
||||
const whenever: typeof import('@vueuse/core').whenever
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
@@ -57,26 +57,26 @@ const refreshActiveAddress = () => {
|
||||
}
|
||||
|
||||
const syncList = async () => {
|
||||
const list: TabInfo[] = await (window as any).ipcAPI.tabs.list()
|
||||
const list: TabInfo[] = await (window as any).api.tabs.list()
|
||||
tabs.splice(0, tabs.length, ...list)
|
||||
if (!activeId.value && list.length > 0) activeId.value = list[0].id
|
||||
refreshActiveAddress()
|
||||
}
|
||||
|
||||
const onNewTab = async () => {
|
||||
const info: TabInfo = await (window as any).ipcAPI.tabs.create('about:blank')
|
||||
const info: TabInfo = await (window as any).api.tabs.create('about:blank')
|
||||
activeId.value = info.id
|
||||
}
|
||||
|
||||
const onSwitch = async (id: string) => {
|
||||
await (window as any).ipcAPI.tabs.switch(id)
|
||||
await (window as any).api.tabs.switch(id)
|
||||
activeId.value = id
|
||||
refreshActiveAddress()
|
||||
}
|
||||
|
||||
const onCloseTab = async () => {
|
||||
if (!activeId.value) return
|
||||
await (window as any).ipcAPI.tabs.close(activeId.value)
|
||||
await (window as any).api.tabs.close(activeId.value)
|
||||
}
|
||||
|
||||
const normalizeUrl = (u: string) => {
|
||||
@@ -90,46 +90,46 @@ const onNavigate = async () => {
|
||||
if (!activeId.value || !address.value) return
|
||||
const url = normalizeUrl(address.value)
|
||||
if (!url) return
|
||||
await (window as any).ipcAPI.tabs.navigate(activeId.value, url)
|
||||
await (window as any).api.tabs.navigate(activeId.value, url)
|
||||
}
|
||||
|
||||
const onReload = async () => {
|
||||
if (!activeId.value) return
|
||||
await (window as any).ipcAPI.tabs.reload(activeId.value)
|
||||
await (window as any).api.tabs.reload(activeId.value)
|
||||
}
|
||||
|
||||
const onBack = async () => {
|
||||
if (!activeId.value) return
|
||||
await (window as any).ipcAPI.tabs.back(activeId.value)
|
||||
await (window as any).api.tabs.back(activeId.value)
|
||||
}
|
||||
|
||||
const onForward = async () => {
|
||||
if (!activeId.value) return
|
||||
await (window as any).ipcAPI.tabs.forward(activeId.value)
|
||||
await (window as any).api.tabs.forward(activeId.value)
|
||||
}
|
||||
|
||||
const onCloseTabId = async (id: string) => {
|
||||
await (window as any).ipcAPI.tabs.close(id)
|
||||
await (window as any).api.tabs.close(id)
|
||||
}
|
||||
|
||||
const onCloseWindow = () => (window as any).ipcAPI.window.close()
|
||||
const onMinimizeWindow = () => (window as any).ipcAPI.window.minimize()
|
||||
const onMaximizeWindow = () => (window as any).ipcAPI.window.maximize()
|
||||
const onCloseWindow = () => (window as any).api.window.close()
|
||||
const onMinimizeWindow = () => (window as any).api.window.minimize()
|
||||
const onMaximizeWindow = () => (window as any).api.window.maximize()
|
||||
|
||||
onMounted(async () => {
|
||||
await syncList()
|
||||
; (window as any).ipcAPI.tabs.on('tab-created', (info: TabInfo) => {
|
||||
; (window as any).api.tabs.on('tab-created', (info: TabInfo) => {
|
||||
const i = tabs.findIndex(t => t.id === info.id)
|
||||
if (i === -1) tabs.push(info)
|
||||
activeId.value = info.id
|
||||
refreshActiveAddress()
|
||||
})
|
||||
; (window as any).ipcAPI.tabs.on('tab-updated', (info: TabInfo) => {
|
||||
; (window as any).api.tabs.on('tab-updated', (info: TabInfo) => {
|
||||
const i = tabs.findIndex(t => t.id === info.id)
|
||||
if (i >= 0) tabs[i] = info
|
||||
if (activeId.value === info.id) refreshActiveAddress()
|
||||
})
|
||||
; (window as any).ipcAPI.tabs.on('tab-closed', ({ tabId }: { tabId: string }) => {
|
||||
; (window as any).api.tabs.on('tab-closed', ({ tabId }: { tabId: string }) => {
|
||||
const i = tabs.findIndex(t => t.id === tabId)
|
||||
if (i >= 0) tabs.splice(i, 1)
|
||||
if (activeId.value === tabId) {
|
||||
@@ -138,7 +138,7 @@ onMounted(async () => {
|
||||
refreshActiveAddress()
|
||||
}
|
||||
})
|
||||
; (window as any).ipcAPI.tabs.on('tab-switched', ({ tabId }: { tabId: string }) => {
|
||||
; (window as any).api.tabs.on('tab-switched', ({ tabId }: { tabId: string }) => {
|
||||
activeId.value = tabId
|
||||
refreshActiveAddress()
|
||||
})
|
||||
|
||||
@@ -103,7 +103,7 @@ tab-switched: { tabId: TabId }
|
||||
1. 核心能力(主进程 + IPC + 预加载)
|
||||
- 实现 `TabManager` 与全部导航方法
|
||||
- 注册 IPC(tabs/bookmarks/plugins)与广播
|
||||
- 预加载扩展 `window.ipcAPI.tabs/*`、事件订阅封装
|
||||
- 预加载扩展 `window.api.tabs/*`、事件订阅封装
|
||||
2. 渲染层界面
|
||||
- 新建 `BrowserLayout` 与基础组件(TabBar、AddressBar、Controls)
|
||||
- 打通地址栏与导航;同步标题与加载状态
|
||||
|
||||
7
src/renderer/env.d.ts
vendored
7
src/renderer/env.d.ts
vendored
@@ -1,7 +0,0 @@
|
||||
declare module "@store/counter";
|
||||
declare module "@utils/request";
|
||||
declare module "@assets/images/*";
|
||||
declare module "@constant/rate";
|
||||
declare module "@constant/menus";
|
||||
declare module "@remixicon/vue";
|
||||
declare module "vue-router";
|
||||
@@ -1,12 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bg {
|
||||
background: linear-gradient( 180deg, #EFF6FF 0%, #F5F7FA 40%);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import "./index.css";
|
||||
import "./styles/index.css";
|
||||
import { createApp } from "vue";
|
||||
import { createPinia } from "pinia";
|
||||
import router from "./router";
|
||||
@@ -16,9 +16,7 @@ app.use(createPinia());
|
||||
|
||||
// 使用 Vue Router
|
||||
app.use(router);
|
||||
app.use(ElementPlus, {
|
||||
locale,
|
||||
})
|
||||
app.use(ElementPlus, { locale })
|
||||
|
||||
// 挂载应用到 DOM
|
||||
app.mount("#app");
|
||||
|
||||
12
src/renderer/styles/index.css
Normal file
12
src/renderer/styles/index.css
Normal file
@@ -0,0 +1,12 @@
|
||||
@import "tailwindcss";
|
||||
@import "./theme/index.css";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bg {
|
||||
background: linear-gradient(180deg, #EFF6FF 0%, #F5F7FA 40%);
|
||||
}
|
||||
126
src/renderer/styles/theme/dark.css
Normal file
126
src/renderer/styles/theme/dark.css
Normal file
@@ -0,0 +1,126 @@
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--primary-color: #07C160;
|
||||
--bg-color: #1E1E1E;
|
||||
--bg-secondary: #2C2C2C;
|
||||
|
||||
--text-primary: #E0E0E0;
|
||||
--text-secondary: #A0A0A0;
|
||||
|
||||
--bubble-self: var(--primary-color);
|
||||
--bubble-others: #3A3A3A;
|
||||
--input-bg: #333333;
|
||||
--ripple-color: var(--text-secondary);
|
||||
--ripple-opacity: 0.2;
|
||||
}
|
||||
|
||||
pre code.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 1em
|
||||
}
|
||||
code.hljs {
|
||||
padding: 3px 5px
|
||||
}
|
||||
/*!
|
||||
Theme: GitHub Dark
|
||||
Description: Dark theme as seen on github.com
|
||||
Author: github.com
|
||||
Maintainer: @Hirse
|
||||
Updated: 2021-05-15
|
||||
|
||||
Outdated base version: https://github.com/primer/github-syntax-dark
|
||||
Current colors taken from GitHub's CSS
|
||||
*/
|
||||
.hljs {
|
||||
color: var(--text-primary);
|
||||
background: var(--input-bg);
|
||||
}
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-variable.language_ {
|
||||
/* prettylights-syntax-keyword */
|
||||
color: #ff7b72
|
||||
}
|
||||
.hljs-title,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-title.function_ {
|
||||
/* prettylights-syntax-entity */
|
||||
color: #d2a8ff
|
||||
}
|
||||
.hljs-attr,
|
||||
.hljs-attribute,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-operator,
|
||||
.hljs-variable,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-id {
|
||||
/* prettylights-syntax-constant */
|
||||
color: #79c0ff
|
||||
}
|
||||
.hljs-regexp,
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-string {
|
||||
/* prettylights-syntax-string */
|
||||
color: #a5d6ff
|
||||
}
|
||||
.hljs-built_in,
|
||||
.hljs-symbol {
|
||||
/* prettylights-syntax-variable */
|
||||
color: #ffa657
|
||||
}
|
||||
.hljs-comment,
|
||||
.hljs-code,
|
||||
.hljs-formula {
|
||||
/* prettylights-syntax-comment */
|
||||
color: #8b949e
|
||||
}
|
||||
.hljs-name,
|
||||
.hljs-quote,
|
||||
.hljs-selector-tag,
|
||||
.hljs-selector-pseudo {
|
||||
/* prettylights-syntax-entity-tag */
|
||||
color: #7ee787
|
||||
}
|
||||
.hljs-subst {
|
||||
/* prettylights-syntax-storage-modifier-import */
|
||||
color: #c9d1d9
|
||||
}
|
||||
.hljs-section {
|
||||
/* prettylights-syntax-markup-heading */
|
||||
color: #1f6feb;
|
||||
font-weight: bold
|
||||
}
|
||||
.hljs-bullet {
|
||||
/* prettylights-syntax-markup-list */
|
||||
color: #f2cc60
|
||||
}
|
||||
.hljs-emphasis {
|
||||
/* prettylights-syntax-markup-italic */
|
||||
color: #c9d1d9;
|
||||
font-style: italic
|
||||
}
|
||||
.hljs-strong {
|
||||
/* prettylights-syntax-markup-bold */
|
||||
color: #c9d1d9;
|
||||
font-weight: bold
|
||||
}
|
||||
.hljs-addition {
|
||||
/* prettylights-syntax-markup-inserted */
|
||||
color: #aff5b4;
|
||||
background-color: #033a16
|
||||
}
|
||||
.hljs-deletion {
|
||||
/* prettylights-syntax-markup-deleted */
|
||||
color: #ffdcd7;
|
||||
background-color: #67060c
|
||||
}
|
||||
}
|
||||
18
src/renderer/styles/theme/index.css
Normal file
18
src/renderer/styles/theme/index.css
Normal file
@@ -0,0 +1,18 @@
|
||||
@import './dark.css';
|
||||
@import './light.css';
|
||||
|
||||
@theme {
|
||||
--color-primary: var(--primary-color);
|
||||
--color-primary-light: var(--primary-color-light);
|
||||
--color-primary-dark: var(--primary-color-dark);
|
||||
--color-primary-hover: var(--primary-color-hover);
|
||||
--color-primary-active: var(--primary-color-active);
|
||||
--color-primary-subtle: var(--primary-color-subtle);
|
||||
--color-main: var(--bg-color);
|
||||
--color-secondary: var(--bg-secondary);
|
||||
--color-input: var(--input-bg);
|
||||
--color-bubble-self: var(--bubble-self);
|
||||
--color-bubble-others: var(--bubble-others);
|
||||
--color-tx-primary: var(--text-primary);
|
||||
--color-tx-secondary: var(--text-secondary);
|
||||
}
|
||||
129
src/renderer/styles/theme/light.css
Normal file
129
src/renderer/styles/theme/light.css
Normal file
@@ -0,0 +1,129 @@
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--primary-color: #07C160;
|
||||
--bg-color: #FFFFFF;
|
||||
--bg-secondary: #F5F5F5;
|
||||
--text-primary: #000000;
|
||||
--text-secondary: #7F7F7F;
|
||||
|
||||
--header-bg: var(--primary-color);
|
||||
--bubble-self: var(--primary-color);
|
||||
--bubble-others: #FFFFFF;
|
||||
--input-bg: #F0F0F0;
|
||||
--ripple-color: var(--text-secondary);
|
||||
--ripple-opacity: 0.2;
|
||||
}
|
||||
|
||||
pre code.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 1em
|
||||
}
|
||||
code.hljs {
|
||||
padding: 3px 5px
|
||||
}
|
||||
/*!
|
||||
Theme: GitHub
|
||||
Description: Light theme as seen on github.com
|
||||
Author: github.com
|
||||
Maintainer: @Hirse
|
||||
Updated: 2021-05-15
|
||||
|
||||
Outdated base version: https://github.com/primer/github-syntax-light
|
||||
Current colors taken from GitHub's CSS
|
||||
*/
|
||||
.hljs {
|
||||
/* color: #24292e;
|
||||
background: #ffffff */
|
||||
|
||||
color: var(--text-primary);
|
||||
background: var(--input-bg);
|
||||
}
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-variable.language_ {
|
||||
/* prettylights-syntax-keyword */
|
||||
color: #d73a49
|
||||
}
|
||||
.hljs-title,
|
||||
.hljs-title.class_,
|
||||
.hljs-title.class_.inherited__,
|
||||
.hljs-title.function_ {
|
||||
/* prettylights-syntax-entity */
|
||||
color: #6f42c1
|
||||
}
|
||||
.hljs-attr,
|
||||
.hljs-attribute,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-operator,
|
||||
.hljs-variable,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-id {
|
||||
/* prettylights-syntax-constant */
|
||||
color: #005cc5
|
||||
}
|
||||
.hljs-regexp,
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-string {
|
||||
/* prettylights-syntax-string */
|
||||
color: #032f62
|
||||
}
|
||||
.hljs-built_in,
|
||||
.hljs-symbol {
|
||||
/* prettylights-syntax-variable */
|
||||
color: #e36209
|
||||
}
|
||||
.hljs-comment,
|
||||
.hljs-code,
|
||||
.hljs-formula {
|
||||
/* prettylights-syntax-comment */
|
||||
color: #6a737d
|
||||
}
|
||||
.hljs-name,
|
||||
.hljs-quote,
|
||||
.hljs-selector-tag,
|
||||
.hljs-selector-pseudo {
|
||||
/* prettylights-syntax-entity-tag */
|
||||
color: #22863a
|
||||
}
|
||||
.hljs-subst {
|
||||
/* prettylights-syntax-storage-modifier-import */
|
||||
color: #24292e
|
||||
}
|
||||
.hljs-section {
|
||||
/* prettylights-syntax-markup-heading */
|
||||
color: #005cc5;
|
||||
font-weight: bold
|
||||
}
|
||||
.hljs-bullet {
|
||||
/* prettylights-syntax-markup-list */
|
||||
color: #735c0f
|
||||
}
|
||||
.hljs-emphasis {
|
||||
/* prettylights-syntax-markup-italic */
|
||||
color: #24292e;
|
||||
font-style: italic
|
||||
}
|
||||
.hljs-strong {
|
||||
/* prettylights-syntax-markup-bold */
|
||||
color: #24292e;
|
||||
font-weight: bold
|
||||
}
|
||||
.hljs-addition {
|
||||
/* prettylights-syntax-markup-inserted */
|
||||
color: #22863a;
|
||||
background-color: #f0fff4
|
||||
}
|
||||
.hljs-deletion {
|
||||
/* prettylights-syntax-markup-deleted */
|
||||
color: #b31d28;
|
||||
background-color: #ffeef0
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ const onSubmit = async () => {
|
||||
// const token = res && (res.token || res.data?.token || res.access_token);
|
||||
// if (!token) throw new Error("登录失败");
|
||||
// localStorage.setItem("token", token);
|
||||
// await (window as any).ipcAPI.app.setFrameless('/home')
|
||||
// await (window as any).api.app.setFrameless('/home')
|
||||
router.push('/home');
|
||||
} finally {
|
||||
// loading.value = false;
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
export enum IPCChannel {
|
||||
APP_MINIMIZE ='app:minimize',
|
||||
APP_MAXIMIZE ='app:maximize',
|
||||
APP_QUIT ='app:quit',
|
||||
FILE_READ = 'file:read',
|
||||
FILE_WRITE = 'file:write',
|
||||
GET_WINDOW_ID='get-window-id',
|
||||
CUSTOM_EVENT ='custom:event',
|
||||
TIME_UPDATE = 'time:update'
|
||||
}
|
||||
|
||||
// 定义每个通道的参数和返回值类型
|
||||
export interface IPCTypings {
|
||||
// 同步通信
|
||||
[IPCChannel.APP_MINIMIZE]: {
|
||||
params: [window:number]
|
||||
return: {success: boolean, error?: string}
|
||||
}
|
||||
[IPCChannel.APP_MAXIMIZE]: {
|
||||
params: [window:number]
|
||||
return: {success: boolean, error?: string}
|
||||
}
|
||||
[IPCChannel.GET_WINDOW_ID]: {
|
||||
params: []
|
||||
return: number
|
||||
}
|
||||
|
||||
// 异步通信
|
||||
[IPCChannel.FILE_READ]: {
|
||||
params: [filePath: string]
|
||||
return: Promise<{success: boolean, data?: string, error?: string}>
|
||||
}
|
||||
[IPCChannel.FILE_WRITE]: {
|
||||
params: [filePath: string, content: string]
|
||||
return: Promise<{success: boolean, error?: string}>
|
||||
}
|
||||
|
||||
// 事件通信
|
||||
[IPCChannel.TIME_UPDATE]: {
|
||||
params: [time: string]
|
||||
return: void
|
||||
}
|
||||
[IPCChannel.CUSTOM_EVENT]: {
|
||||
params: [message: string]
|
||||
return: void
|
||||
}
|
||||
}
|
||||
|
||||
// 定义IPC API 接口
|
||||
export interface IPCAPI {
|
||||
invoke<T extends keyof IPCTypings>(channel: T, ...args: IPCTypings[T]['params']): IPCTypings[T]['return'],
|
||||
invokeAsync<T extends keyof IPCTypings>(channel: T, ...args: IPCTypings[T]['params']): IPCTypings[T]['return'],
|
||||
on<T extends keyof IPCTypings>(channel: T, callback: (...args: IPCTypings[T]['params']) => void): () => void
|
||||
send<T extends keyof IPCTypings>(channel: T, ...args: IPCTypings[T]['params']): void,
|
||||
getCurrentWindowId(): number,
|
||||
versions: NodeJS.ProcessVersions,
|
||||
external: {
|
||||
open: (url: string) => void
|
||||
},
|
||||
window: {
|
||||
minimize: () => void,
|
||||
maximize: () => void,
|
||||
close: () => void
|
||||
},
|
||||
app: {
|
||||
setFrameless: (route?: string) => void
|
||||
},
|
||||
tabs: {
|
||||
create: (url?: string) => void,
|
||||
list: () => void,
|
||||
navigate: (tabId: string, url: string) => void,
|
||||
reload: (tabId: string) => void,
|
||||
back: (tabId: string) => void,
|
||||
forward: (tabId: string) => void,
|
||||
switch: (tabId: string) => void,
|
||||
close: (tabId: string) => 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}>,
|
||||
logToMain: (logLevel: string, message: string) => void,
|
||||
// 打开新窗口
|
||||
openNewTab: (url: string) => Promise<void>,
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@@ -17,16 +17,17 @@
|
||||
"paths": {
|
||||
"@/*": ["src/renderer/*"],
|
||||
"@assets/*": ["src/assets/*"],
|
||||
"@common/*": ["src/common/*"],
|
||||
"@store/*": ["src/renderer/store/*"],
|
||||
"@constant/*": ["src/renderer/constant/*"],
|
||||
"@utils/*": ["src/renderer/utils/*"],
|
||||
"@api/*": ["src/renderer/api/*"],
|
||||
"@/types": ["src/renderer/types/index.ts"],
|
||||
"@modules/*": ["src/electron/main/modules/*"],
|
||||
"@modules/*": ["src/main/modules/*"],
|
||||
"@/shared/*": ["src/shared/*"],
|
||||
},
|
||||
"outDir": "dist",
|
||||
"moduleResolution": "bundler",
|
||||
"moduleResolution": "Bundler",
|
||||
"resolveJsonModule": true,
|
||||
"types": ["element-plus/global"]
|
||||
},
|
||||
@@ -34,7 +35,11 @@
|
||||
"src/**/*",
|
||||
"./package.json",
|
||||
"./forge.config.ts",
|
||||
"*.ts",
|
||||
"vite.renderer.config.ts"
|
||||
, "packages/electron-chrome-context-menu", "packages/chrome-ui" ]
|
||||
"forge.env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.d.ts",
|
||||
"vite.renderer.config.ts",
|
||||
"packages/electron-chrome-context-menu",
|
||||
"packages/chrome-ui"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { resolve } from "path";
|
||||
import electronBytecode from "./src/plugins/bytenode/vite-plugin-electron-encrypt";
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({
|
||||
plugins: [electronBytecode({ entry: ".vite/build/main.js", keepSource: false })],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": resolve(__dirname, "./src/electron"),
|
||||
"@modules": resolve(__dirname, "./src/electron/main/modules"),
|
||||
export default defineConfig( async () => {
|
||||
const electronBytecode = (await import("./src/plugins/bytenode/vite-plugin-electron-encrypt")).default
|
||||
|
||||
return {
|
||||
plugins: [electronBytecode({ entry: ".vite/build/main.js", keepSource: false })],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": resolve(__dirname, "./src/main"),
|
||||
'@common': resolve(__dirname, './src/common'),
|
||||
"@modules": resolve(__dirname, "./src/main/modules"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,9 +3,10 @@ import { resolve } from "path";
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": resolve(__dirname, "./src")
|
||||
"@": resolve(__dirname, "./src"),
|
||||
'@common': resolve(__dirname, './src/common'),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
import { resolve } from "path";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import { defineConfig } from "vite";
|
||||
import { defineConfig, type CSSOptions } from "vite";
|
||||
|
||||
// https://vitejs.dev/config
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
css: {
|
||||
postcss: {
|
||||
plugins: [require("tailwindcss"), require("autoprefixer")],
|
||||
export default defineConfig(async () => {
|
||||
const vue = (await import("@vitejs/plugin-vue")).default
|
||||
const tailwindcss = (await import('@tailwindcss/vite')).default;
|
||||
const autoImport = (await import('unplugin-auto-import/vite')).default;
|
||||
|
||||
return {
|
||||
plugins: [vue(), tailwindcss(), autoImport({
|
||||
imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
|
||||
dts: 'src/renderer/auto-imports.d.ts'
|
||||
})],
|
||||
|
||||
css: {
|
||||
transformer: 'lightningcss' as CSSOptions['transformer'],
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
preserveSymlinks: true,
|
||||
alias: {
|
||||
"@": resolve(__dirname, "./src/renderer"),
|
||||
"@assets": resolve(__dirname, "./src/assets"),
|
||||
"@store": resolve(__dirname, "./src/renderer/store"),
|
||||
"@constant": resolve(__dirname, "./src/renderer/constant"),
|
||||
"@utils": resolve(__dirname, "./src/renderer/utils"),
|
||||
"@api": resolve(__dirname, "./src/renderer/api"),
|
||||
"@/types": resolve(__dirname, "./src/renderer/types"),
|
||||
|
||||
resolve: {
|
||||
preserveSymlinks: true,
|
||||
alias: {
|
||||
"@": resolve(__dirname, "./src/renderer"),
|
||||
"@api": resolve(__dirname, "./src/renderer/api"),
|
||||
"@assets": resolve(__dirname, "./src/assets"),
|
||||
'@common': resolve(__dirname, './src/common'),
|
||||
"@constant": resolve(__dirname, "./src/renderer/constant"),
|
||||
"@store": resolve(__dirname, "./src/renderer/store"),
|
||||
"@utils": resolve(__dirname, "./src/renderer/utils"),
|
||||
"@/types": resolve(__dirname, "./src/renderer/types"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user