Browse Source

调试弹窗

master
hejl 3 weeks ago
parent
commit
529e6fb652
  1. BIN
      gofaster/app/dist/renderer/img/background.7c5f6fb1.png
  2. 12
      gofaster/app/dist/renderer/index.html
  3. 20276
      gofaster/app/dist/renderer/js/chunk-vendors.js
  4. 1
      gofaster/app/dist/renderer/js/chunk-vendors.js.map
  5. 1312
      gofaster/app/dist/renderer/js/index.js
  6. 1
      gofaster/app/dist/renderer/js/index.js.map
  7. 80
      gofaster/app/package-lock.json
  8. 10
      gofaster/app/package.json
  9. 11
      gofaster/app/public/index.html
  10. 57
      gofaster/app/src/main/index.js
  11. 10
      gofaster/app/src/preload.js
  12. 35
      gofaster/app/src/public/index.html
  13. 33
      gofaster/app/src/renderer/App.vue
  14. BIN
      gofaster/app/src/renderer/assets/background.png
  15. 75
      gofaster/app/src/renderer/components/StatusBar.vue
  16. 5
      gofaster/app/src/renderer/services/db.js
  17. 91
      gofaster/app/vue.config.js

BIN
gofaster/app/dist/renderer/img/background.7c5f6fb1.png vendored

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

12
gofaster/app/dist/renderer/index.html vendored

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Vue App</title>
<script defer src="js/chunk-vendors.js"></script><script defer src="js/index.js"></script></head>
<body>
<div id="app"></div>
</body>
</html>

20276
gofaster/app/dist/renderer/js/chunk-vendors.js vendored

File diff suppressed because it is too large Load Diff

1
gofaster/app/dist/renderer/js/chunk-vendors.js.map vendored

File diff suppressed because one or more lines are too long

1312
gofaster/app/dist/renderer/js/index.js vendored

File diff suppressed because it is too large Load Diff

1
gofaster/app/dist/renderer/js/index.js.map vendored

File diff suppressed because one or more lines are too long

80
gofaster/app/package-lock.json generated

