Compare commits
47 Commits
5ec87f67c9
...
d66df5e2cf
Author | SHA1 | Date |
---|---|---|
|
d66df5e2cf | |
|
7d53c34651 | |
|
a929a7b47d | |
|
7c8b2477d5 | |
|
95f8374a13 | |
|
1b9ff88922 | |
|
a08559f55f | |
|
b71aaf4ff7 | |
|
9646a4ae8c | |
|
f697d427ad | |
|
34108a2186 | |
|
4d0d6c2ab9 | |
|
cd708e9eb9 | |
|
902ba88c2f | |
|
fa641c5a28 | |
|
68e29d3ace | |
|
16c8adc1f4 | |
|
57cf6523ef | |
|
e97b8516ae | |
|
20a8a95141 | |
|
c8dd26aec2 | |
|
d36ad16535 | |
|
6c6a3ba4e7 | |
|
3bb9a938d5 | |
|
297d998365 | |
|
9a143c26b0 | |
|
b38b07e5bb | |
|
5c8ec926f9 | |
|
2d4d509ef0 | |
|
9364ef8412 | |
|
1c024beeb8 | |
|
d12381feb3 | |
|
1d67888b56 | |
|
3af303b605 | |
|
6257501187 | |
|
69756af817 | |
|
b9f2b30c57 | |
|
d56f84f631 | |
|
06edc35679 | |
|
5a0304a8d6 | |
|
206de9e618 | |
|
57d766fab0 | |
|
8567ec8c2e | |
|
17164687b6 | |
|
1152321c30 | |
|
7b98fca398 | |
|
9bb8ff8942 |
|
@ -1,5 +1,7 @@
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
|
||||||
out
|
out
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.log*
|
*.log*
|
||||||
|
/dist/
|
||||||
|
/dist.zip
|
||||||
|
.idea
|
||||||
|
|
|
@ -2,14 +2,12 @@
|
||||||
<code_scheme name="Project" version="173">
|
<code_scheme name="Project" version="173">
|
||||||
<HTMLCodeStyleSettings>
|
<HTMLCodeStyleSettings>
|
||||||
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||||
<option name="HTML_QUOTE_STYLE" value="Single" />
|
|
||||||
<option name="HTML_ENFORCE_QUOTES" value="true" />
|
<option name="HTML_ENFORCE_QUOTES" value="true" />
|
||||||
</HTMLCodeStyleSettings>
|
</HTMLCodeStyleSettings>
|
||||||
<JSCodeStyleSettings version="0">
|
<JSCodeStyleSettings version="0">
|
||||||
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
|
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
|
||||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||||
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||||
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
||||||
<option name="FORCE_QUOTE_STYlE" value="true" />
|
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||||
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||||
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
|
||||||
</content>
|
</content>
|
||||||
|
<content url="file://$MODULE_DIR$/node_modules" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="FLOW" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -1,4 +1,18 @@
|
||||||
|
#singleQuote: true
|
||||||
|
#semi: false
|
||||||
|
#printWidth: 100
|
||||||
|
#trailingComma: none
|
||||||
|
printWidth: 220
|
||||||
|
tabWidth: 4
|
||||||
|
useTabs: true
|
||||||
|
semi: true
|
||||||
singleQuote: true
|
singleQuote: true
|
||||||
semi: false
|
quoteProps: "as-needed"
|
||||||
printWidth: 100
|
trailingComma: "none"
|
||||||
trailingComma: none
|
bracketSpacing: true
|
||||||
|
jsxBracketSameLine: false
|
||||||
|
arrowParens: "avoid"
|
||||||
|
endOfLine: "lf"
|
||||||
|
jsxSingleQuote: false
|
||||||
|
vueIndentScriptAndStyle: false
|
||||||
|
Prettier:HTMLWhitespaceSensitivity: 'ignore'
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>com.apple.security.cs.allow-jit</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
BIN
build/icon.icns
BIN
build/icon.ico
Before Width: | Height: | Size: 121 KiB |
BIN
build/icon.png
Before Width: | Height: | Size: 35 KiB |
|
@ -1,44 +1,76 @@
|
||||||
appId: com.electron.app
|
# 应用程序的唯一标识符
|
||||||
productName: gateway-ui
|
appId: gy.calibration.pc
|
||||||
|
# 应用程序的名称
|
||||||
|
productName: 谷云校表产测
|
||||||
|
# 定义构建资源和输出文件的目录
|
||||||
directories:
|
directories:
|
||||||
buildResources: build
|
buildResources: build
|
||||||
|
# 定义要包含或排除在构建输出中的文件
|
||||||
files:
|
files:
|
||||||
- '!**/.vscode/*'
|
- '!**/.vscode/*' # 排除VSCode配置文件
|
||||||
- '!src/*'
|
- '!**/.cursor/*' # 排除cursor配置文件
|
||||||
- '!electron.vite.config.{js,ts,mjs,cjs}'
|
- '!**/.idea/*' # 排除idea配置文件
|
||||||
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
|
- '!src/*' # 排除源代码目录
|
||||||
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
|
- '!**/*.log' # 排除日志文件
|
||||||
|
- '!electron.vite.config.{js,ts,mjs,cjs}' # 排除Electron构建配置文件
|
||||||
|
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' # 排除开发和文档文件
|
||||||
|
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml,*.zip,app.log}' # 排除环境和包管理配置文件
|
||||||
|
# 定义需要解压的asar文件
|
||||||
asarUnpack:
|
asarUnpack:
|
||||||
- resources/**
|
- resources/** # 解压资源目录下的所有文件
|
||||||
|
# 针对Windows平台的配置
|
||||||
win:
|
win:
|
||||||
executableName: gateway-ui
|
icon: resources/icon.png # 应用程序图标的路径
|
||||||
|
# 针对NSIS安装程序的配置
|
||||||
nsis:
|
nsis:
|
||||||
artifactName: ${name}-${version}-setup.${ext}
|
artifactName: ${productName}-${version}-setup.${ext} # 安装程序的文件名格式
|
||||||
shortcutName: ${productName}
|
shortcutName: ${productName} # 快捷方式的名称
|
||||||
uninstallDisplayName: ${productName}
|
uninstallDisplayName: ${productName} # 卸载程序显示的名称
|
||||||
createDesktopShortcut: always
|
createDesktopShortcut: always # 总是在桌面创建快捷方式
|
||||||
|
allowToChangeInstallationDirectory: true # 允许用户选择安装目录
|
||||||
|
oneClick: false # 设置为非一键安装
|
||||||
|
installerIcon: resources/icon.ico # 安装程序的图标
|
||||||
|
uninstallerIcon: resources/icon.ico # 卸载程序的图标
|
||||||
|
installerHeader: resources/icon.png # 安装程序头部的图像
|
||||||
|
installerHeaderIcon: resources/icon.png # 安装程序头部图标的路径
|
||||||
|
# 针对macOS平台的配置
|
||||||
mac:
|
mac:
|
||||||
entitlementsInherit: build/entitlements.mac.plist
|
entitlementsInherit: build/entitlements.mac.plist # 继承权限配置文件
|
||||||
extendInfo:
|
extendInfo: # 添加macOS应用的元数据
|
||||||
- NSCameraUsageDescription: Application requests access to the device's camera.
|
- NSCameraUsageDescription: Application requests access to the device's camera. # 摄像头使用权限描述
|
||||||
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
|
- NSMicrophoneUsageDescription: Application requests access to the device's microphone. # 麦克风使用权限描述
|
||||||
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
|
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. # 文档夹使用权限描述
|
||||||
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
|
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. # 下载夹使用权限描述
|
||||||
notarize: false
|
notarize: false # 是否进行苹果的公证
|
||||||
|
icon: resources/icon.png # 应用程序的图标路径
|
||||||
|
identity: null # 签名身份
|
||||||
|
# 针对dmg安装包的配置
|
||||||
dmg:
|
dmg:
|
||||||
artifactName: ${name}-${version}.${ext}
|
artifactName: ${name}-${version}.${ext} # dmg文件的命名格式
|
||||||
|
# 针对Linux平台的配置
|
||||||
linux:
|
linux:
|
||||||
target:
|
target: # 目标包类型
|
||||||
- AppImage
|
- AppImage
|
||||||
- snap
|
- snap
|
||||||
- deb
|
- deb
|
||||||
maintainer: electronjs.org
|
maintainer: GuyunDevelopment # 维护者信息
|
||||||
category: Utility
|
category: Utility # 应用程序类别
|
||||||
|
icon: resources/icon.png # 应用程序图标路径
|
||||||
|
# 针对AppImage包的配置
|
||||||
appImage:
|
appImage:
|
||||||
artifactName: ${name}-${version}.${ext}
|
artifactName: ${name}-${version}.${ext} # AppImage文件的命名格式
|
||||||
|
# 是否在npm安装时重建asar包
|
||||||
npmRebuild: false
|
npmRebuild: false
|
||||||
|
# 配置自动更新的信息
|
||||||
publish:
|
publish:
|
||||||
provider: generic
|
provider: generic # 更新服务提供者
|
||||||
url: https://example.com/auto-updates
|
url: https://example.com/auto-updates # 更新信息的URL
|
||||||
|
# provider: github # 更新服务提供者
|
||||||
|
# owner: fanhuayishiy # GitHub用户名
|
||||||
|
# repo: mygit1 # GitHub仓库名称
|
||||||
|
# token: ${env:GITHUB_TOKEN}
|
||||||
|
# releaseType: release
|
||||||
|
|
||||||
|
# 配置Electron下载的镜像地址
|
||||||
electronDownload:
|
electronDownload:
|
||||||
mirror: https://npmmirror.com/mirrors/electron/
|
mirror: https://npmmirror.com/mirrors/electron/ # Electron下载的镜像地址
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import VueDevTools from 'vite-plugin-vue-devtools';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
main: {
|
main: {
|
||||||
|
@ -15,6 +16,9 @@ export default defineConfig({
|
||||||
'@renderer': resolve('src/renderer/src')
|
'@renderer': resolve('src/renderer/src')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [vue()]
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
VueDevTools()
|
||||||
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
12
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "gateway-ui",
|
"name": "gy-calibration",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "An Electron application with Vue",
|
"description": "谷云开发部开发的断路器标定软件",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "example.com",
|
"author": "example.com",
|
||||||
"homepage": "https://electron-vite.org",
|
"homepage": "https://electron-vite.org",
|
||||||
|
@ -21,10 +21,13 @@
|
||||||
"@electron-toolkit/preload": "^3.0.1",
|
"@electron-toolkit/preload": "^3.0.1",
|
||||||
"@electron-toolkit/utils": "^3.0.0",
|
"@electron-toolkit/utils": "^3.0.0",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
"electron-updater": "^6.1.7",
|
"electron-updater": "^6.1.7",
|
||||||
"element-plus": "^2.7.6",
|
"element-plus": "^2.7.6",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"vue-router": "^4.4.0"
|
"vue-router": "^4.4.0",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@electron-toolkit/eslint-config": "^1.0.2",
|
"@electron-toolkit/eslint-config": "^1.0.2",
|
||||||
|
@ -36,8 +39,11 @@
|
||||||
"electron-vite": "^2.3.0",
|
"electron-vite": "^2.3.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-vue": "^9.26.0",
|
"eslint-plugin-vue": "^9.26.0",
|
||||||
|
"less": "^4.2.0",
|
||||||
"prettier": "^3.3.2",
|
"prettier": "^3.3.2",
|
||||||
|
"sass": "^1.77.6",
|
||||||
"vite": "^5.3.1",
|
"vite": "^5.3.1",
|
||||||
|
"vite-plugin-vue-devtools": "^7.7.6",
|
||||||
"vue": "^3.4.30"
|
"vue": "^3.4.30"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
//打包配置
|
||||||
|
|
||||||
|
url: 'http://127.0.0.1:8000',
|
||||||
|
wsUrl: 'ws://127.0.0.1:8000',
|
||||||
|
swichWsUrl: 'ws://127.0.0.1:8001',
|
||||||
|
serialPortUrl: 'http://127.0.0.1:8000',
|
||||||
|
|
||||||
|
//开发配置
|
||||||
|
|
||||||
|
// url: 'http://192.168.1.17:8000',
|
||||||
|
// wsUrl: 'ws://192.168.1.17:8000',
|
||||||
|
// swichWsUrl: 'ws://192.168.1.17:8001',
|
||||||
|
// serialPortUrl: 'http://192.168.1.17:8000',
|
||||||
|
|
||||||
|
// 远程连接串口使用
|
||||||
|
// serialPortUrl: 'http://120.77.172.42:7202',
|
||||||
|
// serialPortUrl: 'http://192.168.1.17:8888',
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
[{"name":"属性1","addr":"60000","len":"2","data":"15"},{"name":"属性2","addr":"50000","len":"1","data":"1"}]
|
After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 45 KiB |
|
@ -0,0 +1,21 @@
|
||||||
|
server:
|
||||||
|
serverMain:
|
||||||
|
address: "8000"
|
||||||
|
#serverRoot: "resource/public"
|
||||||
|
|
||||||
|
logger:
|
||||||
|
path: "logs"
|
||||||
|
level: "info"
|
||||||
|
|
||||||
|
#台体编号
|
||||||
|
equipment: HS-9203M-0001
|
||||||
|
#设备总数
|
||||||
|
totalNum: 16
|
||||||
|
#起始端口号
|
||||||
|
startAddr: 22
|
||||||
|
#测试源电压波动比例
|
||||||
|
fluctuateRatioU: 90
|
||||||
|
#测试源电压波动比例
|
||||||
|
fluctuateRatioI: 90
|
||||||
|
#配置密钥
|
||||||
|
secretKey: "1dd53c82958d1de56df4035d3ed9fd82"
|
|
@ -0,0 +1,29 @@
|
||||||
|
[Delay]
|
||||||
|
ErrWaittime=0.5
|
||||||
|
SourceWaittime=1
|
||||||
|
StdmeterWaittime=2
|
||||||
|
Waittime4open=0.2
|
||||||
|
PurgeCommDelay=0.05
|
||||||
|
SampleTIME=3
|
||||||
|
HarmStableTime=3
|
||||||
|
HarmReviseTime=2
|
||||||
|
IntervalWaitTime=0.05
|
||||||
|
BpGrade1=0.05
|
||||||
|
BpGrade2=0.1
|
||||||
|
DelayAfterGearChange=0.5
|
||||||
|
IFCheckGear=0
|
||||||
|
CheckGearIntervalTime=1
|
||||||
|
CheckGearMaxWaitTIme=7
|
||||||
|
ReviseTIme=0
|
||||||
|
|
||||||
|
[System]
|
||||||
|
SetMode5300b=0
|
||||||
|
ReadMode5300b=1
|
||||||
|
HarmReviseMode=0
|
||||||
|
IfHarmRevise=1
|
||||||
|
HS5300ReadUacSupport=1
|
||||||
|
ifThreadLog=1
|
||||||
|
HS5300UURevise=0
|
||||||
|
|
||||||
|
[Debug]
|
||||||
|
Mode=0
|
|
@ -0,0 +1,28 @@
|
||||||
|
server:
|
||||||
|
address: ":8888"
|
||||||
|
staticRoot: "./resource/template"
|
||||||
|
apiPrefix: "/api/v1"
|
||||||
|
pluginPrefix: "/plugins"
|
||||||
|
file:
|
||||||
|
upload_path: "./resource/upload"
|
||||||
|
dir_mode: "byDate"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
logger:
|
||||||
|
level: debug
|
||||||
|
path: "./resource/logs/server.log"
|
||||||
|
max_size: 10
|
||||||
|
max_age: 30
|
||||||
|
|
||||||
|
|
||||||
|
database:
|
||||||
|
default:
|
||||||
|
kind: "mysql"
|
||||||
|
dsn: "root:mysql_YiniNx@tcp(123.60.30.87:3306)/goside?charset=utf8mb4&parseTime=True&loc=Local"
|
||||||
|
max_idle_conns: 10
|
||||||
|
max_open_conns: 100
|
||||||
|
# kind: "SQLite"
|
||||||
|
# dsn: "./resource/db/db.db"
|
||||||
|
# max_idle_conns: 10
|
|
@ -0,0 +1,713 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"key": "c_id",
|
||||||
|
"name": "芯片id",
|
||||||
|
"addr": 0,
|
||||||
|
"len": 4,
|
||||||
|
"dataType": "string",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"key": "calibration_conf",
|
||||||
|
"name": "标定参数",
|
||||||
|
"addr": 30018,
|
||||||
|
"len": 5,
|
||||||
|
"dataType": "struct",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "",
|
||||||
|
"precision": "",
|
||||||
|
"unit": "",
|
||||||
|
"format": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"size": 16,
|
||||||
|
"key": "ec",
|
||||||
|
"name": "脉冲常数",
|
||||||
|
"unit": "",
|
||||||
|
"value": "3200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 16,
|
||||||
|
"size": 16,
|
||||||
|
"key": "u",
|
||||||
|
"name": "电压",
|
||||||
|
"unit": "V",
|
||||||
|
"value": "220"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 32,
|
||||||
|
"size": 16,
|
||||||
|
"key": "i",
|
||||||
|
"name": "电流",
|
||||||
|
"unit": "A",
|
||||||
|
"value": "10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 48,
|
||||||
|
"size": 16,
|
||||||
|
"key": "pt",
|
||||||
|
"name": "电压比",
|
||||||
|
"unit": "",
|
||||||
|
"value": "1981"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 64,
|
||||||
|
"size": 16,
|
||||||
|
"key": "ct",
|
||||||
|
"name": "电流比",
|
||||||
|
"unit": "",
|
||||||
|
"value": "2000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 80,
|
||||||
|
"size": 16,
|
||||||
|
"key": "ileak",
|
||||||
|
"name": "漏电流",
|
||||||
|
"unit": "mA",
|
||||||
|
"value": "20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 96,
|
||||||
|
"size": 8,
|
||||||
|
"key": "ig",
|
||||||
|
"name": "电流通道放大倍数",
|
||||||
|
"unit": "",
|
||||||
|
"value": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 104,
|
||||||
|
"size": 8,
|
||||||
|
"key": "vg",
|
||||||
|
"name": "电压通道放大倍数",
|
||||||
|
"unit": "",
|
||||||
|
"value": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 112,
|
||||||
|
"size": 8,
|
||||||
|
"key": "ilg",
|
||||||
|
"name": "漏电流通道放大倍数",
|
||||||
|
"unit": "",
|
||||||
|
"value": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 120,
|
||||||
|
"size": 8,
|
||||||
|
"key": "reserve",
|
||||||
|
"name": "保留位",
|
||||||
|
"unit": "",
|
||||||
|
"value": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 128,
|
||||||
|
"size": 32,
|
||||||
|
"key": "isr",
|
||||||
|
"name": "电流采样电阻",
|
||||||
|
"unit": "10mΩ",
|
||||||
|
"value": "440"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "last_event",
|
||||||
|
"name": "事件",
|
||||||
|
"addr": 50000,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "string",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "last_event_time",
|
||||||
|
"name": "事件发生时间",
|
||||||
|
"addr": 50001,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "time",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "update_time",
|
||||||
|
"name": "时间戳",
|
||||||
|
"addr": 50002,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "time",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "switch",
|
||||||
|
"name": "开关状态",
|
||||||
|
"addr": 50003,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "",
|
||||||
|
"precision": "",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Freq",
|
||||||
|
"name": "电网频率",
|
||||||
|
"addr": 50004,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.01",
|
||||||
|
"unit": "Hz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Leak_I",
|
||||||
|
"name": "漏电流/N相电流",
|
||||||
|
"addr": 50005,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "mA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Tn_1",
|
||||||
|
"name": "N相进线温度",
|
||||||
|
"addr": 50006,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Tn_2",
|
||||||
|
"name": "N相出线温度",
|
||||||
|
"addr": 50007,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ua",
|
||||||
|
"name": "A/L相电压",
|
||||||
|
"addr": 50008,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.01",
|
||||||
|
"unit": "V"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ia",
|
||||||
|
"name": "A/L相电流",
|
||||||
|
"addr": 50009,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "A",
|
||||||
|
"critical": "0.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Pa",
|
||||||
|
"name": "A/L相有功功率",
|
||||||
|
"addr": 50010,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "W"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Qa",
|
||||||
|
"name": "A/L相无功功率",
|
||||||
|
"addr": 50011,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "var"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Sa",
|
||||||
|
"name": "A/L相视在功率",
|
||||||
|
"addr": 50012,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "va"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Pfa",
|
||||||
|
"name": "A/L相功率因数",
|
||||||
|
"addr": 50013,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPa_H",
|
||||||
|
"name": "A/L相有功电能高32位",
|
||||||
|
"addr": 50014,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPa_L",
|
||||||
|
"name": "A/L相有功电能低32位",
|
||||||
|
"addr": 50015,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQa_H",
|
||||||
|
"name": "A/L相无功电能高32位",
|
||||||
|
"addr": 50016,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQa_L",
|
||||||
|
"name": "A/L相无功电能低32位",
|
||||||
|
"addr": 50017,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ta_1",
|
||||||
|
"name": "L/A相进线温度",
|
||||||
|
"addr": 50018,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ta_2",
|
||||||
|
"name": "L/A相出线温度",
|
||||||
|
"addr": 50019,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ub",
|
||||||
|
"name": "B相电压",
|
||||||
|
"addr": 50020,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.01",
|
||||||
|
"unit": "V"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ib",
|
||||||
|
"name": "B相电流",
|
||||||
|
"addr": 50021,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "A",
|
||||||
|
"critical": "0.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Pb",
|
||||||
|
"name": "B相有功功率 ",
|
||||||
|
"addr": 50022,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "W"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Qb",
|
||||||
|
"name": "B相无功功率",
|
||||||
|
"addr": 50023,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "var"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Sb",
|
||||||
|
"name": "B相视在功率",
|
||||||
|
"addr": 50024,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "va"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Pfb",
|
||||||
|
"name": "B相功率因数",
|
||||||
|
"addr": 50025,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPb_H",
|
||||||
|
"name": "B相有功电能高32位",
|
||||||
|
"addr": 50026,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPb_L",
|
||||||
|
"name": "B相有功电能低32位",
|
||||||
|
"addr": 50027,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQb_H",
|
||||||
|
"name": "B相无功电能高32位",
|
||||||
|
"addr": 50028,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQb_L",
|
||||||
|
"name": "B相无功电能低32位",
|
||||||
|
"addr": 50029,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Tb_1",
|
||||||
|
"name": "B相进线温度",
|
||||||
|
"addr": 50030,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Tb_2",
|
||||||
|
"name": "B相出线温度",
|
||||||
|
"addr": 50031,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Uc",
|
||||||
|
"name": "C相电压",
|
||||||
|
"addr": 50032,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.01",
|
||||||
|
"unit": "V"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ic",
|
||||||
|
"name": "C相电流",
|
||||||
|
"addr": 50033,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "A",
|
||||||
|
"critical": "0.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Pc",
|
||||||
|
"name": "C相有功功率 ",
|
||||||
|
"addr": 50034,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "W"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Qc",
|
||||||
|
"name": "C相无功功率",
|
||||||
|
"addr": 50035,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "var"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Sc",
|
||||||
|
"name": "C相视在功率",
|
||||||
|
"addr": 50036,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "va"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Pfc",
|
||||||
|
"name": "C相功率因数",
|
||||||
|
"addr": 50037,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPc_H",
|
||||||
|
"name": "C相有功电能高32位",
|
||||||
|
"addr": 50038,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPc_L",
|
||||||
|
"name": "C相有功电能低32位",
|
||||||
|
"addr": 50039,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQc_H",
|
||||||
|
"name": "C相无功电能高32位",
|
||||||
|
"addr": 50040,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQc_L",
|
||||||
|
"name": "C相无功电能低32位",
|
||||||
|
"addr": 50041,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Tc_1",
|
||||||
|
"name": "C相进线温度",
|
||||||
|
"addr": 50042,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Tc_2",
|
||||||
|
"name": "C相出线温度",
|
||||||
|
"addr": 50043,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "int32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.1",
|
||||||
|
"unit": "℃"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Usum",
|
||||||
|
"name": "合相电压",
|
||||||
|
"addr": 50044,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.01",
|
||||||
|
"unit": "V"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Isum",
|
||||||
|
"name": "合相电流/剩余电流",
|
||||||
|
"addr": 50045,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "A",
|
||||||
|
"critical": "0.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Psum",
|
||||||
|
"name": "合相有功功率",
|
||||||
|
"addr": 50046,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "W"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Qsum",
|
||||||
|
"name": "合相无功功率",
|
||||||
|
"addr": 50047,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "var"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Ssum",
|
||||||
|
"name": "RMS 合相视在功率",
|
||||||
|
"addr": 50048,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": "va"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Pfsum",
|
||||||
|
"name": "RMS 合相功率因数",
|
||||||
|
"addr": 50049,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "0.001",
|
||||||
|
"unit": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPsum_H;",
|
||||||
|
"name": "合相有功电能高32位",
|
||||||
|
"addr": 50050,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EPsum_L;",
|
||||||
|
"name": "合相有功电能低32位",
|
||||||
|
"addr": 50051,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "Wh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQsum_H,;",
|
||||||
|
"name": "合相无功电能高32位",
|
||||||
|
"addr": 50052,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EQsum_L;",
|
||||||
|
"name": "合相无功电能低32位",
|
||||||
|
"addr": 50053,
|
||||||
|
"len": 1,
|
||||||
|
"dataType": "uint32",
|
||||||
|
"rwType": "R",
|
||||||
|
"default": "0",
|
||||||
|
"precision": "1",
|
||||||
|
"unit": "varh"
|
||||||
|
}
|
||||||
|
]
|
|
@ -1,75 +1,229 @@
|
||||||
import { app, shell, BrowserWindow, ipcMain } from 'electron'
|
import { app, shell, BrowserWindow, ipcMain, globalShortcut, dialog } from 'electron';
|
||||||
import { join } from 'path'
|
import { join } from 'path';
|
||||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
import { electronApp, optimizer, is } from '@electron-toolkit/utils';
|
||||||
import icon from '../../resources/icon.png?asset'
|
import icon from '../../resources/icon.png?asset';
|
||||||
|
|
||||||
|
//关闭exe命令
|
||||||
|
function killProcessByName(processName) {
|
||||||
|
const command = `taskkill /IM ${processName} /F`;
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
|
||||||
|
exec(command, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(`执行的错误: ${error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(`stdout: ${stdout}`);
|
||||||
|
console.error(`stderr: ${stderr}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
app.commandLine.appendSwitch('disable-web-security');
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
const mainWindow = new BrowserWindow({
|
const mainWindow = new BrowserWindow({
|
||||||
width: 900,
|
width: 1280,
|
||||||
height: 670,
|
height: 1024,
|
||||||
show: false,
|
show: false,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
...(process.platform === 'linux' ? { icon } : {}),
|
icon,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload: join(__dirname, '../preload/index.js'),
|
preload: join(__dirname, '../preload/index.js'),
|
||||||
sandbox: false
|
sandbox: false,
|
||||||
|
nodeIntegration: true,
|
||||||
|
// 禁用同源策略,允许跨域请求
|
||||||
|
webSecurity: false,
|
||||||
|
contextIsolation: false,
|
||||||
|
// csp: "default-src 'self'; connect-src 'self' *",
|
||||||
|
// 禁止build环境使用DevTool
|
||||||
|
// devTools: is.dev ? true : false
|
||||||
|
devTools: true
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
//开启调试
|
//开发模式 开启调试
|
||||||
// mainWindow.webContents.openDevTools()
|
if (is.dev) {
|
||||||
|
mainWindow.webContents.openDevTools();
|
||||||
|
}
|
||||||
|
|
||||||
mainWindow.on('ready-to-show', () => {
|
mainWindow.on('ready-to-show', () => {
|
||||||
mainWindow.show()
|
mainWindow.show();
|
||||||
})
|
});
|
||||||
|
|
||||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
mainWindow.webContents.setWindowOpenHandler(details => {
|
||||||
shell.openExternal(details.url)
|
shell.openExternal(details.url);
|
||||||
return { action: 'deny' }
|
return { action: 'deny' };
|
||||||
})
|
});
|
||||||
|
//基于electronic-vite-cli的渲染器HMR。
|
||||||
// HMR for renderer base on electron-vite cli.
|
//加载用于开发的远程URL或用于生产的本地html文件。
|
||||||
// Load the remote URL for development or the local html file for production.
|
|
||||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
|
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']);
|
||||||
} else {
|
} else {
|
||||||
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
|
mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method will be called when Electron has finished
|
// 设置DevTools快捷键
|
||||||
// initialization and is ready to create browser windows.
|
// 设置DevTools快捷键
|
||||||
// Some APIs can only be used after this event occurs.
|
globalShortcut.register('CommandOrControl+Shift+i', function () {
|
||||||
|
mainWindow.webContents.openDevTools();
|
||||||
|
});
|
||||||
|
return mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 程序单例模式
|
||||||
|
let myWindow = null;
|
||||||
|
const gotTheLock = app.requestSingleInstanceLock();
|
||||||
|
if (!gotTheLock) {
|
||||||
|
// 如果已经有同样的该程序正在运行,则不启动
|
||||||
|
app.quit();
|
||||||
|
} else {
|
||||||
|
// 如果检测到有同样的该程序正在试图启动...
|
||||||
|
app.on('second-instance', () => {
|
||||||
|
if (myWindow) {
|
||||||
|
// 弹出系统提示对话框
|
||||||
|
dialog.showMessageBox({
|
||||||
|
message: '此程序已经正在运行'
|
||||||
|
});
|
||||||
|
// 如果该程序窗口处于最小化状态,则恢复窗口
|
||||||
|
if (myWindow.isMinimized()) myWindow.restore();
|
||||||
|
// 将该程序窗口置为当前聚焦态
|
||||||
|
myWindow.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//当Electron完成时,将调用此方法
|
||||||
|
//初始化并准备创建浏览器窗口。
|
||||||
|
//某些API只能在此事件发生后使用。
|
||||||
|
const { spawn } = require('child_process');
|
||||||
|
let child = null;
|
||||||
|
let exePluginsExeList = [];
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
// Set app user model id for windows
|
const fs = require('fs');
|
||||||
electronApp.setAppUserModelId('com.electron')
|
const path = require('path');
|
||||||
|
|
||||||
// Default open or close DevTools by F12 in development
|
const logStream = fs.createWriteStream('app.log', { flags: 'a' }); // 日志文件
|
||||||
// and ignore CommandOrControl + R in production.
|
let exePath = path.resolve('./resources/app.asar.unpacked/resources/service');
|
||||||
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
|
let exePluginsPath = path.resolve('./resources/app.asar.unpacked/resources/service/plugins');
|
||||||
|
//单独配置测试环境
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
exePath = path.resolve('./resources/service');
|
||||||
|
exePluginsPath = path.resolve('./resources/service/plugins');
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询所有插件目录下的exe文件
|
||||||
|
fs.readdir(exePluginsPath, (err, files) => {
|
||||||
|
if (err) {
|
||||||
|
return console.log('Unable to scan directory: ' + err);
|
||||||
|
}
|
||||||
|
// 筛选出以.exe结尾的文件
|
||||||
|
exePluginsExeList = files.filter(file => path.extname(file).toLowerCase() === '.exe');
|
||||||
|
});
|
||||||
|
const userDataPath = app.getPath('userData');
|
||||||
|
child = spawn('./main.exe', ['--args', userDataPath], { cwd: exePath, stdio: ['ignore', 'pipe', 'pipe'] });
|
||||||
|
|
||||||
|
//监听进程的输出
|
||||||
|
child.stdout.on('data', data => {
|
||||||
|
console.log('stdout:', data.toString());
|
||||||
|
logStream.write(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.stderr.on('data', data => {
|
||||||
|
console.error('stderr:', data.toString());
|
||||||
|
logStream.write(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('close', code => {
|
||||||
|
console.log(`子进程已退出,退出码 ${code}`);
|
||||||
|
logStream.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('exit', (code, signal) => {
|
||||||
|
console.log(`子进程已退出,退出码 ${code},信号: ${signal}`);
|
||||||
|
logStream.write(`子进程已退出,退出码 ${code},信号: ${signal}`);
|
||||||
|
logStream.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set app user model id for windows
|
||||||
|
electronApp.setAppUserModelId('com.electron');
|
||||||
|
|
||||||
|
//开发中默认按F12打开或关闭DevTools
|
||||||
|
//在生产中忽略CommandOrControl+R。
|
||||||
|
//看https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
|
||||||
app.on('browser-window-created', (_, window) => {
|
app.on('browser-window-created', (_, window) => {
|
||||||
optimizer.watchWindowShortcuts(window)
|
optimizer.watchWindowShortcuts(window);
|
||||||
})
|
});
|
||||||
|
|
||||||
// IPC test
|
// IPC test
|
||||||
ipcMain.on('ping', () => console.log('pong'))
|
ipcMain.on('ping', () => console.log('pong'));
|
||||||
|
|
||||||
createWindow()
|
myWindow = createWindow();
|
||||||
|
|
||||||
app.on('activate', function () {
|
app.on('activate', function () {
|
||||||
// On macOS it's common to re-create a window in the app when the
|
//在macOS上,当出现以下情况时,通常会在应用程序中重新创建窗口
|
||||||
// dock icon is clicked and there are no other windows open.
|
//单击dock图标后,没有其他打开的窗口。
|
||||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
if (BrowserWindow.getAllWindows().length === 0) createWindow();
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
// 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
|
// ipcMain.handle('readFile', async (event, path) => {
|
||||||
// explicitly with Cmd + Q.
|
// return new Promise((resolve, reject) => {
|
||||||
|
// fs.readFile(join(__dirname, path), 'utf8', (err, data) => {
|
||||||
|
// if (err) {
|
||||||
|
// reject(err);
|
||||||
|
// } else {
|
||||||
|
// resolve(data);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// ipcMain.handle('writeFile', async (event, path, content) => {
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// fs.writeFile(join(__dirname, path), content, 'utf8', (err) => {
|
||||||
|
// if (err) {
|
||||||
|
// reject(err);
|
||||||
|
// } else {
|
||||||
|
// resolve();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // 处理来自渲染进程的请求
|
||||||
|
// ipcMain.handle('readDirectory', async (event, directoryPath) => {
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// fs.readdir(join(__dirname, directoryPath), (err, files) => {
|
||||||
|
// if (err) {
|
||||||
|
// reject(err);
|
||||||
|
// } else {
|
||||||
|
// resolve(files);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
//关闭所有窗口后退出,macOS除外。在那里,这很常见
|
||||||
|
//让应用程序及其菜单栏保持活动状态,直到用户退出
|
||||||
|
//显式使用Cmd+Q。
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
app.quit()
|
// 循环关闭插件 EXE 列表
|
||||||
|
exePluginsExeList.forEach(exe => {
|
||||||
|
killProcessByName(exe);
|
||||||
|
});
|
||||||
|
// child.kill('SIGTERM'); // 或者使用 'SIGKILL' 来强制关闭
|
||||||
|
// killProcessByName('gateway.exe');
|
||||||
|
// 循环关闭后端服务
|
||||||
|
killProcessByName('main.exe');
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// In this file you can include the rest of your app"s specific main process
|
//在此文件中,您可以包含应用程序的其他特定主进程
|
||||||
// code. You can also put them in separate files and require them here.
|
//代码。您也可以将它们放在单独的文件中,并在此处要求它们。
|
||||||
|
|
||||||
|
//获取应用程序版本
|
||||||
|
ipcMain.handle('get-app-version', () => {
|
||||||
|
return app.getVersion();
|
||||||
|
});
|
||||||
|
|
|
@ -1,20 +1,103 @@
|
||||||
import { contextBridge } from 'electron'
|
import { contextBridge, ipcRenderer } from 'electron'
|
||||||
import { electronAPI } from '@electron-toolkit/preload'
|
import { electronAPI } from '@electron-toolkit/preload'
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const { shell } = require('electron');
|
||||||
|
|
||||||
// Custom APIs for renderer
|
// Custom APIs for renderer
|
||||||
const api = {}
|
// 自定义的主进程方法API
|
||||||
|
// const api = {
|
||||||
|
// readFile: async (path) => {
|
||||||
|
// const result = await ipcRenderer.invoke('readFile', path);
|
||||||
|
// return result;
|
||||||
|
// },
|
||||||
|
// writeFile: async (path, content) => {
|
||||||
|
// await ipcRenderer.invoke('writeFile', path, content);
|
||||||
|
// },
|
||||||
|
// readDirectory: async (directoryPath) => {
|
||||||
|
// const result = await ipcRenderer.invoke('readDirectory', directoryPath);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // 暴露获取版本号的方法
|
||||||
|
// ipcMain.handle('get-app-version', () => {
|
||||||
|
// return app.getVersion(); // 返回当前应用版本(来自 package.json)
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 获取config.js的绝对路径
|
||||||
|
function getConfigPath() {
|
||||||
|
// __dirname 是 win-unpacked/resources/app
|
||||||
|
|
||||||
|
let configPath = path.resolve('./resources/app.asar.unpacked/resources/config/config.js');
|
||||||
|
//单独配置测试环境
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
configPath = path.resolve('./resources/config/config.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
return configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExportPath() {
|
||||||
|
// __dirname 是 win-unpacked/resources/app
|
||||||
|
|
||||||
|
let configPath = path.resolve('./resources/app.asar.unpacked/resources/service');
|
||||||
|
//单独配置测试环境
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
configPath = path.resolve('./resources/service');
|
||||||
|
}
|
||||||
|
|
||||||
|
return configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Use `contextBridge` APIs to expose Electron APIs to
|
// Use `contextBridge` APIs to expose Electron APIs to
|
||||||
// renderer only if context isolation is enabled, otherwise
|
// renderer only if context isolation is enabled, otherwise
|
||||||
// just add to the DOM global.
|
// just add to the DOM global.
|
||||||
|
// 使用contextBridge将Electron API和自定义的主进程方法API暴露给渲染进程页面。
|
||||||
if (process.contextIsolated) {
|
if (process.contextIsolated) {
|
||||||
try {
|
try {
|
||||||
contextBridge.exposeInMainWorld('electron', electronAPI)
|
contextBridge.exposeInMainWorld('electron', {
|
||||||
contextBridge.exposeInMainWorld('api', api)
|
...electronAPI,
|
||||||
|
getAppVersion: async () => {
|
||||||
|
return await ipcRenderer.invoke('get-app-version');
|
||||||
|
},
|
||||||
|
readConfig: () => {
|
||||||
|
const configPath = getConfigPath();
|
||||||
|
if (fs.existsSync(configPath)) {
|
||||||
|
// 用require动态加载,确保每次都是最新内容
|
||||||
|
delete require.cache[require.resolve(configPath)];
|
||||||
|
return require(configPath);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
shell: {
|
||||||
|
openPath: shell.openPath
|
||||||
|
},
|
||||||
|
exePath: getExportPath()
|
||||||
|
})
|
||||||
|
// contextBridge.exposeInMainWorld('api', api)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
window.electron = electronAPI
|
window.electron = {
|
||||||
window.api = api
|
...electronAPI,
|
||||||
|
getAppVersion: async () => {
|
||||||
|
return await ipcRenderer.invoke('get-app-version');
|
||||||
|
},
|
||||||
|
readConfig: () => {
|
||||||
|
const configPath = getConfigPath();
|
||||||
|
if (fs.existsSync(configPath)) {
|
||||||
|
// 用require动态加载,确保每次都是最新内容
|
||||||
|
delete require.cache[require.resolve(configPath)];
|
||||||
|
return require(configPath);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
shell: {
|
||||||
|
openPath: shell.openPath
|
||||||
|
},
|
||||||
|
exePath: getExportPath()
|
||||||
|
}
|
||||||
|
// window.api = api
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Electron</title>
|
<title>谷云校表产测</title>
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||||
<meta
|
<link rel="stylesheet" href="/src/assets/iconfont/iconfont.css">
|
||||||
http-equiv="Content-Security-Policy"
|
<!-- <meta-->
|
||||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
<!-- http-equiv="Content-Security-Policy"-->
|
||||||
/>
|
<!-- content="default-src 'self'; connect-src 'self' *; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"-->
|
||||||
|
<!-- />-->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -1,11 +1,52 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { RouterView } from "vue-router"
|
import { RouterView } from 'vue-router'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<RouterView></RouterView>
|
<RouterView></RouterView>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<style lang="scss">
|
||||||
|
:root {
|
||||||
|
--el-input-height: 36px;
|
||||||
|
--el-color-primary: #0066cc;
|
||||||
|
--el-fill-color-blank: #e6e6e6;
|
||||||
|
--el-disabled-bg-color: #f7f7f7;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
background: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
/*全局覆盖样式*/
|
||||||
|
.el-collapse-item {
|
||||||
|
color: #333333;
|
||||||
|
.el-collapse-item__header {
|
||||||
|
font-family: Source Han Sans CN;
|
||||||
|
background: #e6e6e6;
|
||||||
|
padding: 0 30px;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 16px;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
font-weight: 500;
|
||||||
|
&.is-active {
|
||||||
|
color: #0066cc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-collapse-item__wrap {
|
||||||
|
background-color: #f2f2f2 !important;
|
||||||
|
}
|
||||||
|
.el-input__wrapper {
|
||||||
|
background: #e6e6e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: "iconfont"; /* Project id 4622943 */
|
||||||
|
src: url('iconfont.woff2?t=1753694081375') format('woff2'),
|
||||||
|
url('iconfont.woff?t=1753694081375') format('woff'),
|
||||||
|
url('iconfont.ttf?t=1753694081375') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zhakai:before {
|
||||||
|
content: "\e797";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zhahe:before {
|
||||||
|
content: "\e798";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-kuaijiejian:before {
|
||||||
|
content: "\e603";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-sousuo:before {
|
||||||
|
content: "\e60e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xwtubiaoku-13:before {
|
||||||
|
content: "\e61a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xwtubiaoku-15:before {
|
||||||
|
content: "\e61d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-rizhi:before {
|
||||||
|
content: "\e61c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bug:before {
|
||||||
|
content: "\e725";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-caozuorizhi:before {
|
||||||
|
content: "\e610";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-rizhishenji:before {
|
||||||
|
content: "\e666";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chenggong:before {
|
||||||
|
content: "\e615";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-rizhi1:before {
|
||||||
|
content: "\e613";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chenggong1:before {
|
||||||
|
content: "\e616";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bug-fill:before {
|
||||||
|
content: "\e773";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bug-line:before {
|
||||||
|
content: "\e774";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-kongtiaoguizhuduanluqiAA:before {
|
||||||
|
content: "\e68e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon--_saomaqiang:before {
|
||||||
|
content: "\e640";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-qianzhaoyiqibiaoding:before {
|
||||||
|
content: "\e633";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zuobiaobiaoding:before {
|
||||||
|
content: "\e602";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-com001:before {
|
||||||
|
content: "\e62c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chuankou:before {
|
||||||
|
content: "\e6be";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chuankou1:before {
|
||||||
|
content: "\e60a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chuankoushezhi:before {
|
||||||
|
content: "\e600";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chuankou2:before {
|
||||||
|
content: "\e6fc";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shousuoshangjiantou:before {
|
||||||
|
content: "\e9b6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-up-arrow:before {
|
||||||
|
content: "\e9c1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-unlock:before {
|
||||||
|
content: "\e882";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gexinghuabobao:before {
|
||||||
|
content: "\e66d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_suoding:before {
|
||||||
|
content: "\e76c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_shanchu:before {
|
||||||
|
content: "\e76d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_shanghang:before {
|
||||||
|
content: "\e76e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_xiahang:before {
|
||||||
|
content: "\e76f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_shezhi:before {
|
||||||
|
content: "\e770";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_xitong:before {
|
||||||
|
content: "\e771";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_jiankong:before {
|
||||||
|
content: "\e772";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_duanluqi2:before {
|
||||||
|
content: "\e9c2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_caid:before {
|
||||||
|
content: "\e75f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_chajian:before {
|
||||||
|
content: "\e767";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_xiaoxi:before {
|
||||||
|
content: "\e768";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_gengxin:before {
|
||||||
|
content: "\e769";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_fuzhi:before {
|
||||||
|
content: "\e76a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_duanluqi:before {
|
||||||
|
content: "\e76b";
|
||||||
|
}
|
||||||
|
|
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 45 KiB |
|
@ -31,7 +31,8 @@ code {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-bottom: 80px;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
|
|
|
@ -13,13 +13,13 @@ const settings = defineProps({
|
||||||
<el-aside :width="settings.width">
|
<el-aside :width="settings.width">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<el-menu
|
<el-menu
|
||||||
:default-openeds="['1', '3']"
|
default-active="/switch"
|
||||||
:collapse="settings.collapse"
|
:collapse="settings.collapse"
|
||||||
router="true"
|
:router="true"
|
||||||
>
|
>
|
||||||
<el-menu-item index="/versions"><el-icon> <House /> </el-icon>首页</el-menu-item>
|
<el-menu-item index="/switch"><el-icon> <Connection /> </el-icon>断路器调试</el-menu-item>
|
||||||
<el-menu-item index="/about"><el-icon> <Menu /> </el-icon>文章管理列表</el-menu-item>
|
<!-- <el-menu-item index="/about"><el-icon> <Menu /> </el-icon>文章管理列表</el-menu-item>-->
|
||||||
<el-menu-item index="/test"><el-icon> <Menu /> </el-icon>测试</el-menu-item>
|
<!-- <el-menu-item index="/test"><el-icon> <Menu /> </el-icon>测试</el-menu-item>-->
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
@ -29,7 +29,23 @@ const settings = defineProps({
|
||||||
.el-aside {
|
.el-aside {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: var(--el-box-shadow-lighter);
|
border-right: 1px solid #e6e6e6;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
.el-menu{
|
||||||
|
background: #f6f6f6;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
.el-menu-item{
|
||||||
|
border-radius: 10px;
|
||||||
|
/*padding-left: 5px !important;*/
|
||||||
|
}
|
||||||
|
.el-menu-item.is-active{
|
||||||
|
background: #c8cde4;
|
||||||
|
border-radius: 10px;
|
||||||
|
/*margin: 0 10px;*/
|
||||||
|
color: #0066cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-scrollbar {
|
.el-scrollbar {
|
||||||
|
|
|
@ -5,9 +5,5 @@ const versions = reactive({ ...window.electron.process.versions })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ul class="versions">
|
view
|
||||||
<li class="electron-version">Electron v{{ versions.electron }}</li>
|
|
||||||
<li class="chrome-version">Chromium v{{ versions.chrome }}</li>
|
|
||||||
<li class="node-version">Node v{{ versions.node }}</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<template>
|
||||||
|
<el-container direction="vertical" style="height: 100%; width: 100%; ">
|
||||||
|
<el-main>
|
||||||
|
<router-view v-slot="{ Component }">
|
||||||
|
<keep-alive>
|
||||||
|
<component :is="Component" />
|
||||||
|
</keep-alive>
|
||||||
|
</router-view>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// 组件注册
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
body {
|
||||||
|
background-color: #eee;
|
||||||
|
max-width: 100vw;
|
||||||
|
}
|
||||||
|
.el-container {
|
||||||
|
/*padding: 10px 0;*/
|
||||||
|
}
|
||||||
|
.el-main {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
/*height: 100vh;*/
|
||||||
|
overflow-x: hidden;
|
||||||
|
background: #fff;
|
||||||
|
/*padding-right: 10px;*/
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -2,21 +2,26 @@ import '@renderer/assets/main.css'
|
||||||
|
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
|
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
||||||
import 'element-plus/dist/index.css'
|
import 'element-plus/dist/index.css'
|
||||||
|
|
||||||
import App from '@renderer/App.vue'
|
import App from '@renderer/App.vue'
|
||||||
import router from '@renderer/router'
|
import router from '@renderer/router'
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
app.config.globalProperties.$dayjs = dayjs
|
||||||
|
|
||||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
app.component(key, component)
|
app.component(key, component)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
app.use(ElementPlus)
|
app.use(ElementPlus, {
|
||||||
|
locale: zhCn,
|
||||||
|
})
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
|
@ -1,46 +1,32 @@
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
import HomeView from '@renderer/views/HomeView.vue'
|
import Layout from '@renderer/layout/index.vue';
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: createWebHistory(),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
component: Layout,
|
||||||
component: HomeView,
|
meta: { title: '整体页面布局' },
|
||||||
redirect: {name: 'versions'},
|
redirect: '/calibration',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'versions',
|
path: 'calibration',
|
||||||
name: 'versions',
|
name: 'calibration',
|
||||||
component: () => import("@renderer/components/Versions.vue"),
|
component: () => import('@renderer/views/calibration/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
menu: 'versions',
|
menu: 'calibration',
|
||||||
keepAlive: true,
|
keepAlive: true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'about',
|
|
||||||
name: 'about',
|
|
||||||
component: () => import("@renderer/views/AboutView.vue"),
|
|
||||||
meta: {
|
|
||||||
menu: 'about',
|
|
||||||
keepAlive: true,
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'test',
|
|
||||||
name: 'test',
|
|
||||||
component: () => import("@renderer/views/test.vue"),
|
|
||||||
meta: {
|
|
||||||
menu: 'test',
|
|
||||||
keepAlive: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ path: '/:pathMatch(.*)', redirect: '/' },
|
{
|
||||||
|
path: '/', // 这个是根路由,现在我们让它重定向到 /system
|
||||||
|
redirect: '/calibration'
|
||||||
|
},
|
||||||
|
{ path: '/:pathMatch(.*)', redirect: '/' }
|
||||||
]
|
]
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
// import config from '@renderer/util/config.js'
|
||||||
|
const config = window.electron.readConfig();
|
||||||
|
|
||||||
|
// 定义一个名为logWebSocketStore的store,用于管理WebSocket连接的状态和操作
|
||||||
|
export const logWebSocketStore = defineStore('websocket', {
|
||||||
|
state: () => ({
|
||||||
|
websocket: null, // WebSocket实例
|
||||||
|
connectURL: config.wsUrl + '/ws/log', // WebSocket连接的URL
|
||||||
|
socket_open: false, // 标记WebSocket是否连接
|
||||||
|
hearbeat_timer: null, // 心跳检测的定时器
|
||||||
|
hearbeat_interval: 2 * 1000, // 心跳检测的间隔时间
|
||||||
|
is_reonnect: true, // 是否尝试重新连接
|
||||||
|
reconnect_count: 3, // 最大重连次数
|
||||||
|
reconnect_current: 1, // 当前重连次数
|
||||||
|
reconnect_timer: null, // 重连定时器
|
||||||
|
reconnect_interval: 5 * 1000, // 重连间隔时间
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
// 初始化WebSocket连接
|
||||||
|
init(overrideReceiveMessage) {
|
||||||
|
let receiveMessage = overrideReceiveMessage || (() => {})
|
||||||
|
// 检查浏览器是否支持WebSocket
|
||||||
|
if (!('WebSocket' in window)) {
|
||||||
|
this.$router.push({ name: 'ErrorPage', params: { error: '浏览器不支持WebSocket' } })
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
// 创建WebSocket实例并设置事件处理函数
|
||||||
|
this.websocket = new WebSocket(this.connectURL)
|
||||||
|
this.websocket.onmessage = (e) => {
|
||||||
|
receiveMessage(e)
|
||||||
|
}
|
||||||
|
this.websocket.onclose = () => {
|
||||||
|
console.log('socket连接关闭----------------------')
|
||||||
|
this.socket_open = false
|
||||||
|
// 尝试重新连接
|
||||||
|
if (this.is_reonnect) {
|
||||||
|
this.reconnect_timer = setTimeout(() => {
|
||||||
|
if (this.reconnect_current > this.reconnect_count) {
|
||||||
|
clearTimeout(this.reconnect_timer)
|
||||||
|
this.is_reonnect = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('socket重连次数:' + this.reconnect_current)
|
||||||
|
this.reconnect_current++
|
||||||
|
this.reconnect()
|
||||||
|
}, this.reconnect_interval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.websocket.onopen = () => {
|
||||||
|
this.socket_open = true
|
||||||
|
this.is_reonnect = true
|
||||||
|
// this.heartbeat()
|
||||||
|
}
|
||||||
|
this.websocket.onerror = () => {}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 发送心跳包
|
||||||
|
heartbeat() {
|
||||||
|
this.hearbeat_timer && clearInterval(this.hearbeat_timer)
|
||||||
|
this.hearbeat_timer = setInterval(() => {
|
||||||
|
let data = {}
|
||||||
|
this.send(data)
|
||||||
|
}, this.hearbeat_interval)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 发送数据
|
||||||
|
send(data, callback = null) {
|
||||||
|
// 如果WebSocket连接已建立,则发送数据
|
||||||
|
if (this.websocket.readyState === this.websocket.OPEN) {
|
||||||
|
this.websocket.send(JSON.stringify(data))
|
||||||
|
callback && callback()
|
||||||
|
} else {
|
||||||
|
// 如果WebSocket连接断开,则跳转到错误页面
|
||||||
|
clearInterval(this.hearbeat_timer)
|
||||||
|
this.$router.push({ name: 'ErrorPage', params: { error: 'socket链接已断开' } })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 关闭WebSocket连接
|
||||||
|
close() {
|
||||||
|
this.is_reonnect = false
|
||||||
|
this.websocket.close()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 重新连接WebSocket
|
||||||
|
reconnect() {
|
||||||
|
// 如果已存在WebSocket实例且不尝试重新连接,则关闭连接
|
||||||
|
if (this.websocket && !this.is_reonnect) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
// 初始化WebSocket连接
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
|
export const useSerialPortStore = defineStore('seralPort', {
|
||||||
|
state: () => ({
|
||||||
|
serialport: {
|
||||||
|
port: '',
|
||||||
|
baudrate: 115200,
|
||||||
|
databits: 8,
|
||||||
|
parity: 0,
|
||||||
|
stopbits: 0
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
setSerialport(data) {
|
||||||
|
this.serialport = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,42 @@
|
||||||
|
// // // 手动配置的地址
|
||||||
|
// window.config = {
|
||||||
|
// url: 'http://192.168.1.17:8000',
|
||||||
|
// wsUrl: 'ws://192.168.1.17:8000',
|
||||||
|
// ws1Url: 'ws://192.168.1.17:8001',
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 手动配置的地址
|
||||||
|
// window.config = {
|
||||||
|
// url: 'http://127.0.0.1:8000',
|
||||||
|
// wsUrl: 'ws://127.0.0.1:8000',
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export default {
|
||||||
|
// url: 'http://127.0.0.1:8000',
|
||||||
|
// wsUrl: 'ws://127.0.0.1:8000'
|
||||||
|
// }
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// url: 'http://127.0.0.1:8000',
|
||||||
|
// wsUrl: 'ws://127.0.0.1:8000',
|
||||||
|
// swichWsUrl: 'ws://127.0.0.1:8001',
|
||||||
|
// serialPortUrl: 'http://127.0.0.1:8000',
|
||||||
|
|
||||||
|
url: 'http://192.168.1.17:8000',
|
||||||
|
wsUrl: 'ws://192.168.1.17:8000',
|
||||||
|
swichWsUrl: 'ws://192.168.1.17:8001',
|
||||||
|
serialPortUrl: 'http://192.168.1.17:8000',
|
||||||
|
|
||||||
|
// 远程连接串口使用
|
||||||
|
// serialPortUrl: 'http://120.77.172.42:7202',
|
||||||
|
// serialPortUrl: 'http://192.168.1.17:8888',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 手动配置的地址
|
||||||
|
// export default {
|
||||||
|
// url: 'http://192.168.1.17:8000',
|
||||||
|
// wsUrl: 'ws://192.168.1.17:8000',
|
||||||
|
// swichWsUrl: 'ws://192.168.1.17:8001',
|
||||||
|
// serialPortUrl: 'http://192.168.1.17:8000',
|
||||||
|
// }
|
|
@ -0,0 +1,6 @@
|
||||||
|
export function guidGenerator() {
|
||||||
|
var S4 = function() {
|
||||||
|
return ((1 + Math.random())*0X10000|0).toString(16).substring(1);
|
||||||
|
};
|
||||||
|
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
import { ElMessage as message } from 'element-plus'
|
||||||
|
// import storage from 'store'
|
||||||
|
// import config from '@renderer/util/config.js'
|
||||||
|
const config = window.electron.readConfig();
|
||||||
|
let receiveMessage = null
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
const socket = reactive({
|
||||||
|
websocket: null,
|
||||||
|
connectURL: config.swichWsUrl + '/ws/log',
|
||||||
|
// 开启标识
|
||||||
|
socket_open: false,
|
||||||
|
// 心跳timer
|
||||||
|
hearbeat_timer: null,
|
||||||
|
// 心跳发送频率
|
||||||
|
hearbeat_interval: 2 * 1000,
|
||||||
|
// 是否自动重连
|
||||||
|
is_reonnect: true,
|
||||||
|
// 重连次数
|
||||||
|
reconnect_count: 3,
|
||||||
|
// 已发起重连次数
|
||||||
|
reconnect_current: 1,
|
||||||
|
// 重连timer
|
||||||
|
reconnect_timer: null,
|
||||||
|
// 重连频率
|
||||||
|
reconnect_interval: 5 * 1000,
|
||||||
|
init: (overrideReceiveMessage) => {
|
||||||
|
if (overrideReceiveMessage) {
|
||||||
|
receiveMessage = overrideReceiveMessage
|
||||||
|
}
|
||||||
|
if (!('WebSocket' in window)) {
|
||||||
|
message.warning('浏览器不支持WebSocket')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
socket.websocket = new WebSocket(socket.connectURL)
|
||||||
|
socket.websocket.onmessage = (e) => {
|
||||||
|
if (receiveMessage) {
|
||||||
|
receiveMessage(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket.websocket.onclose = () => {
|
||||||
|
console.log('socket连接关闭----------------------')
|
||||||
|
socket.socket_open = false
|
||||||
|
// 需要重新连接
|
||||||
|
if (socket.is_reonnect) {
|
||||||
|
socket.reconnect_timer = setTimeout(() => {
|
||||||
|
// 超过重连次数
|
||||||
|
if (socket.reconnect_current > socket.reconnect_count) {
|
||||||
|
clearTimeout(socket.reconnect_timer)
|
||||||
|
socket.is_reonnect = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('socket重连次数:' + socket.reconnect_current)
|
||||||
|
// 记录重连次数
|
||||||
|
socket.reconnect_current++
|
||||||
|
socket.reconnect()
|
||||||
|
}, socket.reconnect_interval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 连接成功
|
||||||
|
socket.websocket.onopen = function () {
|
||||||
|
socket.socket_open = true
|
||||||
|
socket.is_reonnect = true
|
||||||
|
// 开启心跳
|
||||||
|
// socket.heartbeat()
|
||||||
|
}
|
||||||
|
// 连接发生错误
|
||||||
|
socket.websocket.onerror = function () {}
|
||||||
|
},
|
||||||
|
heartbeat: () => {
|
||||||
|
socket.hearbeat_timer && clearInterval(socket.hearbeat_timer)
|
||||||
|
|
||||||
|
socket.hearbeat_timer = setInterval(() => {
|
||||||
|
let data = {
|
||||||
|
// token: storage.get('token')
|
||||||
|
}
|
||||||
|
socket.send(data)
|
||||||
|
}, socket.hearbeat_interval)
|
||||||
|
},
|
||||||
|
send: (data, callback = null) => {
|
||||||
|
// 开启状态直接发送
|
||||||
|
if (socket.websocket.readyState === socket.websocket.OPEN) {
|
||||||
|
socket.websocket.send(JSON.stringify(data))
|
||||||
|
callback && callback()
|
||||||
|
} else {
|
||||||
|
clearInterval(socket.hearbeat_timer)
|
||||||
|
message({
|
||||||
|
type: 'warning',
|
||||||
|
message: 'socket链接已断开',
|
||||||
|
duration: 1000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close: () => {
|
||||||
|
socket.is_reonnect = false
|
||||||
|
socket.websocket.close()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 重新连接
|
||||||
|
*/
|
||||||
|
reconnect: () => {
|
||||||
|
if (socket.websocket && !socket.is_reonnect) {
|
||||||
|
socket.close()
|
||||||
|
}
|
||||||
|
socket.init(receiveMessage)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default socket
|
|
@ -1,15 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="about">
|
|
||||||
<h1>This is an about page</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.about {
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,59 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
|
|
||||||
// 组件注册
|
|
||||||
import Header from '@renderer/components/Header.vue'
|
|
||||||
|
|
||||||
import Aside from '@renderer/components/Aside.vue'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const asideSettings = ref({
|
|
||||||
isCollapse:true,
|
|
||||||
width:'200'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 给子组件绑定事件,通过子组件emit从而改变父组件的值
|
|
||||||
const changeAside = ()=>{
|
|
||||||
asideSettings.value.isCollapse = !asideSettings.value.isCollapse
|
|
||||||
if(asideSettings.value.isCollapse){
|
|
||||||
asideSettings.value.width = "64"
|
|
||||||
}else{
|
|
||||||
asideSettings.value.width = "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<el-container direction="vertical" style="min-height: 100vh;min-width: 100vw;overflow: hidden;">
|
|
||||||
<Header></Header>
|
|
||||||
<el-container >
|
|
||||||
<Aside :width="200"></Aside>
|
|
||||||
<el-main>
|
|
||||||
<RouterView/>
|
|
||||||
</el-main>
|
|
||||||
</el-container>
|
|
||||||
</el-container>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
body{
|
|
||||||
background-color: #eee;
|
|
||||||
max-width: 100vw;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-main {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
height: 100vh;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -0,0 +1,296 @@
|
||||||
|
/*
|
||||||
|
* @Descripttion:
|
||||||
|
* @version:
|
||||||
|
* @Author: lfzxs@qq.com
|
||||||
|
* @Date: 2024-10-16 13:52:11
|
||||||
|
* @LastEditors: lfzxs@qq.com
|
||||||
|
* @LastEditTime: 2024-10-18 16:33:31
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function buildHead(d_length,d_remote_id,d_local_id,d_cmd,d_dev_type,d_data_type,dataStart,dataLength,dataValue,activeData) {
|
||||||
|
// 初始化data为一个32位2进制数
|
||||||
|
|
||||||
|
let data = "0000" + d_data_type + d_dev_type + d_cmd + toBinaryString(d_local_id,9) + toBinaryString(d_remote_id,9) + d_length;
|
||||||
|
|
||||||
|
console.log("获取头部",data);
|
||||||
|
|
||||||
|
let hex_data = binaryToHex(data);
|
||||||
|
let dataBuffer = '';
|
||||||
|
let buffer = hexToBuffer(hex_data);
|
||||||
|
//根据d_cmd的值拼接命令格式
|
||||||
|
switch (d_cmd) {
|
||||||
|
case "0000"://特殊指令
|
||||||
|
break;
|
||||||
|
case "0011"://地址读
|
||||||
|
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)));
|
||||||
|
break;
|
||||||
|
case "0100"://地址写
|
||||||
|
|
||||||
|
if(activeData.dataType === 'hex'){
|
||||||
|
dataValue = rearrangeHexStr(dataValue);
|
||||||
|
dataBuffer = hexToBuffer(dataValue);
|
||||||
|
}else if(activeData.dataType === 'hexString'){
|
||||||
|
dataBuffer = hexToBuffer(dataValue);
|
||||||
|
}else{
|
||||||
|
dataBuffer = stringToHexBuffer(dataValue,dataLength*4*2);
|
||||||
|
}
|
||||||
|
console.log("dataBuffer",dataBuffer)
|
||||||
|
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)),dataBuffer)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log("dataValue-buffer",dataValue,buffer)
|
||||||
|
|
||||||
|
let result = bufferToHex(buffer);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function allBuildHead(d_length,d_remote_id,d_local_id,d_cmd,d_dev_type,d_data_type,dataStart,dataLength,dataValue,allList) {
|
||||||
|
// 初始化data为一个32位2进制数
|
||||||
|
|
||||||
|
let data = "0000" + d_data_type + d_dev_type + d_cmd + toBinaryString(d_local_id,9) + toBinaryString(d_remote_id,9) + d_length;
|
||||||
|
|
||||||
|
console.log("获取头部",data);
|
||||||
|
|
||||||
|
let hex_data = binaryToHex(data);
|
||||||
|
|
||||||
|
let buffer = hexToBuffer(hex_data);
|
||||||
|
let allBufferList = [];
|
||||||
|
//根据d_cmd的值拼接命令格式
|
||||||
|
switch (d_cmd) {
|
||||||
|
case "0000"://特殊指令
|
||||||
|
break;
|
||||||
|
case "0011"://地址读
|
||||||
|
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)));
|
||||||
|
break;
|
||||||
|
case "0100"://地址写
|
||||||
|
allBufferList = allList.map(item=>{
|
||||||
|
return stringToHexBuffer(item.inputValue,item.lengthValue*4*2);
|
||||||
|
})
|
||||||
|
buffer = concatenateBuffers(htonl(buffer),htonl(toFixedSizeBuffer(parseInt(dataStart),4)),htonl(toFixedSizeBuffer(parseInt(dataLength),4)),...allBufferList)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = bufferToHex(buffer);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bufferToHex(buffer) {
|
||||||
|
let hexString = '';
|
||||||
|
const view = new Uint8Array(buffer);
|
||||||
|
for (let i = 0; i < view.length; i++) {
|
||||||
|
const hex = view[i].toString(16).padStart(2, '0');
|
||||||
|
hexString += hex;
|
||||||
|
}
|
||||||
|
return hexString;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toBinaryString(number, length) {
|
||||||
|
let binaryString = number.toString(2);
|
||||||
|
return binaryString.padStart(length, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function binaryToHex(binaryStr) {
|
||||||
|
// 确保二进制字符串长度是4的倍数
|
||||||
|
if (binaryStr.length % 4 !== 0) {
|
||||||
|
binaryStr = binaryStr.padStart(binaryStr.length + 4 - (binaryStr.length % 4), '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
let hexStr = '';
|
||||||
|
for (let i = 0; i < binaryStr.length; i += 4) {
|
||||||
|
// 取出每4位二进制字符串
|
||||||
|
const binaryChunk = binaryStr.slice(i, i + 4);
|
||||||
|
// 转换成十六进制字符并追加到结果字符串中
|
||||||
|
hexStr += parseInt(binaryChunk, 2).toString(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hexStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function hexToBuffer(hexStr) {
|
||||||
|
if (hexStr.length % 2 !== 0) {
|
||||||
|
throw new Error('Invalid hex string');
|
||||||
|
}
|
||||||
|
|
||||||
|
let buffer = new ArrayBuffer(hexStr.length / 2);
|
||||||
|
let view = new Uint8Array(buffer);
|
||||||
|
|
||||||
|
for (let i = 0; i < hexStr.length; i += 2) {
|
||||||
|
view[i / 2] = parseInt(hexStr.substr(i, 2), 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function swapEndian(buffer) {
|
||||||
|
const swappedBuffer = new ArrayBuffer(buffer.byteLength);
|
||||||
|
const view = new DataView(buffer);
|
||||||
|
const swappedView = new DataView(swappedBuffer);
|
||||||
|
|
||||||
|
for (let i = 0; i < buffer.byteLength; i++) {
|
||||||
|
swappedView.setUint8(i, view.getUint8(buffer.byteLength - 1 - i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return swappedBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function htonl(buffer) {
|
||||||
|
if (buffer.byteLength !== 4) {
|
||||||
|
throw new Error('Buffer must be exactly 4 bytes.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let view = new DataView(buffer);
|
||||||
|
let number = view.getUint32(0);
|
||||||
|
|
||||||
|
let swappedNumber = ((number & 0xFF) << 24) |
|
||||||
|
((number & 0xFF00) << 8) |
|
||||||
|
((number & 0xFF0000) >> 8) |
|
||||||
|
((number >> 24) & 0xFF);
|
||||||
|
|
||||||
|
let swappedBuffer = new ArrayBuffer(4);
|
||||||
|
let swappedView = new DataView(swappedBuffer);
|
||||||
|
swappedView.setUint32(0, swappedNumber);
|
||||||
|
|
||||||
|
return swappedBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//将数字转换成指定字节大小的buffer
|
||||||
|
export function toFixedSizeBuffer(number, byteSize) {
|
||||||
|
if (byteSize <= 0) {
|
||||||
|
throw new Error('Byte size must be greater than zero.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let buffer = new ArrayBuffer(byteSize);
|
||||||
|
let view = new DataView(buffer);
|
||||||
|
|
||||||
|
// 根据指定字节数设置数值到缓冲区中
|
||||||
|
for (let i = 0; i < byteSize; i++) {
|
||||||
|
view.setUint8(byteSize - 1 - i, number & 0xFF);
|
||||||
|
number = number >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function concatenateBuffers(...buffers) {
|
||||||
|
|
||||||
|
// 确保所有元素均为 ArrayBuffer
|
||||||
|
buffers.forEach(buffer => {
|
||||||
|
if (!(buffer instanceof ArrayBuffer)) {
|
||||||
|
throw new TypeError('All arguments must be ArrayBuffers');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 计算总长度
|
||||||
|
let totalLength = buffers.reduce((sum, buffer) => sum + buffer.byteLength, 0);
|
||||||
|
|
||||||
|
// 创建一个新的 ArrayBuffer 并使用 Uint8Array 进行操作
|
||||||
|
let concatenatedBuffer = new Uint8Array(totalLength);
|
||||||
|
let offset = 0;
|
||||||
|
|
||||||
|
// 逐个复制每个缓冲区的内容
|
||||||
|
buffers.forEach(buffer => {
|
||||||
|
concatenatedBuffer.set(new Uint8Array(buffer), offset);
|
||||||
|
offset += buffer.byteLength;
|
||||||
|
});
|
||||||
|
|
||||||
|
return concatenatedBuffer.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stringToHexBuffer(str,length) {
|
||||||
|
// return new TextEncoder().encode(str).buffer;
|
||||||
|
const bufferView = new TextEncoder().encode(str);
|
||||||
|
|
||||||
|
// 计算需要补充的00的数量
|
||||||
|
const targetLength = length / 2; // 目标长度(字节数)
|
||||||
|
const paddingLength = targetLength - bufferView.length;
|
||||||
|
|
||||||
|
// 创建一个新的Uint8Array,长度为目标长度
|
||||||
|
const paddedBufferView = new Uint8Array(targetLength);
|
||||||
|
|
||||||
|
// 将原始Uint8Array的内容复制到新的Uint8Array中
|
||||||
|
paddedBufferView.set(bufferView);
|
||||||
|
|
||||||
|
// 填充00
|
||||||
|
if (paddingLength > 0) {
|
||||||
|
paddedBufferView.fill(0, bufferView.length, targetLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回格式化后的Uint8Array
|
||||||
|
return paddedBufferView.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hexToString(hexStr) {
|
||||||
|
let str = '';
|
||||||
|
for (let i = 0; i < hexStr.length; i += 2) {
|
||||||
|
if(hexStr.substr(i, 2)!=='00'){
|
||||||
|
str += String.fromCharCode(parseInt(hexStr.substr(i, 2), 16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rearrangeHexStr(hexStr) {
|
||||||
|
// 将输入的十六进制字符串解析为字节数组
|
||||||
|
// 将输入的十六进制字符串按每8位分组
|
||||||
|
const groups = [];
|
||||||
|
for (let i = 0; i < hexStr.length; i += 8) {
|
||||||
|
groups.push(hexStr.slice(i, i + 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对每个组内的每两位进行倒序拼接
|
||||||
|
const rearrangedGroups = groups.map(group => {
|
||||||
|
let rearrangedGroup = '';
|
||||||
|
for (let i = 0; i < group.length; i += 2) {
|
||||||
|
rearrangedGroup = group.substr(i, 2) + rearrangedGroup;
|
||||||
|
}
|
||||||
|
return rearrangedGroup;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将所有组重新拼接成一个字符串
|
||||||
|
const rearrangedHexStr = rearrangedGroups.join('');
|
||||||
|
|
||||||
|
return rearrangedHexStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//高低位交换
|
||||||
|
export function rearrangeHexStr4(hexStr) {
|
||||||
|
let rearrangedGroup = '';
|
||||||
|
for (let i = 0; i < hexStr.length; i += 2) {
|
||||||
|
rearrangedGroup = hexStr.substr(i, 2) + rearrangedGroup;
|
||||||
|
}
|
||||||
|
return rearrangedGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hexToVersion(hexStr) {
|
||||||
|
let str = rearrangeHexStr(hexStr);
|
||||||
|
str = hexToDec(str);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function versionToHex(hexStr) {
|
||||||
|
let str = decToHex(hexStr);
|
||||||
|
str = rearrangeHexStr(str);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 十六进制转十进制
|
||||||
|
export function hexToDec(hexStr) {
|
||||||
|
// 去除前缀 "0x"(如果存在)
|
||||||
|
hexStr = hexStr.replace(/^0x/, '');
|
||||||
|
// 将十六进制字符串转换为十进制数字
|
||||||
|
return parseInt(hexStr, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 十进制转十六进制
|
||||||
|
export function decToHex(decNum) {
|
||||||
|
// 将十进制数字转换为十六进制字符串
|
||||||
|
let hexStr = decNum.toString(16);
|
||||||
|
// 可选:添加前缀 "0x"
|
||||||
|
return `0x${hexStr}`;
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>测试test</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'test'
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
</style>
|
|