| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- import type { OpenDialogOptions, Event } from 'electron'
- import { dialog, ipcMain, shell, app } from 'electron'
- import * as fs from 'fs-extra'
- import * as path from 'path'
- /** 当前项目文件夹锁:持有一个项目内文件的句柄,防止用户删除项目文件夹 */
- let projectLockFd: number | null = null
- /**
- * 选择文件夹
- */
- export const choeseDirectory = async () => {
- const { canceled, filePaths } = await dialog.showOpenDialog({
- properties: ['openDirectory']
- })
- if (!canceled) {
- return filePaths[0]
- }
- return
- }
- /**
- * 选择文件
- */
- export const choeseFile = async (_e: Event, options: OpenDialogOptions = {}) => {
- const { canceled, filePaths } = await dialog.showOpenDialog({
- title: '选择文件',
- buttonLabel: '选择',
- ...options
- })
- if (!canceled) {
- return filePaths
- }
- return
- }
- /**
- * 保存文件
- */
- export const writeFile = async (_e: Event, filePath: string, content: string) => {
- return fs.writeFileSync(filePath, content)
- }
- /**
- * 读取文件
- */
- export const readFile = async (_e: Event, filePath: string, encoding: BufferEncoding) => {
- return fs.readFileSync(filePath, { encoding })
- }
- /**
- * 检查文件是否存在
- */
- export const checkFileExists = async (_e: Event, filePath: string) => {
- return fs.existsSync(filePath)
- }
- /**
- * 创建目录
- */
- export const createDirectory = async (_e: Event, directoryPath: string) => {
- return fs.mkdirSync(directoryPath, { recursive: true })
- }
- /**
- * 复制文件
- */
- export const copyFile = async (_e: Event, sourcePath: string, destinationPath: string) => {
- return fs.copyFileSync(sourcePath, destinationPath)
- }
- /**
- * 打开文件夹
- */
- export const openDir = async (
- _e: Event,
- directoryPath: string,
- cb: (err: NodeJS.ErrnoException | null, dir: fs.Dir) => void
- ) => {
- return fs.opendir(directoryPath, cb)
- }
- /**
- * 复制文件夹
- */
- export const cp = (_e: Event, sourcePath: string, destinationPath: string) => {
- return fs.cpSync(sourcePath, destinationPath)
- }
- /**
- * 删除文件
- */
- export const removeFile = (_e: Event, sourcePath: string) => {
- return fs.rmSync(sourcePath)
- }
- /**
- * 打开并锁定文件
- */
- export const openFile = (_e: Event, sourcePath: string, flag: string) => {
- return fs.openSync(sourcePath, flag || 'w')
- }
- /**
- * 关闭并解锁文件
- */
- export const closeFile = (_e: Event, fd: number) => {
- return fs.closeSync(fd)
- }
- /**
- * 修改文件名
- */
- export const renameFile = (_e: Event, sourcePath: string, targetPath: string) => {
- return fs.renameSync(sourcePath, targetPath)
- }
- /**
- * 资源管理器中打开
- * @param path 文件路径
- */
- export const openFileInExplorer = (_e: Event, path: string) => {
- return shell.showItemInFolder(path)
- }
- /**
- * 锁定项目文件夹:打开项目目录内的 project.ui 并保持句柄,防止用户在资源管理器中删除该文件夹
- * @param projectDir 项目根目录路径(如 D:\projects\myProject)
- */
- const lockProjectFolder = async (_e: Event, projectDir: string) => {
- if (projectLockFd !== null) {
- try {
- fs.closeSync(projectLockFd)
- } catch (_) {}
- projectLockFd = null
- }
- const lockFilePath = path.join(projectDir, 'project.ui')
- if (!fs.existsSync(lockFilePath)) return
- try {
- projectLockFd = fs.openSync(lockFilePath, 'r')
- } catch (_) {}
- }
- /**
- * 解锁项目文件夹:关闭句柄,允许用户删除项目文件夹
- */
- export const unlockProjectFolder = () => {
- if (projectLockFd !== null) {
- try {
- fs.closeSync(projectLockFd)
- } catch (_) {}
- projectLockFd = null
- }
- }
- export const copyTemplate = async (_e: Event, targetPath: string) => {
- const templatePaths = app.isPackaged
- ? [
- path.join(process.resourcesPath, 'template/src'),
- path.join(process.resourcesPath, 'app.asar.unpacked/resources/template/src')
- ]
- : [path.join(process.cwd(), 'resources/template/src')]
- const templatePath = templatePaths.find((item) => fs.existsSync(item))
- await fs.ensureDir(targetPath)
- if (templatePath) {
- await fs.copy(templatePath, targetPath)
- }
- await fs.ensureDir(path.join(targetPath, 'assets/images'))
- await fs.ensureDir(path.join(targetPath, 'assets/fonts'))
- await fs.ensureDir(path.join(targetPath, 'assets/others'))
- // .gitkeep占位文件 创建后移除
- await fs.remove(path.join(targetPath, 'assets/images/.gitkeep'))
- await fs.remove(path.join(targetPath, 'assets/others/.gitkeep'))
- }
- export function handleFile() {
- // 获取文件夹
- ipcMain.handle('get-directory', choeseDirectory)
- // 获取文件
- ipcMain.handle('get-file', choeseFile)
- // 创建文件夹
- ipcMain.handle('create-directory', createDirectory)
- // 复制文件夹
- ipcMain.handle('copy-directory', cp)
- // 写入文件
- ipcMain.handle('write-file', writeFile)
- // 读取文件
- ipcMain.handle('read-file', readFile)
- // 检查路径是否存在
- ipcMain.handle('check-file-path', checkFileExists)
- // 复制文件
- ipcMain.handle('copy-file', copyFile)
- // 删除文件
- ipcMain.handle('delete-file', removeFile)
- // 独占打开
- ipcMain.handle('exclusive-open', openFile)
- // 独占关闭
- ipcMain.handle('exclusive-close', closeFile)
- // 修改文件名
- ipcMain.handle('modify-file-name', renameFile)
- // 资源管理器中打开
- ipcMain.handle('open-file-in-explorer', openFileInExplorer)
- // 锁定/解锁项目文件夹(防止用户删除正在使用的项目目录)
- ipcMain.handle('lock-project-folder', lockProjectFolder)
- // 解锁项目文件夹
- ipcMain.handle('unlock-project-folder', unlockProjectFolder)
- // 复制模板文件
- ipcMain.handle('copy-template', copyTemplate)
- }
|