331 lines
9.8 KiB
JavaScript
331 lines
9.8 KiB
JavaScript
import { app, shell, BrowserWindow, ipcMain, session, BrowserView } from 'electron'
|
||
import { join } from 'path'
|
||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||
import icon from '../../resources/icon.png?asset'
|
||
import File from './file'
|
||
import Logger from './logger' // 日志封装
|
||
import chat from './chat' // chat封装
|
||
import Store from './store' // Store封装
|
||
import updateInit from './update'
|
||
// 代理 electron/remote
|
||
// 第一步:引入remote
|
||
import remote from '@electron/remote/main'
|
||
// 第二步: 初始化remote
|
||
remote.initialize()
|
||
// 日志配置-初始化(日志直接绑定到console上)
|
||
if(!is.dev) Logger.initialize()
|
||
// 持久化数据-初始化
|
||
Store.initialize()
|
||
|
||
File({ app, shell, BrowserWindow, ipcMain })
|
||
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
|
||
let mainWindow, loginWindow
|
||
|
||
const additionalData = {myKey:'ys_axi_smarttalk'}
|
||
const gotTheLock = app.requestSingleInstanceLock(additionalData)
|
||
|
||
if(!gotTheLock){
|
||
app.quit()
|
||
}else{
|
||
app.on('second-instance',(event,commandLine,workingDirectory,additionalData)=>{
|
||
//输入从第二个实例中接收到的数据
|
||
console.log(additionalData)
|
||
//有人试图运行第二个实例,我们应该关注我们的窗口
|
||
if(mainWindow){
|
||
if(mainWindow.isMinimized()) mainWindow.restore()
|
||
mainWindow.focus()
|
||
}
|
||
if(loginWindow){
|
||
if(loginWindow.isMinimized()) loginWindow.restore()
|
||
loginWindow.focus()
|
||
}
|
||
})
|
||
}
|
||
|
||
//登录窗口
|
||
function createLoginWindow() {
|
||
if (loginWindow) return
|
||
loginWindow = new BrowserWindow({
|
||
width: 888,
|
||
height: 520,
|
||
show: false,
|
||
frame: false,
|
||
autoHideMenuBar: true,
|
||
maximizable: false,
|
||
resizable: false,
|
||
icon: join(__dirname, '../../resources/logo2.ico'),
|
||
...(process.platform === 'linux' ? { icon } : {}),
|
||
webPreferences: {
|
||
defaultEncoding: 'utf-8',
|
||
preload: join(__dirname, '../preload/index.js'),
|
||
sandbox: false,
|
||
nodeIntegration: true,
|
||
contextIsolation: false // 沙箱取消
|
||
}
|
||
})
|
||
loginWindow.type = 'login' // 唯一标识
|
||
// handleUpdate(loginWindow,ipcMain)
|
||
// const loginURL = is.dev ? `http://localhost:5173/#/login` : `file://${__dirname}/index.html/#/login`
|
||
// loginWindow.loadURL(loginURL)
|
||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||
loginWindow.loadURL('http://localhost:5173/#/login')
|
||
} else {
|
||
loginWindow.loadFile(join(__dirname, '../renderer/index.html'), { hash: 'login' })
|
||
updateInit(loginWindow)
|
||
}
|
||
if (import.meta.env.VITE_SHOW_DEV_TOOLS === 'true') loginWindow.webContents.openDevTools()
|
||
loginWindow.once('ready-to-show', () => {
|
||
loginWindow.show()
|
||
})
|
||
|
||
loginWindow.on('closed', () => {
|
||
loginWindow = null
|
||
})
|
||
|
||
remote.enable(loginWindow.webContents)
|
||
}
|
||
//主窗口
|
||
function createMainWindow() {
|
||
mainWindow = new BrowserWindow({
|
||
width: 1350,
|
||
minWidth: 1370,
|
||
height: 700,
|
||
minHeight: 700,
|
||
show: false,
|
||
frame: false, // 无边框
|
||
autoHideMenuBar: true,
|
||
maximizable: false,
|
||
icon: join(__dirname, '../../resources/logo2.ico'),
|
||
...(process.platform === 'linux' ? { icon } : {}),
|
||
webPreferences: {
|
||
defaultEncoding: 'utf-8',
|
||
preload: join(__dirname, '../preload/index.js'),
|
||
sandbox: false,
|
||
// nodeIntegration: true,
|
||
nodeIntegration: true, // nodeApi调用
|
||
contextIsolation: false // 沙箱取消
|
||
// webSecurity: false // 跨域关闭
|
||
}
|
||
})
|
||
mainWindow.type = 'main' // 唯一标识
|
||
mainWindow.on('ready-to-show', () => {
|
||
mainWindow.show()
|
||
})
|
||
mainWindow.on('closed', () => {
|
||
setTimeout(() => {
|
||
// 延迟销毁
|
||
mainWindow = null
|
||
}, 1000)
|
||
// app.quit() // 主窗口关闭-结束所有进程
|
||
})
|
||
mainWindow.on('resize', () => {
|
||
const { width, height } = mainWindow.getBounds();
|
||
mainWindow.webContents.send('minWinResize', { width, height });
|
||
});
|
||
|
||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||
shell.openExternal(details.url)
|
||
return { action: 'deny' }
|
||
})
|
||
if (import.meta.env.VITE_SHOW_DEV_TOOLS === 'true') mainWindow.webContents.openDevTools()
|
||
|
||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
|
||
} else {
|
||
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
|
||
}
|
||
|
||
// mainWindow.setAlwaysOnTop(true, "screen-saver") // 将窗口设置为顶层窗口
|
||
// mainWindow.setVisibleOnAllWorkspaces(true) // 如果窗口在所有工作区都可见
|
||
// mainWindow.maximize();
|
||
// 第三步: 开启remote服务
|
||
remote.enable(mainWindow.webContents)
|
||
}
|
||
|
||
// 打开外部链接窗口
|
||
let linkWin = {}
|
||
async function createLinkWin(data) {
|
||
if (linkWin[data.key]) return
|
||
|
||
linkWin[data.key] = new BrowserWindow({
|
||
show: false,
|
||
frame: true,
|
||
maximizable: true,
|
||
autoHideMenuBar: true,
|
||
...(process.platform === 'linux' ? { icon } : {}),
|
||
webPreferences: {
|
||
defaultEncoding: 'utf-8',
|
||
sandbox: false,
|
||
nodeIntegration: true,
|
||
worldSafeExecuteJavaScript: true,
|
||
contextIsolation: true
|
||
}
|
||
})
|
||
linkWin[data.key].type = 'link'+data.key // 唯一标识
|
||
|
||
let cookieDetails = { ...data.cookieData }
|
||
await linkWin[data.key].webContents.session.cookies
|
||
.set(cookieDetails)
|
||
.then(() => {})
|
||
.catch((error) => {})
|
||
data.fullPath = data.fullPath.replaceAll('//', '/')
|
||
if (data.fullPath.indexOf('?') !== -1) {
|
||
data.fullPath += '&urlSource=smarttalk&t' + Date.now()
|
||
}else {
|
||
data.fullPath += '?urlSource=smarttalk&t' + Date.now()
|
||
}
|
||
linkWin[data.key].loadURL(data.fullPath)
|
||
|
||
linkWin[data.key].once('ready-to-show', () => {
|
||
linkWin[data.key].show()
|
||
linkWin[data.key].maximize()
|
||
})
|
||
linkWin[data.key].on('closed', () => {
|
||
linkWin[data.key] = null
|
||
delete linkWin[data.key]
|
||
})
|
||
}
|
||
|
||
// 初始化完成
|
||
app.on('ready', () => {
|
||
appWatchError() // 监听app错误
|
||
process.env.LANG = 'en_US.UTF-8'
|
||
// 设置应用程序用户模型标识符
|
||
electronApp.setAppUserModelId('com.electron')
|
||
|
||
//一个新的browserWindow 被创建时触发
|
||
app.on('browser-window-created', (_, window) => {
|
||
optimizer.watchWindowShortcuts(window)
|
||
})
|
||
|
||
//窗口 最大、最小、关闭
|
||
ipcMain.on('minimize-window', () => {
|
||
if (loginWindow) {
|
||
loginWindow.minimize()
|
||
}
|
||
if (mainWindow) {
|
||
mainWindow.minimize()
|
||
}
|
||
})
|
||
|
||
ipcMain.on('maximize-window', () => {
|
||
mainWindow.isMaximized() ? mainWindow.unmaximize() : mainWindow.maximize()
|
||
})
|
||
|
||
ipcMain.on('close-window', () => {
|
||
if (loginWindow) {
|
||
loginWindow.destroy()
|
||
}
|
||
if (mainWindow) {
|
||
mainWindow.close() // 先发出这个关闭指令
|
||
setTimeout(() => {
|
||
//
|
||
mainWindow.destroy()
|
||
}, 200)
|
||
}
|
||
})
|
||
|
||
// 打开主窗口
|
||
ipcMain.on('openMainWindow', () => {
|
||
if (!mainWindow) {
|
||
createMainWindow()
|
||
}
|
||
loginWindow.destroy()
|
||
loginWindow = null
|
||
})
|
||
// 打开登录窗口
|
||
ipcMain.on('openLoginWindow', () => {
|
||
if (!loginWindow) {
|
||
createLoginWindow()
|
||
}
|
||
mainWindow.destroy()
|
||
mainWindow = null
|
||
loginWindow.show()
|
||
loginWindow.focus()
|
||
})
|
||
|
||
//打开作业窗口
|
||
ipcMain.on('openWindow', (e, data) => {
|
||
createLinkWin(data)
|
||
})
|
||
// zdg: 消息监听
|
||
handleAll()
|
||
// 打开-登录窗口
|
||
createLoginWindow()
|
||
|
||
app.on('activate', function () {
|
||
if (BrowserWindow.getAllWindows().length === 0) createLoginWindow()
|
||
})
|
||
})
|
||
|
||
// Quit when all windows are closed, except on macOS. There, it's common
|
||
// for applications and their menu bar to stay active until the user quits
|
||
// explicitly with Cmd + Q.
|
||
app.on('window-all-closed', () => {
|
||
if (process.platform !== 'darwin') {
|
||
app.quit()
|
||
}
|
||
})
|
||
|
||
// 监听全局事件
|
||
function handleAll() {
|
||
const chatInstance = chat.initialize() // im-chat 实例
|
||
// 新窗口创建-监听
|
||
ipcMain.handle('new-window', (e, data) => {
|
||
const { id, type } = data
|
||
const win = BrowserWindow.fromId(id)
|
||
win.type = type // 绑定独立标识
|
||
remote.enable(win.webContents) // 开启远程服务
|
||
chatInstance.enable(win.webContents) // 开启im-chat
|
||
console.log(`主进程 [${type}]: 窗口注册-远程代理-完毕(${Date.now()})`)
|
||
})
|
||
// 用于监听-状态管理变化-同步所有窗口
|
||
ipcMain.handle('pinia-state-change', (e, storeName, jsonStr) => {
|
||
|
||
for(const curWin of BrowserWindow.getAllWindows()){
|
||
const id = curWin.webContents.id
|
||
const bool = id !== e.sender.id && !curWin.isDestroyed()
|
||
if (bool) { // 除了消息发送窗口和销毁的窗口 其他都发送
|
||
curWin.webContents.send('pinia-state-set', storeName, jsonStr)
|
||
}
|
||
}
|
||
})
|
||
// 用于监听-状态管理变化-初始同步
|
||
ipcMain.handle('pinia-state-init', (e, wid, storeName, jsonStr) => {
|
||
// console.log('pinia-state-init', jsonStr)
|
||
const win = BrowserWindow.fromId(wid)
|
||
win.webContents.send('pinia-state-set', storeName, jsonStr)
|
||
})
|
||
}
|
||
|
||
// app 崩溃监听器
|
||
function appWatchError() {
|
||
// 渲染进程崩溃
|
||
app.on('renderer-process-crashed', (event, webContents, killed) => {
|
||
console.error(
|
||
`APP-ERROR:renderer-process-crashed; event: ${JSON.stringify(event)}; webContents:${JSON.stringify(
|
||
webContents
|
||
)}; killed:${JSON.stringify(killed)}`
|
||
)
|
||
})
|
||
|
||
// GPU进程崩溃
|
||
app.on('gpu-process-crashed', (event, killed) => {
|
||
console.error(`APP-ERROR:gpu-process-crashed; event: ${JSON.stringify(event)}; killed: ${JSON.stringify(killed)}`)
|
||
})
|
||
|
||
// 渲染进程结束
|
||
app.on('render-process-gone', async (event, webContents, details) => {
|
||
console.error(
|
||
`APP-ERROR:render-process-gone; event: ${JSON.stringify(event)}; webContents:${JSON.stringify(
|
||
webContents
|
||
)}; details:${JSON.stringify(details)}`
|
||
)
|
||
})
|
||
|
||
// 子进程结束
|
||
app.on('child-process-gone', async (event, details) => {
|
||
console.error(`APP-ERROR:child-process-gone; event: ${JSON.stringify(event)}; details:${JSON.stringify(details)}`)
|
||
})
|
||
}
|