光伏pc端应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

213 lines
9.1 KiB

/*
* @Author: 李皓 hao_li_work@163.com
* @Date: 2026-07-28 16:31:45
* @LastEditors: 李皓 hao_li_work@163.com
* @LastEditTime: 2026-07-28 16:44:07
* @FilePath: \pc\preload.js
* @Description:
* @Version: 1.0.0
*/
const { contextBridge, ipcRenderer } = require('electron')
const nodeNet = require('net')
const dns = require('dns')
function tryConnect(host, port, timeout) {
return new Promise((resolve) => {
const socket = new nodeNet.Socket()
socket.setTimeout(timeout)
socket.on('connect', () => { socket.destroy(); resolve(true) })
socket.on('error', () => { socket.destroy(); resolve(false) })
socket.on('timeout', () => { socket.destroy(); resolve(false) })
socket.connect(port, host)
})
}
const net = {
async ping(host, timeout) {
try {
await dns.promises.resolve(host)
} catch {
return false
}
for (const port of [443, 80]) {
if (await tryConnect(host, port, timeout)) return true
}
return false
}
}
const appCallbacks = {
onFileWrite: null,
onFileRead: null,
onFileDelete: null,
onPageModeChanged: null
}
ipcRenderer.on('app-file-write-callback', (_event, token, filePath, success, err) => {
if (typeof appCallbacks.onFileWrite === 'function') appCallbacks.onFileWrite(token, filePath, success, err)
})
ipcRenderer.on('app-file-read-callback', (_event, token, filePath, content) => {
if (typeof appCallbacks.onFileRead === 'function') appCallbacks.onFileRead(token, filePath, content)
})
ipcRenderer.on('app-file-delete-callback', (_event, token, filePath, success) => {
if (typeof appCallbacks.onFileDelete === 'function') appCallbacks.onFileDelete(token, filePath, success)
})
ipcRenderer.on('app-page-mode', (_event, mode) => {
if (typeof appCallbacks.onPageModeChanged === 'function') appCallbacks.onPageModeChanged(mode)
})
const app = {
clearCache() { return ipcRenderer.sendSync('app-clear-cache-sync') },
versionCode() { return ipcRenderer.sendSync('app-version-code-sync') },
setCache(key, value) { return ipcRenderer.sendSync('set-cache-sync', key, value) },
getCache(key) { return ipcRenderer.sendSync('get-cache-sync', key) },
offlinePage() { ipcRenderer.send('app-offline-page') },
onlinePage() { ipcRenderer.send('app-online-page') },
fileList(dir) { return ipcRenderer.sendSync('app-file-list-sync', dir) },
fileWriteString(filePath, content, token) { ipcRenderer.send('app-file-write-string', filePath, content, token) },
fileReadString(filePath, token) { ipcRenderer.send('app-file-read-string', filePath, token) },
fileDelete(filePath, token) { ipcRenderer.send('app-file-delete', filePath, token) },
get onFileWrite() { return appCallbacks.onFileWrite },
set onFileWrite(fn) { appCallbacks.onFileWrite = fn },
get onFileRead() { return appCallbacks.onFileRead },
set onFileRead(fn) { appCallbacks.onFileRead = fn },
get onFileDelete() { return appCallbacks.onFileDelete },
set onFileDelete(fn) { appCallbacks.onFileDelete = fn },
get onPageModeChanged() { return appCallbacks.onPageModeChanged },
set onPageModeChanged(fn) { appCallbacks.onPageModeChanged = fn }
}
const sensorCallbacks = {
onSensorAttached: null,
onSensorDetached: null,
onOperationCallback: null
}
ipcRenderer.on('sensor-attached', (_event, data) => {
if (typeof sensorCallbacks.onSensorAttached === 'function') sensorCallbacks.onSensorAttached(data.id, data.name)
})
ipcRenderer.on('sensor-detached', (_event, data) => {
if (typeof sensorCallbacks.onSensorDetached === 'function') sensorCallbacks.onSensorDetached(data.id, data.name)
})
ipcRenderer.on('sensor-operation-callback', (_event, id, opId, result) => {
if (typeof sensorCallbacks.onOperationCallback === 'function') sensorCallbacks.onOperationCallback(id, opId, result)
})
const sensor = {
initAll() { return ipcRenderer.sendSync('sensor-init-all-sync') },
flush() { return ipcRenderer.sendSync('sensor-flush-sync') },
sensorList() { return ipcRenderer.sendSync('sensor-list-sync') },
init(id) { return ipcRenderer.sendSync('sensor-init-sync', id) },
open(id) { return ipcRenderer.sendSync('sensor-open-sync', id) },
close(id) { return ipcRenderer.sendSync('sensor-close-sync', id) },
operation(id, opId, args) { return ipcRenderer.sendSync('sensor-operation-sync', id, opId, args) },
operationAsync(id, opId, args) { ipcRenderer.send('sensor-operation-async', id, opId, args) },
get onSensorAttached() { return sensorCallbacks.onSensorAttached },
set onSensorAttached(fn) { sensorCallbacks.onSensorAttached = fn },
get onSensorDetached() { return sensorCallbacks.onSensorDetached },
set onSensorDetached(fn) { sensorCallbacks.onSensorDetached = fn },
get onOperationCallback() { return sensorCallbacks.onOperationCallback },
set onOperationCallback(fn) { sensorCallbacks.onOperationCallback = fn }
}
const appSensorCallbacks = { onValueCallback: null }
const appSensor = {
version: '1.0.0',
name: 'appSensor',
open() { return ipcRenderer.sendSync('app-sensor-open-sync') },
close() { return ipcRenderer.sendSync('app-sensor-close-sync') },
isOpen() { return ipcRenderer.sendSync('app-sensor-is-open-sync') },
get onValueCallback() { return appSensorCallbacks.onValueCallback },
set onValueCallback(fn) { appSensorCallbacks.onValueCallback = fn }
}
ipcRenderer.on('sensor-data', (_event, data) => {
if (typeof appSensorCallbacks.onValueCallback === 'function') appSensorCallbacks.onValueCallback(data)
})
const appLocationCallbacks = {
onOpened: null,
onLocationChanged: null
}
ipcRenderer.on('app-location-opened', (_event, status) => {
if (typeof appLocationCallbacks.onOpened === 'function') appLocationCallbacks.onOpened(status)
})
ipcRenderer.on('app-location-changed', (_event, location) => {
if (typeof appLocationCallbacks.onLocationChanged === 'function') appLocationCallbacks.onLocationChanged(location)
})
const appLocation = {
isSupport() { return ipcRenderer.sendSync('app-location-is-support-sync') },
isOpen() { return ipcRenderer.sendSync('app-location-is-open-sync') },
open() { ipcRenderer.send('app-location-open') },
close() { ipcRenderer.send('app-location-close') },
get onOpened() { return appLocationCallbacks.onOpened },
set onOpened(fn) { appLocationCallbacks.onOpened = fn },
get onLocationChanged() { return appLocationCallbacks.onLocationChanged },
set onLocationChanged(fn) { appLocationCallbacks.onLocationChanged = fn }
}
const usbSerialCallbacks = {
onDeviceAttached: null,
onDeviceDetached: null,
onDeviceDiscovered: null,
onDeviceProbeResult: null,
onDeviceOpened: null,
onDeviceState: null,
onDeviceData: null
}
for (const [eventName, cbName] of [
['usb-callback-device-attached', 'onDeviceAttached'],
['usb-callback-device-detached', 'onDeviceDetached'],
['usb-callback-device-discovered', 'onDeviceDiscovered'],
['usb-callback-device-probe-result', 'onDeviceProbeResult'],
['usb-callback-device-opened', 'onDeviceOpened'],
['usb-callback-device-state', 'onDeviceState'],
['usb-callback-device-data', 'onDeviceData']
]) {
ipcRenderer.on(eventName, (_event, jsonStr) => {
const cb = usbSerialCallbacks[cbName]
if (typeof cb === 'function') cb(jsonStr)
})
}
const usbSerial = {
get onDeviceAttached() { return usbSerialCallbacks.onDeviceAttached },
set onDeviceAttached(fn) { usbSerialCallbacks.onDeviceAttached = fn },
get onDeviceDetached() { return usbSerialCallbacks.onDeviceDetached },
set onDeviceDetached(fn) { usbSerialCallbacks.onDeviceDetached = fn },
get onDeviceDiscovered() { return usbSerialCallbacks.onDeviceDiscovered },
set onDeviceDiscovered(fn) { usbSerialCallbacks.onDeviceDiscovered = fn },
get onDeviceProbeResult() { return usbSerialCallbacks.onDeviceProbeResult },
set onDeviceProbeResult(fn) { usbSerialCallbacks.onDeviceProbeResult = fn },
get onDeviceOpened() { return usbSerialCallbacks.onDeviceOpened },
set onDeviceOpened(fn) { usbSerialCallbacks.onDeviceOpened = fn },
get onDeviceState() { return usbSerialCallbacks.onDeviceState },
set onDeviceState(fn) { usbSerialCallbacks.onDeviceState = fn },
get onDeviceData() { return usbSerialCallbacks.onDeviceData },
set onDeviceData(fn) { usbSerialCallbacks.onDeviceData = fn },
startDiscovery() { ipcRenderer.send('usb-start-discovery') },
stopDiscovery() { ipcRenderer.send('usb-stop-discovery') },
getDiscoveredDevices() { return ipcRenderer.invoke('usb-get-discovered') },
deviceProbe(deviceName, portNumber, baudRate, hexCmd, timeoutMs) {
ipcRenderer.send('usb-device-probe', { deviceName, portNumber, baudRate, hexCmd, timeoutMs })
},
deviceOpen(deviceName, portNumber, baudRate) {
ipcRenderer.send('usb-device-open', { deviceName, portNumber, baudRate })
},
deviceClose(deviceName, portNumber) {
ipcRenderer.send('usb-device-close', { deviceName, portNumber })
},
deviceWrite(deviceName, portNumber, hexData) {
ipcRenderer.send('usb-device-write', { deviceName, portNumber, hexData })
}
}
contextBridge.exposeInMainWorld('app', app)
contextBridge.exposeInMainWorld('net', net)
contextBridge.exposeInMainWorld('sensor', sensor)
contextBridge.exposeInMainWorld('appSensor', appSensor)
contextBridge.exposeInMainWorld('appLocation', appLocation)
contextBridge.exposeInMainWorld('usbSerial', usbSerial)