246 lines
7.4 KiB
TypeScript
246 lines
7.4 KiB
TypeScript
|
|
import { dialog, nativeTheme, shell } from 'electron'
|
|||
|
|
import { CheckFileOrDirExist, CopyFileOrFolder } from '../../../define/Tools/file'
|
|||
|
|
import path from 'path'
|
|||
|
|
import { errorMessage, successMessage } from '../../../public/generalTools'
|
|||
|
|
import { ErrorItem, SuccessItem } from '@/define/model/generalResponse'
|
|||
|
|
|
|||
|
|
/** 打开指定的文件夹的方法 */
|
|||
|
|
export type OpenFolderParams = {
|
|||
|
|
/** 是不是基于项目文件,是的话,会在项目文件夹的基础上进行拼接 */
|
|||
|
|
baseProject: boolean
|
|||
|
|
/** 判断是不是打开父文件夹 */
|
|||
|
|
dirFloder: boolean
|
|||
|
|
/** 文件路径,baseProject 为false,需要设置完整的文件路径 */
|
|||
|
|
folderPath: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 一些对electron接口的封装,配合业务逻辑 */
|
|||
|
|
export default class ElectronInterface {
|
|||
|
|
constructor() {}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 打开指定的文件,试用默认的打开方式
|
|||
|
|
* @param value
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
public async OpenFile(value: string): Promise<ErrorItem | SuccessItem> {
|
|||
|
|
if (!(await CheckFileOrDirExist(value))) {
|
|||
|
|
return errorMessage('文件/文件夹 不存在', 'SystemIpc_OPEN_FILE')
|
|||
|
|
}
|
|||
|
|
await shell.openPath(value)
|
|||
|
|
return successMessage(null, '打开指定的文件成功', 'SystemIpc_OPEN_FILE')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 深度复制文件夹内容到目标文件夹
|
|||
|
|
* @param source 源文件夹路径
|
|||
|
|
* @param destination 目标文件夹路径
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
public async CopyFolderContents(
|
|||
|
|
source: string,
|
|||
|
|
destination: string
|
|||
|
|
): Promise<ErrorItem | SuccessItem> {
|
|||
|
|
try {
|
|||
|
|
// 使用更完善的复制方法
|
|||
|
|
await CopyFileOrFolder(source, destination, false)
|
|||
|
|
|
|||
|
|
return successMessage(null, '复制文件夹内容成功', 'SystemIpc_COPY_FOLDER_CONTENTS')
|
|||
|
|
} catch (error: any) {
|
|||
|
|
return errorMessage(
|
|||
|
|
'复制文件夹内容错误,错误信息如下:' + error.message,
|
|||
|
|
'SystemIpc_COPY_FOLDER_CONTENTS'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 打开对应的文件夹
|
|||
|
|
* @param params
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
public async OpenFolder(params: OpenFolderParams) {
|
|||
|
|
try {
|
|||
|
|
let openFolder = ''
|
|||
|
|
if (params.baseProject) {
|
|||
|
|
openFolder = path.join(global.config.project_path, params.folderPath)
|
|||
|
|
}
|
|||
|
|
if (params.dirFloder) {
|
|||
|
|
openFolder = path.dirname(params.folderPath)
|
|||
|
|
}
|
|||
|
|
if (!openFolder) {
|
|||
|
|
openFolder = params.folderPath
|
|||
|
|
}
|
|||
|
|
// 判断文件夹是不是存在
|
|||
|
|
let isExist = await CheckFileOrDirExist(openFolder)
|
|||
|
|
if (!isExist) {
|
|||
|
|
throw new Error('文件夹不存在,请检查')
|
|||
|
|
}
|
|||
|
|
shell.openPath(openFolder)
|
|||
|
|
return successMessage(null, '打开成功')
|
|||
|
|
} catch (error: any) {
|
|||
|
|
return errorMessage('打开文件夹错误,错误信息如下:' + error.message, 'SystemIpc_OPEN_FOLDER')
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 选择单个指定文件后缀的文件
|
|||
|
|
* @param value 后缀列表
|
|||
|
|
*/
|
|||
|
|
public async SelectSingleFile(value: string[]): Promise<SuccessItem | ErrorItem> {
|
|||
|
|
try {
|
|||
|
|
let { filePaths } = await dialog.showOpenDialog({
|
|||
|
|
properties: ['openFile'],
|
|||
|
|
filters: [{ name: 'fileName', extensions: value }]
|
|||
|
|
})
|
|||
|
|
if (filePaths.length === 0) {
|
|||
|
|
throw new Error('没有选择的文件')
|
|||
|
|
}
|
|||
|
|
return successMessage(filePaths[0], '选择文件成功', 'SystemIpc_SelectSingleFile')
|
|||
|
|
} catch (error: any) {
|
|||
|
|
return errorMessage(
|
|||
|
|
'选择文件错误,错误信息如下:' + error.message,
|
|||
|
|
'SystemIpc_SelectSingleFile'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 选择多个指定文件后缀的文件
|
|||
|
|
* @param value 文件后缀列表
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
public async SelectMultipleFile(value: string[]): Promise<SuccessItem | ErrorItem> {
|
|||
|
|
try {
|
|||
|
|
const { filePaths } = await dialog.showOpenDialog({
|
|||
|
|
properties: ['openFile', 'multiSelections'],
|
|||
|
|
filters: [{ name: 'fileName', extensions: value }]
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if (filePaths.length === 0) {
|
|||
|
|
throw new Error('没有选择的文件')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return successMessage(filePaths, '选择文件成功', 'SystemIpc_SelectMultipleFile')
|
|||
|
|
} catch (error: any) {
|
|||
|
|
console.error('选择文件错误:', error) // 记录错误日志
|
|||
|
|
return errorMessage(
|
|||
|
|
'选择文件错误,错误信息如下:' + error.message,
|
|||
|
|
'SystemIpc_SelectMultipleFile'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 切换主题
|
|||
|
|
* @param theme 主题名称
|
|||
|
|
* @returns 返回当前是否使用深色模式
|
|||
|
|
*/
|
|||
|
|
public async ToggleTheme(theme: string) {
|
|||
|
|
if (theme != 'light' && theme != 'dark') {
|
|||
|
|
nativeTheme.themeSource = 'system'
|
|||
|
|
} else {
|
|||
|
|
nativeTheme.themeSource = theme
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nativeTheme.shouldUseDarkColors
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 选择单个文件夹
|
|||
|
|
* @param defaultPath 可选配置
|
|||
|
|
* @returns 成功返回选择的文件夹路径,失败返回错误信息
|
|||
|
|
*/
|
|||
|
|
public async SelectSingleFolder(defaultPath: string): Promise<SuccessItem | ErrorItem> {
|
|||
|
|
try {
|
|||
|
|
const { filePaths } = await dialog.showOpenDialog({
|
|||
|
|
properties: ['openDirectory'],
|
|||
|
|
defaultPath: defaultPath,
|
|||
|
|
title: '选择文件夹',
|
|||
|
|
buttonLabel: '选择文件夹'
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if (filePaths.length === 0) {
|
|||
|
|
throw new Error('没有选择任何文件夹')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return successMessage(filePaths[0], '选择文件夹成功', 'SystemIpc_SelectSingleFolder')
|
|||
|
|
} catch (error: any) {
|
|||
|
|
return errorMessage(
|
|||
|
|
'选择文件夹错误,错误信息如下:' + error.message,
|
|||
|
|
'SystemIpc_SelectSingleFolder'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 选择文件夹或指定后缀的文件
|
|||
|
|
* @param extensions 文件后缀列表(可选)
|
|||
|
|
* @returns
|
|||
|
|
*/
|
|||
|
|
public async SelectFolderOrFile(extensions?: string[]): Promise<SuccessItem | ErrorItem> {
|
|||
|
|
try {
|
|||
|
|
// 使用消息框让用户选择类型
|
|||
|
|
const choice = await dialog.showMessageBox({
|
|||
|
|
type: 'question',
|
|||
|
|
title: '选择类型',
|
|||
|
|
message: '请选择要选择的类型:',
|
|||
|
|
buttons: ['选择文件', '选择文件夹', '取消'],
|
|||
|
|
defaultId: 0,
|
|||
|
|
cancelId: 2
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if (choice.response === 2) {
|
|||
|
|
throw new Error('用户取消选择')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (choice.response === 0) {
|
|||
|
|
// 选择文件
|
|||
|
|
const result = await dialog.showOpenDialog({
|
|||
|
|
properties: ['openFile'],
|
|||
|
|
filters:
|
|||
|
|
extensions && extensions.length > 0
|
|||
|
|
? [
|
|||
|
|
{ name: 'Audio Files', extensions },
|
|||
|
|
{ name: 'All Files', extensions: ['*'] }
|
|||
|
|
]
|
|||
|
|
: [{ name: 'All Files', extensions: ['*'] }],
|
|||
|
|
title: '选择文件'
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if (result.filePaths.length === 0) {
|
|||
|
|
throw new Error('没有选择文件')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return successMessage(result.filePaths[0], '选择文件成功', 'SystemIpc_SelectFolderOrFile')
|
|||
|
|
} else {
|
|||
|
|
// 选择文件夹
|
|||
|
|
const result = await dialog.showOpenDialog({
|
|||
|
|
properties: ['openDirectory'],
|
|||
|
|
title: '选择文件夹'
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if (result.filePaths.length === 0) {
|
|||
|
|
throw new Error('没有选择文件夹')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return successMessage(result.filePaths[0], '选择文件夹成功', 'SystemIpc_SelectFolderOrFile')
|
|||
|
|
}
|
|||
|
|
} catch (error: any) {
|
|||
|
|
console.error('选择文件或文件夹错误:', error)
|
|||
|
|
return errorMessage(
|
|||
|
|
'选择文件或文件夹错误,错误信息如下:' + error.message,
|
|||
|
|
'SystemIpc_SelectFolderOrFile'
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 打开指定的URL
|
|||
|
|
* @param url
|
|||
|
|
*/
|
|||
|
|
public OpenUrl(url: string) {
|
|||
|
|
shell.openExternal(url)
|
|||
|
|
}
|
|||
|
|
}
|