Files
tunji2/electron/main.js
2026-06-01 17:28:00 +08:00

142 lines
3.2 KiB
JavaScript

import { app, BrowserWindow, dialog, ipcMain } from 'electron'
import { join } from 'path'
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs'
let mainWindow = null
const CONFIG_DIR = join(app.getPath('userData'), '.tunji')
const CONFIG_FILE = join(CONFIG_DIR, 'config.json')
function ensureConfigDir() {
if (!existsSync(CONFIG_DIR)) {
mkdirSync(CONFIG_DIR, { recursive: true })
}
}
function loadConfig() {
ensureConfigDir()
if (existsSync(CONFIG_FILE)) {
try {
return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'))
} catch {
return {}
}
}
return {}
}
function saveConfig(config) {
ensureConfigDir()
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8')
}
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
webPreferences: {
preload: join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
})
if (process.env.VITE_DEV_SERVER_URL) {
mainWindow.loadURL(process.env.VITE_DEV_SERVER_URL)
mainWindow.webContents.openDevTools()
} else {
mainWindow.loadFile(join(__dirname, '../dist/index.html'))
}
}
// IPC Handlers
ipcMain.handle('workspace:select', async () => {
const result = await dialog.showOpenDialog(mainWindow, {
properties: ['openDirectory'],
title: '选择工作目录',
})
if (result.canceled) return null
const workspacePath = result.filePaths[0]
const config = loadConfig()
config.workspace = workspacePath
saveConfig(config)
return workspacePath
})
ipcMain.handle('workspace:get', () => {
const config = loadConfig()
return config.workspace || null
})
ipcMain.handle('workspace:set', (_event, path) => {
const config = loadConfig()
config.workspace = path
saveConfig(config)
})
ipcMain.handle('workspace:ensure-structure', (_event, workspacePath) => {
const tunjiDir = join(workspacePath, '.tunji')
if (!existsSync(tunjiDir)) {
mkdirSync(tunjiDir, { recursive: true })
}
const configPath = join(tunjiDir, 'config.json')
if (!existsSync(configPath)) {
writeFileSync(configPath, JSON.stringify({ theme: 'light' }, null, 2), 'utf-8')
}
})
ipcMain.handle('file:read', (_event, filePath) => {
try {
return readFileSync(filePath, 'utf-8')
} catch {
return null
}
})
ipcMain.handle('file:write', (_event, filePath, content) => {
writeFileSync(filePath, content, 'utf-8')
})
ipcMain.handle('file:mkdir', (_event, dirPath) => {
try {
if (!existsSync(dirPath)) {
mkdirSync(dirPath, { recursive: true })
}
return true
} catch {
return false
}
})
ipcMain.handle('file:list', (_event, dirPath) => {
try {
const entries = readdirSync(dirPath, { withFileTypes: true })
return entries
.filter(e => !e.name.startsWith('.'))
.map(e => ({
name: e.name,
path: join(dirPath, e.name),
isDirectory: e.isDirectory(),
isFile: e.isFile(),
}))
} catch {
return []
}
})
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})