diff --git a/frontend/dist-electron/main.js b/frontend/dist-electron/main.js index 8c7c8ae..4a48150 100644 --- a/frontend/dist-electron/main.js +++ b/frontend/dist-electron/main.js @@ -38,8 +38,8 @@ const path = __importStar(require("path")); let mainWindow = null; function createWindow() { mainWindow = new electron_1.BrowserWindow({ - width: 1200, - height: 800, + width: 1600, + height: 900, minWidth: 800, minHeight: 600, icon: path.join(__dirname, '../public/AUTO_MAA.ico'), // 设置应用图标 @@ -73,6 +73,35 @@ electron_1.ipcMain.handle('open-dev-tools', () => { mainWindow.webContents.openDevTools({ mode: 'undocked' }); } }); +// 处理文件夹选择请求 +electron_1.ipcMain.handle('select-folder', async () => { + if (!mainWindow) + return null; + const result = await electron_1.dialog.showOpenDialog(mainWindow, { + properties: ['openDirectory'], + title: '选择文件夹' + }); + if (result.canceled) { + return null; + } + return result.filePaths[0]; +}); +// 处理文件选择请求 +electron_1.ipcMain.handle('select-file', async (event, filters = []) => { + if (!mainWindow) + return null; + const result = await electron_1.dialog.showOpenDialog(mainWindow, { + properties: ['openFile'], + title: '选择文件', + filters: filters.length > 0 ? filters : [ + { name: '所有文件', extensions: ['*'] } + ] + }); + if (result.canceled) { + return null; + } + return result.filePaths[0]; +}); electron_1.app.whenReady().then(createWindow); electron_1.app.on('window-all-closed', () => { if (process.platform !== 'darwin') diff --git a/frontend/dist-electron/preload.js b/frontend/dist-electron/preload.js index dec0df9..59fe621 100644 --- a/frontend/dist-electron/preload.js +++ b/frontend/dist-electron/preload.js @@ -6,5 +6,7 @@ window.addEventListener('DOMContentLoaded', () => { }); // 暴露安全的 API 给渲染进程 electron_1.contextBridge.exposeInMainWorld('electronAPI', { - openDevTools: () => electron_1.ipcRenderer.invoke('open-dev-tools') + openDevTools: () => electron_1.ipcRenderer.invoke('open-dev-tools'), + selectFolder: () => electron_1.ipcRenderer.invoke('select-folder'), + selectFile: (filters) => electron_1.ipcRenderer.invoke('select-file', filters) }); diff --git a/frontend/electron/main.ts b/frontend/electron/main.ts index 47e4375..9d549f8 100644 --- a/frontend/electron/main.ts +++ b/frontend/electron/main.ts @@ -1,12 +1,12 @@ -import { app, BrowserWindow, ipcMain } from 'electron' +import { app, BrowserWindow, ipcMain, dialog } from 'electron' import * as path from 'path' let mainWindow: BrowserWindow | null = null function createWindow() { mainWindow = new BrowserWindow({ - width: 1200, - height: 800, + width: 1600, + height: 900, minWidth: 800, minHeight: 600, icon: path.join(__dirname, '../public/AUTO_MAA.ico'), // 设置应用图标 @@ -44,6 +44,41 @@ ipcMain.handle('open-dev-tools', () => { } }) +// 处理文件夹选择请求 +ipcMain.handle('select-folder', async () => { + if (!mainWindow) return null + + const result = await dialog.showOpenDialog(mainWindow, { + properties: ['openDirectory'], + title: '选择文件夹' + }) + + if (result.canceled) { + return null + } + + return result.filePaths[0] +}) + +// 处理文件选择请求 +ipcMain.handle('select-file', async (event, filters = []) => { + if (!mainWindow) return null + + const result = await dialog.showOpenDialog(mainWindow, { + properties: ['openFile'], + title: '选择文件', + filters: filters.length > 0 ? filters : [ + { name: '所有文件', extensions: ['*'] } + ] + }) + + if (result.canceled) { + return null + } + + return result.filePaths[0] +}) + app.whenReady().then(createWindow) app.on('window-all-closed', () => { diff --git a/frontend/electron/preload.ts b/frontend/electron/preload.ts index d618e0a..38bcaae 100644 --- a/frontend/electron/preload.ts +++ b/frontend/electron/preload.ts @@ -6,5 +6,7 @@ window.addEventListener('DOMContentLoaded', () => { // 暴露安全的 API 给渲染进程 contextBridge.exposeInMainWorld('electronAPI', { - openDevTools: () => ipcRenderer.invoke('open-dev-tools') + openDevTools: () => ipcRenderer.invoke('open-dev-tools'), + selectFolder: () => ipcRenderer.invoke('select-folder'), + selectFile: (filters?: any[]) => ipcRenderer.invoke('select-file', filters) }) diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/public/AUTO_MAA.ico b/frontend/src/assets/AUTO_MAA.ico similarity index 100% rename from frontend/public/AUTO_MAA.ico rename to frontend/src/assets/AUTO_MAA.ico diff --git a/frontend/src/assets/AUTO_MAA.png b/frontend/src/assets/AUTO_MAA.png new file mode 100644 index 0000000..669770c Binary files /dev/null and b/frontend/src/assets/AUTO_MAA.png differ diff --git a/frontend/src/assets/MAA.png b/frontend/src/assets/MAA.png new file mode 100644 index 0000000..1af2759 Binary files /dev/null and b/frontend/src/assets/MAA.png differ diff --git a/frontend/src/components/AppLayout.vue b/frontend/src/components/AppLayout.vue index b9495f1..1504778 100644 --- a/frontend/src/components/AppLayout.vue +++ b/frontend/src/components/AppLayout.vue @@ -12,7 +12,7 @@
diff --git a/frontend/src/components/ScriptEditor.vue b/frontend/src/components/ScriptEditor.vue new file mode 100644 index 0000000..f1ba48a --- /dev/null +++ b/frontend/src/components/ScriptEditor.vue @@ -0,0 +1,340 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/ScriptTable.vue b/frontend/src/components/ScriptTable.vue new file mode 100644 index 0000000..53e1e47 --- /dev/null +++ b/frontend/src/components/ScriptTable.vue @@ -0,0 +1,567 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/composables/useScriptApi.ts b/frontend/src/composables/useScriptApi.ts new file mode 100644 index 0000000..998c8fd --- /dev/null +++ b/frontend/src/composables/useScriptApi.ts @@ -0,0 +1,208 @@ +import { ref } from 'vue' +import type { + ScriptType, + AddScriptResponse, + MAAScriptConfig, + GeneralScriptConfig, + GetScriptsResponse, + ScriptDetail, + ScriptIndexItem +} from '@/types/script' + +const API_BASE_URL = 'http://localhost:8000/api' + +export function useScriptApi() { + const loading = ref(false) + const error = ref(null) + + // 添加脚本 + const addScript = async (type: ScriptType): Promise => { + loading.value = true + error.value = null + + try { + const response = await fetch(`${API_BASE_URL}/add/scripts`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ type }), + }) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const data: AddScriptResponse = await response.json() + return data + } catch (err) { + error.value = err instanceof Error ? err.message : '添加脚本失败' + return null + } finally { + loading.value = false + } + } + + // 获取所有脚本 + const getScripts = async (): Promise => { + loading.value = true + error.value = null + + try { + const response = await fetch(`${API_BASE_URL}/get/scripts`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({}), // 传空对象获取全部脚本 + }) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const apiResponse: GetScriptsResponse = await response.json() + + // 转换API响应为前端需要的格式 + const scripts: ScriptDetail[] = apiResponse.index.map((item: ScriptIndexItem) => { + const config = apiResponse.data[item.uid] + const scriptType: ScriptType = item.type === 'MaaConfig' ? 'MAA' : 'General' + + // 从配置中获取脚本名称 + let name = '' + if (scriptType === 'MAA') { + name = (config as MAAScriptConfig).Info.Name || '未命名MAA脚本' + } else { + name = (config as GeneralScriptConfig).Info.Name || '未命名General脚本' + } + + return { + uid: item.uid, + type: scriptType, + name, + config, + createTime: new Date().toLocaleString() // 暂时使用当前时间,后续可从API获取 + } + }) + + return scripts + } catch (err) { + error.value = err instanceof Error ? err.message : '获取脚本列表失败' + return [] + } finally { + loading.value = false + } + } + + // 获取单个脚本 + const getScript = async (scriptId: string): Promise => { + loading.value = true + error.value = null + + try { + const response = await fetch(`${API_BASE_URL}/get/scripts`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ scriptId }), // 传scriptId获取单个脚本 + }) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const apiResponse: GetScriptsResponse = await response.json() + + // 检查是否有数据返回 + if (apiResponse.index.length === 0) { + throw new Error('脚本不存在') + } + + const item = apiResponse.index[0] + const config = apiResponse.data[item.uid] + const scriptType: ScriptType = item.type === 'MaaConfig' ? 'MAA' : 'General' + + // 从配置中获取脚本名称 + let name = '' + if (scriptType === 'MAA') { + name = (config as MAAScriptConfig).Info.Name || '未命名MAA脚本' + } else { + name = (config as GeneralScriptConfig).Info.Name || '未命名General脚本' + } + + return { + uid: item.uid, + type: scriptType, + name, + config, + createTime: new Date().toLocaleString() // 暂时使用当前时间,后续可从API获取 + } + } catch (err) { + error.value = err instanceof Error ? err.message : '获取脚本详情失败' + return null + } finally { + loading.value = false + } + } + + // 更新脚本(暂时模拟) + const updateScript = async (scriptId: string, config: MAAScriptConfig | GeneralScriptConfig) => { + loading.value = true + error.value = null + + try { + const response = await fetch(`${API_BASE_URL}/update/scripts/${scriptId}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(config), + }) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + return await response.json() + } catch (err) { + error.value = err instanceof Error ? err.message : '更新脚本失败' + return null + } finally { + loading.value = false + } + } + + // 删除脚本(暂时模拟) + const deleteScript = async (scriptId: string) => { + loading.value = true + error.value = null + + try { + const response = await fetch(`${API_BASE_URL}/delete/scripts/${scriptId}`, { + method: 'DELETE', + }) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + return await response.json() + } catch (err) { + error.value = err instanceof Error ? err.message : '删除脚本失败' + return null + } finally { + loading.value = false + } + } + + return { + loading, + error, + addScript, + getScripts, + getScript, + updateScript, + deleteScript, + } +} \ No newline at end of file diff --git a/frontend/src/composables/useTheme.ts b/frontend/src/composables/useTheme.ts index a7ccdc4..7801c8a 100644 --- a/frontend/src/composables/useTheme.ts +++ b/frontend/src/composables/useTheme.ts @@ -61,6 +61,91 @@ const updateTheme = () => { } else { document.documentElement.classList.remove('dark') } + + // 更新CSS变量 + updateCSSVariables() +} + +// 更新CSS变量 +const updateCSSVariables = () => { + const root = document.documentElement + const primaryColor = themeColors[themeColor.value] + + if (isDark.value) { + // 深色模式变量 + root.style.setProperty('--ant-color-primary', primaryColor) + root.style.setProperty('--ant-color-primary-hover', lightenColor(primaryColor, 10)) + root.style.setProperty('--ant-color-primary-bg', `${primaryColor}1a`) + root.style.setProperty('--ant-color-text', 'rgba(255, 255, 255, 0.88)') + root.style.setProperty('--ant-color-text-secondary', 'rgba(255, 255, 255, 0.65)') + root.style.setProperty('--ant-color-text-tertiary', 'rgba(255, 255, 255, 0.45)') + root.style.setProperty('--ant-color-bg-container', '#141414') + root.style.setProperty('--ant-color-bg-layout', '#000000') + root.style.setProperty('--ant-color-bg-elevated', '#1f1f1f') + root.style.setProperty('--ant-color-border', '#424242') + root.style.setProperty('--ant-color-border-secondary', '#303030') + root.style.setProperty('--ant-color-error', '#ff4d4f') + root.style.setProperty('--ant-color-success', '#52c41a') + root.style.setProperty('--ant-color-warning', '#faad14') + } else { + // 浅色模式变量 + root.style.setProperty('--ant-color-primary', primaryColor) + root.style.setProperty('--ant-color-primary-hover', darkenColor(primaryColor, 10)) + root.style.setProperty('--ant-color-primary-bg', `${primaryColor}1a`) + root.style.setProperty('--ant-color-text', 'rgba(0, 0, 0, 0.88)') + root.style.setProperty('--ant-color-text-secondary', 'rgba(0, 0, 0, 0.65)') + root.style.setProperty('--ant-color-text-tertiary', 'rgba(0, 0, 0, 0.45)') + root.style.setProperty('--ant-color-bg-container', '#ffffff') + root.style.setProperty('--ant-color-bg-layout', '#f5f5f5') + root.style.setProperty('--ant-color-bg-elevated', '#ffffff') + root.style.setProperty('--ant-color-border', '#d9d9d9') + root.style.setProperty('--ant-color-border-secondary', '#f0f0f0') + root.style.setProperty('--ant-color-error', '#ff4d4f') + root.style.setProperty('--ant-color-success', '#52c41a') + root.style.setProperty('--ant-color-warning', '#faad14') + } +} + +// 颜色工具函数 +const hexToRgb = (hex: string) => { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null +} + +const rgbToHex = (r: number, g: number, b: number) => { + return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1) +} + +const lightenColor = (hex: string, percent: number) => { + const rgb = hexToRgb(hex) + if (!rgb) return hex + + const { r, g, b } = rgb + const amount = Math.round(2.55 * percent) + + return rgbToHex( + Math.min(255, r + amount), + Math.min(255, g + amount), + Math.min(255, b + amount) + ) +} + +const darkenColor = (hex: string, percent: number) => { + const rgb = hexToRgb(hex) + if (!rgb) return hex + + const { r, g, b } = rgb + const amount = Math.round(2.55 * percent) + + return rgbToHex( + Math.max(0, r - amount), + Math.max(0, g - amount), + Math.max(0, b - amount) + ) } // 监听系统主题变化 @@ -71,8 +156,9 @@ mediaQuery.addEventListener('change', () => { } }) -// 监听主题模式变化 +// 监听主题模式和颜色变化 watch(themeMode, updateTheme, { immediate: true }) +watch(themeColor, updateTheme) // Ant Design 主题配置 const antdTheme = computed(() => ({ diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 1b5091d..e04c5a1 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -18,6 +18,12 @@ const routes: RouteRecordRaw[] = [ component: () => import('../views/Scripts.vue'), meta: { title: '脚本管理' }, }, + { + path: '/scripts/:id/edit', + name: 'ScriptEdit', + component: () => import('../views/ScriptEdit.vue'), + meta: { title: '编辑脚本' }, + }, { path: '/plans', name: 'Plans', @@ -48,6 +54,12 @@ const routes: RouteRecordRaw[] = [ component: () => import('../views/Settings.vue'), meta: { title: '设置' }, }, + { + path: '/test', + name: 'Test', + component: () => import('../views/TestScript.vue'), + meta: { title: '测试' }, + }, ] const router = createRouter({ diff --git a/frontend/src/style.css b/frontend/src/style.css index f691315..e3edf68 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -4,76 +4,91 @@ font-weight: 400; color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - + font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + + /* 默认浅色模式 CSS 变量 */ + --ant-color-primary: #1677ff; + --ant-color-primary-hover: #4096ff; + --ant-color-primary-bg: #1677ff1a; + --ant-color-text: rgba(0, 0, 0, 0.88); + --ant-color-text-secondary: rgba(0, 0, 0, 0.65); + --ant-color-text-tertiary: rgba(0, 0, 0, 0.45); + --ant-color-bg-container: #ffffff; + --ant-color-bg-layout: #f5f5f5; + --ant-color-bg-elevated: #ffffff; + --ant-color-border: #d9d9d9; + --ant-color-border-secondary: #f0f0f0; + --ant-color-error: #ff4d4f; + --ant-color-success: #52c41a; + --ant-color-warning: #faad14; } -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; +/* 深色模式默认变量 */ +:root.dark { + --ant-color-primary: #1677ff; + --ant-color-primary-hover: #4096ff; + --ant-color-primary-bg: #1677ff1a; + --ant-color-text: rgba(255, 255, 255, 0.88); + --ant-color-text-secondary: rgba(255, 255, 255, 0.65); + --ant-color-text-tertiary: rgba(255, 255, 255, 0.45); + --ant-color-bg-container: #141414; + --ant-color-bg-layout: #000000; + --ant-color-bg-elevated: #1f1f1f; + --ant-color-border: #424242; + --ant-color-border-secondary: #303030; + --ant-color-error: #ff4d4f; + --ant-color-success: #52c41a; + --ant-color-warning: #faad14; } -a:hover { - color: #535bf2; + +* { + box-sizing: border-box; } body { margin: 0; - display: flex; - place-items: center; min-width: 320px; min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -.card { - padding: 2em; + background-color: var(--ant-color-bg-layout); + color: var(--ant-color-text); } #app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; + width: 100%; + height: 100vh; + overflow: hidden; } -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } +/* 链接样式 */ +a { + color: var(--ant-color-primary); + text-decoration: none; + transition: color 0.3s ease; +} + +a:hover { + color: var(--ant-color-primary-hover); +} + +/* 滚动条样式 */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: var(--ant-color-bg-layout); +} + +::-webkit-scrollbar-thumb { + background: var(--ant-color-border); + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--ant-color-border-secondary); } diff --git a/frontend/src/types/electron.ts b/frontend/src/types/electron.ts new file mode 100644 index 0000000..eda4ab0 --- /dev/null +++ b/frontend/src/types/electron.ts @@ -0,0 +1,14 @@ +// Electron API 类型定义 +export interface ElectronAPI { + openDevTools: () => Promise + selectFolder: () => Promise + selectFile: (filters?: { name: string; extensions: string[] }[]) => Promise +} + +declare global { + interface Window { + electronAPI: ElectronAPI + } +} + +export {} \ No newline at end of file diff --git a/frontend/src/types/script.ts b/frontend/src/types/script.ts new file mode 100644 index 0000000..d022e6c --- /dev/null +++ b/frontend/src/types/script.ts @@ -0,0 +1,171 @@ +// 脚本类型定义 +export type ScriptType = 'MAA' | 'General' + +// MAA脚本配置 +export interface MAAScriptConfig { + Info: { + Name: string + Path: string + } + Run: { + ADBSearchRange: number + AnnihilationTimeLimit: number + AnnihilationWeeklyLimit: boolean + ProxyTimesLimit: number + RoutineTimeLimit: number + RunTimesLimit: number + TaskTransitionMethod: string + } + SubConfigsInfo: { + UserData: { + instances: any[] + } + } +} + +// General脚本配置 +export interface GeneralScriptConfig { + Game: { + Arguments: string + Enabled: boolean + IfForceClose: boolean + Path: string + Style: string + WaitTime: number + } + Info: { + Name: string + RootPath: string + } + Run: { + ProxyTimesLimit: number + RunTimeLimit: number + RunTimesLimit: number + } + Script: { + Arguments: string + ConfigPath: string + ConfigPathMode: string + ErrorLog: string + IfTrackProcess: boolean + LogPath: string + LogPathFormat: string + LogTimeEnd: number + LogTimeStart: number + LogTimeFormat: string + ScriptPath: string + SuccessLog: string + UpdateConfigMode: string + } + SubConfigsInfo: { + UserData: { + instances: any[] + } + } +} + +// 脚本基础信息 +export interface Script { + id: string + type: ScriptType + name: string + config: MAAScriptConfig | GeneralScriptConfig + users: User[] +} + +// 用户配置 +export interface User { + id: string + name: string + Data: { + CustomInfrastPlanIndex: string + IfPassCheck: boolean + LastAnnihilationDate: string + LastProxyDate: string + LastSklandDate: string + ProxyTimes: number + } + Info: { + Annihilation: string + Id: string + IfSkland: boolean + InfrastMode: string + MedicineNumb: number + Mode: string + Name: string + Notes: string + Password: string + RemainedDay: number + Routine: boolean + SeriesNumb: string + Server: string + SklandToken: string + Stage: string + StageMode: string + Stage_1: string + Stage_2: string + Stage_3: string + Stage_Remain: string + Status: boolean + } + Notify: { + CompanyWebHookBotUrl: string + Enabled: boolean + IfCompanyWebHookBot: boolean + IfSendMail: boolean + IfSendSixStar: boolean + IfSendStatistic: boolean + IfServerChan: boolean + ServerChanChannel: string + ServerChanKey: string + ServerChanTag: string + ToAddress: string + } + Task: { + IfAutoRoguelike: boolean + IfBase: boolean + IfCombat: boolean + IfMall: boolean + IfMission: boolean + IfReclamation: boolean + IfRecruiting: boolean + IfWakeUp: boolean + } + QFluentWidgets: { + ThemeColor: string + ThemeMode: string + } +} + +// API响应类型 +export interface AddScriptResponse { + code: number + status: string + message: string + scriptId: string + data: MAAScriptConfig | GeneralScriptConfig +} + +// 脚本索引项 +export interface ScriptIndexItem { + uid: string + type: 'MaaConfig' | 'GeneralConfig' +} + +// 获取脚本API响应 +export interface GetScriptsResponse { + code: number + status: string + message: string + index: ScriptIndexItem[] + data: Record +} + +// 脚本详情(用于前端展示) +export interface ScriptDetail { + uid: string + type: ScriptType + name: string + config: MAAScriptConfig | GeneralScriptConfig + createTime?: string +} \ No newline at end of file diff --git a/frontend/src/views/ScriptEdit.vue b/frontend/src/views/ScriptEdit.vue new file mode 100644 index 0000000..900c3b4 --- /dev/null +++ b/frontend/src/views/ScriptEdit.vue @@ -0,0 +1,1549 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/views/Scripts.vue b/frontend/src/views/Scripts.vue index 9607084..5fb3f29 100644 --- a/frontend/src/views/Scripts.vue +++ b/frontend/src/views/Scripts.vue @@ -1,12 +1,591 @@ + + \ No newline at end of file diff --git a/frontend/src/views/TestScript.vue b/frontend/src/views/TestScript.vue new file mode 100644 index 0000000..e341389 --- /dev/null +++ b/frontend/src/views/TestScript.vue @@ -0,0 +1,90 @@ + + + \ No newline at end of file diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 0f54dd5..70b004c 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -3,7 +3,9 @@ declare global { interface Window { electronAPI?: { - openDevTools: () => void + openDevTools: () => Promise + selectFolder: () => Promise + selectFile: (filters?: Array<{ name: string; extensions: string[] }>) => Promise } } }