AIx_Smarttalk_WS/src/main/index.js

331 lines
9.8 KiB
JavaScript
Raw Normal View History

2024-10-25 14:38:32 +08:00
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,
2024-10-31 14:05:24 +08:00
minWidth: 1370,
2024-10-25 14:38:32 +08:00
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) // 如果窗口在所有工作区都可见
2024-10-29 14:26:09 +08:00
// mainWindow.maximize();
2024-10-25 14:38:32 +08:00
// 第三步: 开启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)}`)
})
}