@ -1,13 +1,12 @@ @@ -1,13 +1,12 @@
{
"name": "app",
"name": "GoFaster",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "app",
"name": "GoFaster",
"version": "1.0.0",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
"lowdb": "^7.0.1",
@ -16,10 +15,13 @@ @@ -16,10 +15,13 @@
},
"devDependencies": {
"@electron/remote": "^2.1.3",
"@types/node": "^24.2.1",
"@vue/cli-service": "^5.0.8",
"concurrently": "^9.2.0",
"electron": "^37.2.6",
"electron-builder": "^26.0.12",
"electron-reload": "^2.0.0-alpha.1",
"global": "^4.4.0",
"vue": "^3.5.18",
"wait-on": "^8.0.4"
}
@ -1293,12 +1295,12 @@ @@ -1293,12 +1295,12 @@
"dev": true
},
"node_modules/@types/node": {
"version": "22.17.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.1.tgz",
"integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==",
"version": "24.2.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-24.2.1.tgz",
"integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==",
"dev": true,
"dependencies": {
"undici-types": "~6.21.0"
"undici-types": "~7.10.0"
}
},
"node_modules/@types/node-forge": {
@ -4536,6 +4538,12 @@ @@ -4536,6 +4538,12 @@
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
"dev": true
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
@ -4842,6 +4850,15 @@ @@ -4842,6 +4850,15 @@
"node": ">=4.0.0"
}
},
"node_modules/electron-reload": {
"version": "2.0.0-alpha.1",
"resolved": "https://registry.npmmirror.com/electron-reload/-/electron-reload-2.0.0-alpha.1.tgz",
"integrity": "sha512-hTde7gv0TEqxbxlB3pj2CwoyCQ9sdiQrcP8GkpzhosxyVeYM3mZbMEVKCZK3L0fED7Mz5A9IWmK7zEvi4H3P1g==",
"dev": true,
"dependencies": {
"chokidar": "^3.5.2"
}
},
"node_modules/electron-to-chromium": {
"version": "1.5.199",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.199.tgz",
@ -4904,6 +4921,21 @@ @@ -4904,6 +4921,21 @@
"node": ">= 4.0.0"
}
},
"node_modules/electron/node_modules/@types/node": {
"version": "22.17.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.17.1.tgz",
"integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==",
"dev": true,
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/electron/node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@ -5828,6 +5860,16 @@ @@ -5828,6 +5860,16 @@
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true
},
"node_modules/global": {
"version": "4.4.0",
"resolved": "https://registry.npmmirror.com/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"dev": true,
"dependencies": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"node_modules/global-agent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
@ -7417,6 +7459,15 @@ @@ -7417,6 +7459,15 @@
"node": ">=4"
}
},
"node_modules/min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"dev": true,
"dependencies": {
"dom-walk": "^0.1.0"
}
},
"node_modules/mini-css-extract-plugin": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.3.tgz",
@ -8992,6 +9043,15 @@ @@ -8992,6 +9043,15 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dev": true,
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -10805,9 +10865,9 @@ @@ -10805,9 +10865,9 @@
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"version": "7.10.0",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.10.0.tgz",
"integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
"dev": true
},
"node_modules/unique-filename": {

10
gofaster/app/package.json

@ -3,11 +3,10 @@ @@ -3,11 +3,10 @@
"version": "1.0.0",
"main": "src/main/index.js",
"scripts": {
"serve": "vue-cli-service serve",
"dev": "vue-cli-service build --mode development && electron .",
"dev:watch": "vue-cli-service build --mode development --watch & electron .",
"build": "vue-cli-service build && electron-builder",
"start": "electron .",
"dev": "concurrently \"npm run serve\" \"wait-on http://localhost:8080 && npm run start\"",
"postinstall": "electron-builder install-app-deps"
"electron:serve": "vue-cli-service build --mode development && electron ."
},
"keywords": [],
"author": "",
@ -15,10 +14,13 @@ @@ -15,10 +14,13 @@
"description": "",
"devDependencies": {
"@electron/remote": "^2.1.3",
"@types/node": "^24.2.1",
"@vue/cli-service": "^5.0.8",
"concurrently": "^9.2.0",
"electron": "^37.2.6",
"electron-builder": "^26.0.12",
"electron-reload": "^2.0.0-alpha.1",
"global": "^4.4.0",
"vue": "^3.5.18",
"wait-on": "^8.0.4"
},

11
gofaster/app/public/index.html

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GoFaster</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

57
gofaster/app/src/main/index.js

@ -1,43 +1,66 @@ @@ -1,43 +1,66 @@
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
// 获取项目根目录绝对路径
const appRoot = path.resolve(__dirname, '../..')
console.log('Application root:', appRoot)
let mainWindow
// 开发环境热重载
if (process.env.NODE_ENV === 'development') {
require('electron-reload')(__dirname, {
electron: path.join(__dirname, 'node_modules', '.bin', 'electron'),
hardResetMethod: 'exit'
});
}
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
autoHideMenuBar: true,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
enableRemoteModule: false,
preload: path.join(__dirname, '../preload.js')
preload: path.join(appRoot, 'src/preload.js')
}
})
// 开发模式下加载开发服务器
// 开发环境下抑制安全警告
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:8080')
mainWindow.webContents.openDevTools()
} else {
mainWindow.loadFile(path.join(__dirname, '../public/index.html'))
mainWindow.webContents.on('did-frame-finish-load', () => {
mainWindow.webContents.executeJavaScript(`
console.warn = console.error = () => {};
`).catch(err => console.error('抑制警告失败:', err));
});
}
mainWindow.on('closed', () => {
mainWindow = null
const loadPath = path.join(appRoot, 'dist/renderer/index.html')
console.log('Loading:', loadPath)
mainWindow.loadFile(loadPath).catch(err => {
console.error('加载失败:', err)
mainWindow.loadURL(`data:text/html,<h1>加载失败: ${err.toString()}</h1>`)
})
mainWindow.webContents.openDevTools()
}
app.whenReady().then(createWindow)
app.whenReady().then(() => {
createWindow()
ipcMain.on('request-status', (event) => {
const statusData = { /* 你的数据 */ }
event.sender.send('status-update', statusData)
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
})
if (mainWindow === null) createWindow()
})

10
gofaster/app/src/preload.js

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
const { contextBridge } = require('electron')
// preload.js
const { contextBridge, ipcRenderer } = require('electron')
// 安全地暴露API给渲染进程
contextBridge.exposeInMainWorld('electron', {
platform: process.platform
// 可以添加更多安全的API
contextBridge.exposeInMainWorld('electronAPI', {
sendStatusRequest: () => ipcRenderer.send('request-status'),
onStatusUpdate: (callback) => ipcRenderer.on('status-update', callback)
})

35
gofaster/app/src/public/index.html

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
<base href="./">
<!-- 强化 CSP 策略 -->
<meta http-equiv="Content-Security-Policy" content="
default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self' ws:;
object-src 'none';
frame-src 'none';
base-uri 'self';
form-action 'none';
">
<!-- 全局 polyfill 解决方案 -->
<script>
(function() {
if (typeof global === 'undefined') {
if (typeof window !== 'undefined') window.global = window;
else if (typeof self !== 'undefined') self.global = self;
else if (typeof globalThis !== 'undefined') globalThis.global = globalThis;
}
})();
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>

33
gofaster/app/src/renderer/App.vue

@ -1,13 +1,24 @@ @@ -1,13 +1,24 @@
<!-- src/App.vue -->
<template>
<div id="app">
<router-view />
<StatusBar />
</div>
</template>
<script>
import StatusBar from './components/StatusBar.vue';
export default {
name: 'App'
}
name: 'App',
components: {
StatusBar
},
mounted() {
//
window.electronAPI?.sendStatusRequest();
}
};
</script>
<style>
@ -19,5 +30,23 @@ export default { @@ -19,5 +30,23 @@ export default {
color: #2c3e50;
margin: 0;
padding: 0;
height: 100vh;
width: 100vw;
/* 添加背景图片 */
background-image: url('@/assets/background.png');
/* 假设图片放在src/assets目录下 */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
/* 确保html和body元素也填满窗口 */
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
</style>

BIN
gofaster/app/src/renderer/assets/background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

75
gofaster/app/src/renderer/components/StatusBar.vue

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
<!-- src/components/StatusBar.vue -->
<template>
<div class="status-bar">
<div class="status-item">服务地址: {{ serverUrl }}</div>
<div class="status-item">用户: {{ userInfo }}</div>
<div class="status-item">最近错误: {{ errorCount }}</div>
<div class="status-item">版本: {{ appVersion }}</div>
<div class="status-item">内存: {{ memoryUsage }} MB</div>
</div>
</template>
<script>
import { ref, onMounted, onUnmounted } from 'vue';
export default {
name: 'StatusBar',
setup() {
const serverUrl = ref(process.env.NODE_ENV === 'development' ? 'http://localhost:8080' : window.location.href);
const userInfo = ref('未登录');
const errorCount = ref(0);
const appVersion = ref(process.env.VUE_APP_VERSION || '1.0.0');
const memoryUsage = ref(0);
// 使
let intervalId;
onMounted(() => {
intervalId = setInterval(() => {
if (window.performance && window.performance.memory) {
memoryUsage.value = (window.performance.memory.usedJSHeapSize / (1024 * 1024)).toFixed(2);
}
}, 2000);
});
onUnmounted(() => {
clearInterval(intervalId);
});
//
window.electronAPI?.onStatusUpdate((event, data) => {
if (data.userInfo) userInfo.value = data.userInfo;
if (data.errorCount !== undefined) errorCount.value = data.errorCount;
});
return {
serverUrl,
userInfo,
errorCount,
appVersion,
memoryUsage
};
}
};
</script>
<style scoped>
.status-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 24px;
background-color: #333;
color: #fff;
display: flex;
align-items: center;
padding: 0 10px;
font-size: 12px;
border-top: 1px solid #444;
z-index: 1000;
}
.status-item {
margin-right: 20px;
}
</style>

5
gofaster/app/src/renderer/services/db.js

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
import { Low, JSONFile } from 'lowdb'
import { Low } from 'lowdb'
import { JSONFile } from 'lowdb/node' // 注意这里的变化
import { join } from 'path'
import { app } from '@electron/remote'
@ -6,6 +7,8 @@ const file = join(app.getPath('userData'), 'gofaster-db.json') @@ -6,6 +7,8 @@ const file = join(app.getPath('userData'), 'gofaster-db.json')
const adapter = new JSONFile(file)
const db = new Low(adapter)
// 其余代码保持不变...
// 初始化数据库
async function initDB() {
await db.read()

91
gofaster/app/vue.config.js

@ -1,55 +1,86 @@ @@ -1,55 +1,86 @@
const path = require('path')
const { defineConfig } = require('@vue/cli-service')
const appRoot = path.resolve(__dirname)
module.exports = defineConfig({
outputDir: path.resolve(__dirname, 'dist/renderer'),
outputDir: path.join(appRoot, 'dist/renderer'),
publicPath: './',
// 关键修改:配置 Electron 构建目标和排除原生模块
configureWebpack: {
target: 'electron-renderer', // 指定为 Electron 渲染进程
externals: {
electron: 'require("electron")', // 防止 Webpack 处理 electron 模块
fs: 'require("fs")', // 排除 Node.js 原生模块
path: 'require("path")',
target: 'electron-renderer',
node: {
global: false, // 禁用全局 polyfill
__dirname: true
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src/renderer'),
// 确保 Vue 单文件组件引用时自动补全扩展名
'views': path.resolve(__dirname, 'src/renderer/views')
},
// 添加扩展名自动解析
extensions: ['.js', '.vue', '.json']
fallback: {
global: false // 禁用 fallback
},
alias: {
'@': path.join(appRoot, 'src/renderer'),
'views': path.join(appRoot, 'src/renderer/views')
},
extensions: ['.js', '.vue', '.json']
},
externals: {
electron: 'require("electron")',
fs: 'require("fs")',
path: 'require("path")'
}
},
// 保留原有页面配置
pages: {
index: {
entry: 'src/renderer/main.js',
template: 'public/index.html',
entry: path.join(appRoot, 'src/renderer/main.js'),
template: path.join(appRoot, 'public/index.html'),
filename: 'index.html'
}
},
// 保留 Electron Builder 配置
pluginOptions: {
electronBuilder: {
preload: 'src/preload.js',
nodeIntegration: false,
contextIsolation: true,
// 可选:明确指定主进程文件路径
mainProcessFile: 'src/main/index.js'
preload: path.join(appRoot, 'src/preload.js'),
mainProcessFile: path.join(appRoot, 'src/main/index.js'),
builderOptions: {
extraResources: [{
from: path.join(appRoot, 'dist/renderer'),
to: 'app',
filter: ["**/*"]
}]
}
}
},
// 开发服务器配置(与 Electron 主进程配合)
devServer: {
port: 8080, // 确保与 wait-on 端口一致
hot: true,
headers: {
'Access-Control-Allow-Origin': '*'
}
hot: false,
liveReload: false,
allowedHosts: "all",
static: {
directory: path.join(__dirname, 'dist/renderer'),
watch: false
},
compress: false,
proxy: null
},
chainWebpack: config => {
// 开发环境 sourcemap
config.devtool(process.env.NODE_ENV === 'development'
? 'source-map'
: false)
// 静态资源处理
config.module
.rule('images')
.set('generator', {
filename: 'img/[name].[hash:8][ext]'
})
// 全局变量定义
config.plugin('define').tap(args => {
args[0]['global.GLOBAL'] = JSON.stringify(false)
return args
})
}
})
Loading…
Cancel
Save