AIx_Smarttalk_WS/src/main/index.js

331 lines
9.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)}`)
})
}