优化重启逻辑
30
electron_h5/.gitignore
vendored
@@ -1,30 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
.DS_Store
|
|
||||||
electron_h5
|
|
||||||
dist-ssr
|
|
||||||
coverage
|
|
||||||
*.local
|
|
||||||
|
|
||||||
/cypress/videos/
|
|
||||||
/cypress/screenshots/
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.idea
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
|
|
||||||
*.tsbuildinfo
|
|
||||||
3
electron_h5/.vscode/extensions.json
vendored
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": ["Vue.volar"]
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# electron_h5
|
|
||||||
|
|
||||||
This template should help get you started developing with Vue 3 in Vite.
|
|
||||||
|
|
||||||
## Recommended IDE Setup
|
|
||||||
|
|
||||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
|
||||||
|
|
||||||
## Customize configuration
|
|
||||||
|
|
||||||
See [Vite Configuration Reference](https://vite.dev/config/).
|
|
||||||
|
|
||||||
## Project Setup
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compile and Hot-Reload for Development
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compile and Minify for Production
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
services:
|
|
||||||
bqw-ai-system:
|
|
||||||
environment:
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
LANG: C.UTF-8
|
|
||||||
LC_ALL: C.UTF-8
|
|
||||||
DIFY_DB_HOST: 10.102.8.56
|
|
||||||
DIFY_API_HOST: 10.102.8.56
|
|
||||||
DIFY_API_PORT: 30080
|
|
||||||
restart: always
|
|
||||||
container_name: bqw-ai-system
|
|
||||||
image: java:1.8.391
|
|
||||||
volumes:
|
|
||||||
- ./system/target/bqw-ai.jar:/application/app.jar
|
|
||||||
- ./system/logs:/logs
|
|
||||||
- ./system/data:/application/data
|
|
||||||
command: java -jar -Dfile.encoding=UTF-8 /application/app.jar
|
|
||||||
logging:
|
|
||||||
driver: "json-file"
|
|
||||||
options:
|
|
||||||
max-size: "1024m"
|
|
||||||
max-file: "3"
|
|
||||||
depends_on:
|
|
||||||
- bqw-ai-mysql
|
|
||||||
- bqw-ai-redis
|
|
||||||
bqw-ai-magic:
|
|
||||||
environment:
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
LANG: C.UTF-8
|
|
||||||
LC_ALL: C.UTF-8
|
|
||||||
restart: always
|
|
||||||
container_name: bqw-ai-magic
|
|
||||||
image: java:1.8.391
|
|
||||||
depends_on:
|
|
||||||
- bqw-ai-mysql
|
|
||||||
- bqw-ai-redis
|
|
||||||
volumes:
|
|
||||||
- ./system/target/magic-api-demo.jar:/application/app.jar
|
|
||||||
- ./system/logs:/logs
|
|
||||||
- ./system/data:/application/data
|
|
||||||
command: java -jar -Dfile.encoding=UTF-8 /application/app.jar
|
|
||||||
logging:
|
|
||||||
driver: "json-file"
|
|
||||||
options:
|
|
||||||
max-size: "1024m"
|
|
||||||
max-file: "3"
|
|
||||||
bqw-ai-mysql:
|
|
||||||
environment:
|
|
||||||
MYSQL_ROOT_PASSWORD: Mars@23600800
|
|
||||||
MYSQL_ROOT_HOST: '%'
|
|
||||||
MYSQL_DATABASE: ai-application
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
restart: always
|
|
||||||
privileged: true
|
|
||||||
container_name: bqw-ai-mysql
|
|
||||||
image: mysql:8.0.33
|
|
||||||
command:
|
|
||||||
--character-set-server=utf8mb4
|
|
||||||
--collation-server=utf8mb4_general_ci
|
|
||||||
--explicit_defaults_for_timestamp=true
|
|
||||||
--lower_case_table_names=1
|
|
||||||
--max_allowed_packet=128M
|
|
||||||
--default-authentication-plugin=caching_sha2_password
|
|
||||||
volumes:
|
|
||||||
- ./mysql/data/:/var/lib/mysql/
|
|
||||||
- ./mysql/sql:/docker-entrypoint-initdb.d
|
|
||||||
bqw-ai-redis:
|
|
||||||
image: redis:7.0.4
|
|
||||||
environment:
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
restart: always
|
|
||||||
container_name: bqw-ai-redis
|
|
||||||
volumes:
|
|
||||||
- ./redis/conf:/redis/config:rw
|
|
||||||
- ./redis/data/:/redis/data/:rw
|
|
||||||
command: "redis-server /redis/config/redis.conf"
|
|
||||||
privileged: true
|
|
||||||
bqw-ai-web:
|
|
||||||
image: nginx:1.23.4
|
|
||||||
ports:
|
|
||||||
- 18900:80
|
|
||||||
- 18901:8080
|
|
||||||
- 18902:8081
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
LANG: C.UTF-8
|
|
||||||
LC_ALL: C.UTF-8
|
|
||||||
container_name: bqw-ai-web
|
|
||||||
volumes:
|
|
||||||
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
|
|
||||||
- ./nginx/html/dist:/usr/share/nginx/html
|
|
||||||
- ./nginx/html/chat:/usr/share/nginx/chat
|
|
||||||
- ./nginx/html/llm_flow:/usr/share/nginx/llm_flow
|
|
||||||
- ./nginx/html/electron_h5:/usr/share/nginx/electron_h5
|
|
||||||
depends_on:
|
|
||||||
- bqw-ai-system
|
|
||||||
logging:
|
|
||||||
driver: "json-file"
|
|
||||||
options:
|
|
||||||
max-size: "1024m"
|
|
||||||
max-file: "3"
|
|
||||||
bqw-ai-minio:
|
|
||||||
image: minio/minio
|
|
||||||
privileged: true
|
|
||||||
restart: always
|
|
||||||
container_name: bqw-ai-minio
|
|
||||||
# ports:
|
|
||||||
# # api端口
|
|
||||||
# - 9000:9000
|
|
||||||
# # 控制台页面端口
|
|
||||||
# - 9011:9011
|
|
||||||
environment:
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
MINIO_ACCESS_KEY: admin
|
|
||||||
MINIO_SECRET_KEY: Huashiai@2024
|
|
||||||
volumes:
|
|
||||||
- ./minio/data:/data
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
command: server /data --console-address ":9011"
|
|
||||||
logging:
|
|
||||||
driver: "json-file"
|
|
||||||
options:
|
|
||||||
max-size: "1024m"
|
|
||||||
max-file: "3"
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link rel="icon" href="/favicon.ico">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>龙岗区百千万AI智能体共创平台</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exclude": ["node_modules", "dist"]
|
|
||||||
}
|
|
||||||
@@ -1,276 +0,0 @@
|
|||||||
user root;
|
|
||||||
worker_processes auto;
|
|
||||||
|
|
||||||
error_log /var/log/nginx/error.log notice;
|
|
||||||
pid /var/run/nginx.pid;
|
|
||||||
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
http {
|
|
||||||
include /etc/nginx/mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
||||||
'$status $body_bytes_sent "$http_referer" '
|
|
||||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
|
||||||
|
|
||||||
access_log /var/log/nginx/access.log main;
|
|
||||||
sendfile on;
|
|
||||||
#tcp_nopush on;
|
|
||||||
keepalive_timeout 65;
|
|
||||||
#gzip on;
|
|
||||||
gzip on;
|
|
||||||
gzip_min_length 1k;
|
|
||||||
gzip_comp_level 9;
|
|
||||||
gzip_types text/plain application/x-javascript text/javascript application/x-httpd-php text/css text/xml text/jsp application/eot application/ttf application/otf application/svg application/woff application/javascript application/xml image/jpeg image/gif image/png;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_disable "MSIE [1-6].";
|
|
||||||
# 除去 Web 站点中的信用卡号
|
|
||||||
sub_filter '(\d{4}[- ]?){3}\d{4}' '**** **** **** ****';
|
|
||||||
sub_filter_once off;
|
|
||||||
|
|
||||||
# 全局设置允许的最大请求体大小
|
|
||||||
client_max_body_size 2048m;
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name localhost;
|
|
||||||
location ^~/bqw-ai {
|
|
||||||
proxy_pass http://bqw-ai-system:8080/bqw-ai;
|
|
||||||
proxy_set_header Host 127.0.0.1;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
|
|
||||||
# 允许跨域请求
|
|
||||||
add_header Access-Control-Allow-Origin *;
|
|
||||||
# 允许带身份验证信息的跨域请求
|
|
||||||
add_header Access-Control-Allow-Credentials true;
|
|
||||||
# 允许的请求方法
|
|
||||||
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
|
||||||
# 允许的请求头
|
|
||||||
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
|
||||||
# 预检请求的有效期
|
|
||||||
add_header Access-Control-Max-Age 3600;
|
|
||||||
# 处理 OPTIONS 请求
|
|
||||||
if ($request_method = 'OPTIONS') {
|
|
||||||
add_header Content-Type 'text/plain; charset=utf-8';
|
|
||||||
add_header Content-Length 0;
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
location /bqw-ai/websocket {
|
|
||||||
proxy_pass http://bqw-ai-system:8080/bqw-ai/websocket;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_read_timeout 900s;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html/;
|
|
||||||
index index.html index.htm;
|
|
||||||
if (!-e $request_filename) {
|
|
||||||
rewrite ^(.*)$ /index.html?s=$1last;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
location /h5_client {
|
|
||||||
alias /usr/share/nginx/llm_flow/;
|
|
||||||
index index.html index.htm;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /electron_h5 {
|
|
||||||
alias /usr/share/nginx/electron_h5/;
|
|
||||||
index index.html index.htm;
|
|
||||||
}
|
|
||||||
|
|
||||||
# http://10.180.6.206
|
|
||||||
# https://xtbg.lg.gov.cn/LGOA
|
|
||||||
|
|
||||||
|
|
||||||
location /LGOA {
|
|
||||||
proxy_pass https://xtbg.lg.gov.cn/LGOA;
|
|
||||||
}
|
|
||||||
location /OAZS {
|
|
||||||
proxy_pass http://10.180.6.206/OAZS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
location /magic {
|
|
||||||
proxy_pass http://bqw-ai-magic:9999/magic;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
location /magic/web/console {
|
|
||||||
proxy_pass http://bqw-ai-magic:9999/magic/web/console;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_read_timeout 900s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# minio-api
|
|
||||||
location /minio-api/ {
|
|
||||||
proxy_pass http://bqw-ai-minio:9000/;
|
|
||||||
}
|
|
||||||
|
|
||||||
#minio页面
|
|
||||||
location /minio/login {
|
|
||||||
proxy_pass http://bqw-ai-minio:9011;
|
|
||||||
# 启用支持websocket连接
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
client_max_body_size 1024m;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_connect_timeout 3600;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Forwarded-Host $http_host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
location /bqw-ai/sys/common/static/bqw-ai-file/ {
|
|
||||||
proxy_pass http://bqw-ai-minio:9000/bqw-ai-file/;
|
|
||||||
|
|
||||||
# 可选:添加一些常用的代理设置
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# 如果需要处理大文件上传或下载,可以调整超时时间
|
|
||||||
proxy_connect_timeout 600;
|
|
||||||
proxy_send_timeout 600;
|
|
||||||
proxy_read_timeout 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
location /h5_client/bqw-ai-file/ {
|
|
||||||
proxy_pass http://bqw-ai-minio:9000/bqw-ai-file/;
|
|
||||||
|
|
||||||
# 可选:添加一些常用的代理设置
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# 如果需要处理大文件上传或下载,可以调整超时时间
|
|
||||||
proxy_connect_timeout 600;
|
|
||||||
proxy_send_timeout 600;
|
|
||||||
proxy_read_timeout 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
location /bqw-video/ {
|
|
||||||
proxy_pass http://10.102.8.55:8090/;
|
|
||||||
|
|
||||||
# 可选:添加一些常用的代理设置
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# 如果需要处理大文件上传或下载,可以调整超时时间
|
|
||||||
proxy_connect_timeout 600;
|
|
||||||
proxy_send_timeout 600;
|
|
||||||
proxy_read_timeout 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
location /bqw-ai-file/ {
|
|
||||||
proxy_pass http://bqw-ai-minio:9000/bqw-ai-file/;
|
|
||||||
|
|
||||||
# 可选:添加一些常用的代理设置
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# 如果需要处理大文件上传或下载,可以调整超时时间
|
|
||||||
proxy_connect_timeout 600;
|
|
||||||
proxy_send_timeout 600;
|
|
||||||
proxy_read_timeout 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
server {
|
|
||||||
|
|
||||||
listen 8081;
|
|
||||||
server_name localhost;
|
|
||||||
|
|
||||||
client_max_body_size 2000M;
|
|
||||||
|
|
||||||
# minio-api
|
|
||||||
location / {
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
|
|
||||||
proxy_connect_timeout 300;
|
|
||||||
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Connection "";
|
|
||||||
chunked_transfer_encoding off;
|
|
||||||
|
|
||||||
proxy_pass http://bqw-ai-minio:9000/;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 8080;
|
|
||||||
server_name localhost;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# minio-api
|
|
||||||
location /minio-api/ {
|
|
||||||
proxy_pass http://bqw-ai-minio:9000/;
|
|
||||||
}
|
|
||||||
|
|
||||||
#minio页面
|
|
||||||
location / {
|
|
||||||
proxy_pass http://bqw-ai-minio:9011;
|
|
||||||
# 启用支持websocket连接
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
client_max_body_size 1024m;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_connect_timeout 3600;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Forwarded-Host $http_host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
include /etc/nginx/conf.d/*.conf;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "electron_h5",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "vite build",
|
|
||||||
"preview": "vite preview"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"vue": "^3.5.13",
|
|
||||||
"vue-router": "^4.5.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@vitejs/plugin-vue": "^5.2.3",
|
|
||||||
"vite": "^6.2.4",
|
|
||||||
"vite-plugin-vue-devtools": "^7.7.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -1,216 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="mini-window"
|
|
||||||
@dblclick="handleDoubleClick"
|
|
||||||
@mousedown="handleMouseDown"
|
|
||||||
@mouseenter="handleMouseEnter"
|
|
||||||
@mouseleave="handleMouseLeave">
|
|
||||||
<!-- 折叠状态 -->
|
|
||||||
<div class="mini-content">
|
|
||||||
<span class="mini-bg">
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue'
|
|
||||||
|
|
||||||
let ipcRenderService=null
|
|
||||||
|
|
||||||
try {
|
|
||||||
ipcRenderService= window.electron.ipcRenderer
|
|
||||||
}catch (e){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const isExpanded = ref(false)
|
|
||||||
let isDragging = false
|
|
||||||
let initialMouseX = 0
|
|
||||||
let initialMouseY = 0
|
|
||||||
let mouseDownTime = 0
|
|
||||||
let windowInitialX = 0
|
|
||||||
let windowInitialY = 0
|
|
||||||
const isFlashing = ref(false)
|
|
||||||
|
|
||||||
const handleDoubleClick=(e)=>{
|
|
||||||
console.log("双击事件")
|
|
||||||
ipcRenderService.invoke('app:window:switch-show-main-window').then(() => {
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 处理鼠标按下事件
|
|
||||||
const handleMouseDown = (e) => {
|
|
||||||
// if (isExpanded.value) return // 展开状态不允许拖动
|
|
||||||
|
|
||||||
// isDragging = false
|
|
||||||
initialMouseX = e.screenX // 使用screenX/screenY获取相对于屏幕的坐标
|
|
||||||
initialMouseY = e.screenY
|
|
||||||
mouseDownTime = Date.now()
|
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', handleMouseMove)
|
|
||||||
document.addEventListener('mouseup', handleMouseUp)
|
|
||||||
|
|
||||||
// 获取窗口初始位置
|
|
||||||
ipcRenderService.invoke('app:window:get-position').then((postion) => {
|
|
||||||
|
|
||||||
console.log("app:window:get-position")
|
|
||||||
console.log(postion.x)
|
|
||||||
console.log(postion.y)
|
|
||||||
|
|
||||||
windowInitialX = postion.x
|
|
||||||
windowInitialY = postion.y
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理鼠标移动事件
|
|
||||||
const handleMouseMove = (e) => {
|
|
||||||
const deltaX = e.screenX - initialMouseX
|
|
||||||
const deltaY = e.screenY - initialMouseY
|
|
||||||
|
|
||||||
// 判断是否达到拖动阈值
|
|
||||||
if (!isDragging && (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5)) {
|
|
||||||
isDragging = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDragging) {
|
|
||||||
// 计算新位置
|
|
||||||
const newX = windowInitialX + deltaX
|
|
||||||
const newY = windowInitialY + deltaY
|
|
||||||
console.log("发送位置:",newX)
|
|
||||||
console.log("发送位置:",newY)
|
|
||||||
|
|
||||||
// 发送新位置到主进程
|
|
||||||
window.electron.ipcRenderer.send('ping', newX, newY)
|
|
||||||
window.electron.ipcRenderer.send('app:window:set-position', newX, newY )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleMouseUp = () => {
|
|
||||||
document.removeEventListener('mousemove', handleMouseMove)
|
|
||||||
document.removeEventListener('mouseup', handleMouseUp)
|
|
||||||
|
|
||||||
// 如果不是拖拽且点击时间小于200ms,则触发展开/收起
|
|
||||||
// if (!isDragging && (Date.now() - mouseDownTime < 200)) {
|
|
||||||
// toggleExpand()
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleMouseEnter = () => {
|
|
||||||
// 每次进入都触发闪烁
|
|
||||||
// isFlashing.value = true
|
|
||||||
//
|
|
||||||
// // 300ms 后移除闪烁效果
|
|
||||||
// setTimeout(() => {
|
|
||||||
// isFlashing.value = false
|
|
||||||
// }, 300)
|
|
||||||
|
|
||||||
ipcRenderService.send('app:window:mouse-enter')
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleMouseLeave = () => {
|
|
||||||
// 确保离开时重置闪烁状态
|
|
||||||
isFlashing.value = false
|
|
||||||
ipcRenderService.send('app:window:mouse-leave')
|
|
||||||
}
|
|
||||||
|
|
||||||
const toggleExpand = () => {
|
|
||||||
isExpanded.value = !isExpanded.value
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleAction = (action) => {
|
|
||||||
switch (action) {
|
|
||||||
case 'restore':
|
|
||||||
ipcRenderService.send('app:window:restore-main')
|
|
||||||
break
|
|
||||||
case 'dashboard':
|
|
||||||
ipcRenderService.send('app:window:restore-main', { route: 'INDEX' })
|
|
||||||
break
|
|
||||||
case 'settings':
|
|
||||||
ipcRenderService.send('app:window:restore-main', { route: 'SETTINGS' })
|
|
||||||
break
|
|
||||||
}
|
|
||||||
isExpanded.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听主进程发来的事件
|
|
||||||
onMounted(() => {
|
|
||||||
ipcRenderService.on('app:window:mouse-enter', () => {
|
|
||||||
// 可以在这里处理鼠标进入事件
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcRenderService.on('app:window:mouse-leave', () => {
|
|
||||||
// 可以在这里处理鼠标离开事件
|
|
||||||
})
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.mini-window {
|
|
||||||
width: 120px;
|
|
||||||
height: 120px;
|
|
||||||
border-radius: 25px;
|
|
||||||
background: rgba(0,0,0,0);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
overflow: hidden;
|
|
||||||
user-select: none;
|
|
||||||
background-image: url("./assets/lxi_120.png");
|
|
||||||
background-size: contain;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.mini-window.expanded .mini-content {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mini-window .mini-content {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 1px;
|
|
||||||
right: 5px;
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mini-window .mini-content .mini-bg {
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
width: 120px;
|
|
||||||
height: 120px;
|
|
||||||
border-radius: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.mini-window .expanded-content .actions .action-item .el-icon {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mini-window .expanded-content .actions .action-item span {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@keyframes flash {
|
|
||||||
0% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="main-app">
|
|
||||||
<router-view></router-view>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
// 这里可以添加全局的逻辑
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
*{
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.main-app {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
/* color palette from <https://github.com/vuejs/theme> */
|
|
||||||
:root {
|
|
||||||
--vt-c-white: #ffffff;
|
|
||||||
--vt-c-white-soft: #f8f8f8;
|
|
||||||
--vt-c-white-mute: #f2f2f2;
|
|
||||||
|
|
||||||
--vt-c-black: #181818;
|
|
||||||
--vt-c-black-soft: #222222;
|
|
||||||
--vt-c-black-mute: #282828;
|
|
||||||
|
|
||||||
--vt-c-indigo: #2c3e50;
|
|
||||||
|
|
||||||
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
|
|
||||||
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
|
|
||||||
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
|
|
||||||
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
|
|
||||||
|
|
||||||
--vt-c-text-light-1: var(--vt-c-indigo);
|
|
||||||
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
|
|
||||||
--vt-c-text-dark-1: var(--vt-c-white);
|
|
||||||
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* semantic color variables for this project */
|
|
||||||
:root {
|
|
||||||
--color-background: var(--vt-c-white);
|
|
||||||
--color-background-soft: var(--vt-c-white-soft);
|
|
||||||
--color-background-mute: var(--vt-c-white-mute);
|
|
||||||
|
|
||||||
--color-border: var(--vt-c-divider-light-2);
|
|
||||||
--color-border-hover: var(--vt-c-divider-light-1);
|
|
||||||
|
|
||||||
--color-heading: var(--vt-c-text-light-1);
|
|
||||||
--color-text: var(--vt-c-text-light-1);
|
|
||||||
|
|
||||||
--section-gap: 160px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
--color-background: var(--vt-c-black);
|
|
||||||
--color-background-soft: var(--vt-c-black-soft);
|
|
||||||
--color-background-mute: var(--vt-c-black-mute);
|
|
||||||
|
|
||||||
--color-border: var(--vt-c-divider-dark-2);
|
|
||||||
--color-border-hover: var(--vt-c-divider-dark-1);
|
|
||||||
|
|
||||||
--color-heading: var(--vt-c-text-dark-1);
|
|
||||||
--color-text: var(--vt-c-text-dark-2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
|
||||||
*::before,
|
|
||||||
*::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
min-height: 100vh;
|
|
||||||
color: var(--color-text);
|
|
||||||
background: var(--color-background);
|
|
||||||
transition:
|
|
||||||
color 0.5s,
|
|
||||||
background-color 0.5s;
|
|
||||||
line-height: 1.6;
|
|
||||||
font-family:
|
|
||||||
Inter,
|
|
||||||
-apple-system,
|
|
||||||
BlinkMacSystemFont,
|
|
||||||
'Segoe UI',
|
|
||||||
Roboto,
|
|
||||||
Oxygen,
|
|
||||||
Ubuntu,
|
|
||||||
Cantarell,
|
|
||||||
'Fira Sans',
|
|
||||||
'Droid Sans',
|
|
||||||
'Helvetica Neue',
|
|
||||||
sans-serif;
|
|
||||||
font-size: 15px;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<svg viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle cx="64" cy="64" r="64" fill="#2F3242"/>
|
|
||||||
<ellipse cx="63.9835" cy="23.2036" rx="4.48794" ry="4.495" stroke="#A2ECFB" stroke-width="3.6" stroke-linecap="round"/>
|
|
||||||
<path d="M51.3954 39.5028C52.3733 39.6812 53.3108 39.033 53.4892 38.055C53.6676 37.0771 53.0194 36.1396 52.0414 35.9612L51.3954 39.5028ZM28.6153 43.5751L30.1748 44.4741L30.1748 44.4741L28.6153 43.5751ZM28.9393 60.9358C29.4332 61.7985 30.5329 62.0976 31.3957 61.6037C32.2585 61.1098 32.5575 60.0101 32.0636 59.1473L28.9393 60.9358ZM37.6935 66.7457C37.025 66.01 35.8866 65.9554 35.1508 66.6239C34.415 67.2924 34.3605 68.4308 35.029 69.1666L37.6935 66.7457ZM53.7489 81.7014L52.8478 83.2597L53.7489 81.7014ZM96.9206 89.515C97.7416 88.9544 97.9526 87.8344 97.3919 87.0135C96.8313 86.1925 95.7113 85.9815 94.8904 86.5422L96.9206 89.515ZM52.0414 35.9612C46.4712 34.9451 41.2848 34.8966 36.9738 35.9376C32.6548 36.9806 29.0841 39.1576 27.0559 42.6762L30.1748 44.4741C31.5693 42.0549 34.1448 40.3243 37.8188 39.4371C41.5009 38.5479 46.1547 38.5468 51.3954 39.5028L52.0414 35.9612ZM27.0559 42.6762C24.043 47.9029 25.2781 54.5399 28.9393 60.9358L32.0636 59.1473C28.6579 53.1977 28.1088 48.0581 30.1748 44.4741L27.0559 42.6762ZM35.029 69.1666C39.6385 74.24 45.7158 79.1355 52.8478 83.2597L54.6499 80.1432C47.8081 76.1868 42.0298 71.5185 37.6935 66.7457L35.029 69.1666ZM52.8478 83.2597C61.344 88.1726 70.0465 91.2445 77.7351 92.3608C85.359 93.4677 92.2744 92.6881 96.9206 89.515L94.8904 86.5422C91.3255 88.9767 85.4902 89.849 78.2524 88.7982C71.0793 87.7567 62.809 84.8612 54.6499 80.1432L52.8478 83.2597ZM105.359 84.9077C105.359 81.4337 102.546 78.6127 99.071 78.6127V82.2127C100.553 82.2127 101.759 83.4166 101.759 84.9077H105.359ZM99.071 78.6127C95.5956 78.6127 92.7831 81.4337 92.7831 84.9077H96.3831C96.3831 83.4166 97.5892 82.2127 99.071 82.2127V78.6127ZM92.7831 84.9077C92.7831 88.3817 95.5956 91.2027 99.071 91.2027V87.6027C97.5892 87.6027 96.3831 86.3988 96.3831 84.9077H92.7831ZM99.071 91.2027C102.546 91.2027 105.359 88.3817 105.359 84.9077H101.759C101.759 86.3988 100.553 87.6027 99.071 87.6027V91.2027Z" fill="#A2ECFB"/>
|
|
||||||
<path d="M91.4873 65.382C90.8456 66.1412 90.9409 67.2769 91.7002 67.9186C92.4594 68.5603 93.5951 68.465 94.2368 67.7058L91.4873 65.382ZM99.3169 43.6354L97.7574 44.5344L99.3169 43.6354ZM84.507 35.2412C83.513 35.2282 82.6967 36.0236 82.6838 37.0176C82.6708 38.0116 83.4661 38.8279 84.4602 38.8409L84.507 35.2412ZM74.9407 39.8801C75.9127 39.6716 76.5315 38.7145 76.323 37.7425C76.1144 36.7706 75.1573 36.1517 74.1854 36.3603L74.9407 39.8801ZM53.7836 46.3728L54.6847 47.931L53.7836 46.3728ZM25.5491 80.9047C25.6932 81.8883 26.6074 82.5688 27.5911 82.4247C28.5747 82.2806 29.2552 81.3664 29.1111 80.3828L25.5491 80.9047ZM94.2368 67.7058C97.8838 63.3907 100.505 58.927 101.752 54.678C103.001 50.4213 102.9 46.2472 100.876 42.7365L97.7574 44.5344C99.1494 46.9491 99.3603 50.0419 98.2974 53.6644C97.2323 57.2945 94.9184 61.3223 91.4873 65.382L94.2368 67.7058ZM100.876 42.7365C97.9119 37.5938 91.7082 35.335 84.507 35.2412L84.4602 38.8409C91.1328 38.9278 95.7262 41.0106 97.7574 44.5344L100.876 42.7365ZM74.1854 36.3603C67.4362 37.8086 60.0878 40.648 52.8826 44.8146L54.6847 47.931C61.5972 43.9338 68.5948 41.2419 74.9407 39.8801L74.1854 36.3603ZM52.8826 44.8146C44.1366 49.872 36.9669 56.0954 32.1491 62.3927C27.3774 68.63 24.7148 75.2115 25.5491 80.9047L29.1111 80.3828C28.4839 76.1026 30.4747 70.5062 35.0084 64.5802C39.496 58.7143 46.2839 52.7889 54.6847 47.931L52.8826 44.8146Z" fill="#A2ECFB"/>
|
|
||||||
<path d="M49.0825 87.2295C48.7478 86.2934 47.7176 85.8059 46.7816 86.1406C45.8455 86.4753 45.358 87.5055 45.6927 88.4416L49.0825 87.2295ZM78.5635 96.4256C79.075 95.5732 78.7988 94.4675 77.9464 93.9559C77.0941 93.4443 75.9884 93.7205 75.4768 94.5729L78.5635 96.4256ZM79.5703 85.1795C79.2738 86.1284 79.8027 87.1379 80.7516 87.4344C81.7004 87.7308 82.71 87.2019 83.0064 86.2531L79.5703 85.1795ZM84.3832 64.0673H82.5832H84.3832ZM69.156 22.5301C68.2477 22.1261 67.1838 22.535 66.7799 23.4433C66.3759 24.3517 66.7848 25.4155 67.6931 25.8194L69.156 22.5301ZM45.6927 88.4416C47.5994 93.7741 50.1496 98.2905 53.2032 101.505C56.2623 104.724 59.9279 106.731 63.9835 106.731V103.131C61.1984 103.131 58.4165 101.765 55.8131 99.0249C53.2042 96.279 50.8768 92.2477 49.0825 87.2295L45.6927 88.4416ZM63.9835 106.731C69.8694 106.731 74.8921 102.542 78.5635 96.4256L75.4768 94.5729C72.0781 100.235 68.0122 103.131 63.9835 103.131V106.731ZM83.0064 86.2531C85.0269 79.7864 86.1832 72.1831 86.1832 64.0673H82.5832C82.5832 71.8536 81.4723 79.0919 79.5703 85.1795L83.0064 86.2531ZM86.1832 64.0673C86.1832 54.1144 84.4439 44.922 81.4961 37.6502C78.5748 30.4436 74.3436 24.8371 69.156 22.5301L67.6931 25.8194C71.6364 27.5731 75.3846 32.1564 78.1598 39.0026C80.9086 45.7836 82.5832 54.507 82.5832 64.0673H86.1832Z" fill="#A2ECFB"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M103.559 84.9077C103.559 82.4252 101.55 80.4127 99.071 80.4127C96.5924 80.4127 94.5831 82.4252 94.5831 84.9077C94.5831 87.3902 96.5924 89.4027 99.071 89.4027C101.55 89.4027 103.559 87.3902 103.559 84.9077V84.9077Z" stroke="#A2ECFB" stroke-width="3.6" stroke-linecap="round"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.8143 89.4027C31.2929 89.4027 33.3023 87.3902 33.3023 84.9077C33.3023 82.4252 31.2929 80.4127 28.8143 80.4127C26.3357 80.4127 24.3264 82.4252 24.3264 84.9077C24.3264 87.3902 26.3357 89.4027 28.8143 89.4027V89.4027V89.4027Z" stroke="#A2ECFB" stroke-width="3.6" stroke-linecap="round"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M64.8501 68.0857C62.6341 68.5652 60.451 67.1547 59.9713 64.9353C59.4934 62.7159 60.9007 60.5293 63.1167 60.0489C65.3326 59.5693 67.5157 60.9798 67.9954 63.1992C68.4742 65.4186 67.066 67.6052 64.8501 68.0857Z" fill="#A2ECFB"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 66 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 276 B |
|
Before Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 18 KiB |
@@ -1,35 +0,0 @@
|
|||||||
@import './base.css';
|
|
||||||
|
|
||||||
#app {
|
|
||||||
max-width: 1280px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
a,
|
|
||||||
.green {
|
|
||||||
text-decoration: none;
|
|
||||||
color: hsla(160, 100%, 37%, 1);
|
|
||||||
transition: 0.4s;
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (hover: hover) {
|
|
||||||
a:hover {
|
|
||||||
background-color: hsla(160, 100%, 37%, 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
body {
|
|
||||||
display: flex;
|
|
||||||
place-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
padding: 0 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1422 800" opacity="0.3">
|
|
||||||
<defs>
|
|
||||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="oooscillate-grad">
|
|
||||||
<stop stop-color="hsl(206, 75%, 49%)" stop-opacity="1" offset="0%"></stop>
|
|
||||||
<stop stop-color="hsl(331, 90%, 56%)" stop-opacity="1" offset="100%"></stop>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<g stroke-width="1" stroke="url(#oooscillate-grad)" fill="none" stroke-linecap="round">
|
|
||||||
<path d="M 0 448 Q 355.5 -100 711 400 Q 1066.5 900 1422 448" opacity="0.05"></path>
|
|
||||||
<path d="M 0 420 Q 355.5 -100 711 400 Q 1066.5 900 1422 420" opacity="0.11"></path>
|
|
||||||
<path d="M 0 392 Q 355.5 -100 711 400 Q 1066.5 900 1422 392" opacity="0.18"></path>
|
|
||||||
<path d="M 0 364 Q 355.5 -100 711 400 Q 1066.5 900 1422 364" opacity="0.24"></path>
|
|
||||||
<path d="M 0 336 Q 355.5 -100 711 400 Q 1066.5 900 1422 336" opacity="0.30"></path>
|
|
||||||
<path d="M 0 308 Q 355.5 -100 711 400 Q 1066.5 900 1422 308" opacity="0.37"></path>
|
|
||||||
<path d="M 0 280 Q 355.5 -100 711 400 Q 1066.5 900 1422 280" opacity="0.43"></path>
|
|
||||||
<path d="M 0 252 Q 355.5 -100 711 400 Q 1066.5 900 1422 252" opacity="0.49"></path>
|
|
||||||
<path d="M 0 224 Q 355.5 -100 711 400 Q 1066.5 900 1422 224" opacity="0.56"></path>
|
|
||||||
<path d="M 0 196 Q 355.5 -100 711 400 Q 1066.5 900 1422 196" opacity="0.62"></path>
|
|
||||||
<path d="M 0 168 Q 355.5 -100 711 400 Q 1066.5 900 1422 168" opacity="0.68"></path>
|
|
||||||
<path d="M 0 140 Q 355.5 -100 711 400 Q 1066.5 900 1422 140" opacity="0.75"></path>
|
|
||||||
<path d="M 0 112 Q 355.5 -100 711 400 Q 1066.5 900 1422 112" opacity="0.81"></path>
|
|
||||||
<path d="M 0 84 Q 355.5 -100 711 400 Q 1066.5 900 1422 84" opacity="0.87"></path>
|
|
||||||
<path d="M 0 56 Q 355.5 -100 711 400 Q 1066.5 900 1422 56" opacity="0.94"></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,103 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="api-config">
|
|
||||||
<h2>系统配置</h2>
|
|
||||||
<div class="form-item">
|
|
||||||
<label>客户端地址:</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
v-model="h5ClientUrl"
|
|
||||||
placeholder="请输入客户端访问地址"
|
|
||||||
>
|
|
||||||
<div class="hint">例如:http://10.102.8.56:18900</div>
|
|
||||||
</div>
|
|
||||||
<div class="button-group">
|
|
||||||
<button @click="saveConfig">保存</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue'
|
|
||||||
|
|
||||||
const h5ClientUrl = ref('')
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
// 从本地存储获取现有配置
|
|
||||||
h5ClientUrl.value = await window.electron.ipcRenderer.invoke('getStoreValue', 'h5_client_url') || ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const saveConfig = async () => {
|
|
||||||
try {
|
|
||||||
await window.electron.ipcRenderer.invoke('setStoreValue', 'h5_client_url', h5ClientUrl.value)
|
|
||||||
alert('保存成功')
|
|
||||||
// 关闭当前窗口
|
|
||||||
window.electron.ipcRenderer.send('closeConfigWindow')
|
|
||||||
} catch (error) {
|
|
||||||
alert('保存失败:' + error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.api-config {
|
|
||||||
padding: 20px;
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
color: #333;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-item {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
width: 400px;
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: #4CAF50;
|
|
||||||
box-shadow: 0 0 5px rgba(76, 175, 80, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hint {
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
margin-top: 30px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
padding: 8px 20px;
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
background-color: #45a049;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
defineProps({
|
|
||||||
msg: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="greetings">
|
|
||||||
<h1 class="green">{{ msg }}</h1>
|
|
||||||
<h3>
|
|
||||||
You’ve successfully created a project with
|
|
||||||
<a href="https://vite.dev/" target="_blank" rel="noopener">Vite</a> +
|
|
||||||
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
h1 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2.6rem;
|
|
||||||
position: relative;
|
|
||||||
top: -10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.greetings h1,
|
|
||||||
.greetings h3 {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.greetings h1,
|
|
||||||
.greetings h3 {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import WelcomeItem from './WelcomeItem.vue'
|
|
||||||
import DocumentationIcon from './icons/IconDocumentation.vue'
|
|
||||||
import ToolingIcon from './icons/IconTooling.vue'
|
|
||||||
import EcosystemIcon from './icons/IconEcosystem.vue'
|
|
||||||
import CommunityIcon from './icons/IconCommunity.vue'
|
|
||||||
import SupportIcon from './icons/IconSupport.vue'
|
|
||||||
|
|
||||||
const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<DocumentationIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Documentation</template>
|
|
||||||
|
|
||||||
Vue’s
|
|
||||||
<a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a>
|
|
||||||
provides you with all information you need to get started.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<ToolingIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Tooling</template>
|
|
||||||
|
|
||||||
This project is served and bundled with
|
|
||||||
<a href="https://vite.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The
|
|
||||||
recommended IDE setup is
|
|
||||||
<a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a>
|
|
||||||
+
|
|
||||||
<a href="https://github.com/vuejs/language-tools" target="_blank" rel="noopener">Vue - Official</a>. If
|
|
||||||
you need to test your components and web pages, check out
|
|
||||||
<a href="https://vitest.dev/" target="_blank" rel="noopener">Vitest</a>
|
|
||||||
and
|
|
||||||
<a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a>
|
|
||||||
/
|
|
||||||
<a href="https://playwright.dev/" target="_blank" rel="noopener">Playwright</a>.
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
More instructions are available in
|
|
||||||
<a href="javascript:void(0)" @click="openReadmeInEditor"><code>README.md</code></a
|
|
||||||
>.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<EcosystemIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Ecosystem</template>
|
|
||||||
|
|
||||||
Get official tools and libraries for your project:
|
|
||||||
<a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
|
|
||||||
<a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>,
|
|
||||||
<a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and
|
|
||||||
<a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If
|
|
||||||
you need more resources, we suggest paying
|
|
||||||
<a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a>
|
|
||||||
a visit.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<CommunityIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Community</template>
|
|
||||||
|
|
||||||
Got stuck? Ask your question on
|
|
||||||
<a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>
|
|
||||||
(our official Discord server), or
|
|
||||||
<a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener"
|
|
||||||
>StackOverflow</a
|
|
||||||
>. You should also follow the official
|
|
||||||
<a href="https://bsky.app/profile/vuejs.org" target="_blank" rel="noopener">@vuejs.org</a>
|
|
||||||
Bluesky account or the
|
|
||||||
<a href="https://x.com/vuejs" target="_blank" rel="noopener">@vuejs</a>
|
|
||||||
X account for latest news in the Vue world.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<SupportIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Support Vue</template>
|
|
||||||
|
|
||||||
As an independent project, Vue relies on community backing for its sustainability. You can help
|
|
||||||
us by
|
|
||||||
<a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>.
|
|
||||||
</WelcomeItem>
|
|
||||||
</template>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import { reactive } from 'vue'
|
|
||||||
|
|
||||||
const versions = reactive({ ...window.electron.process.versions })
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<ul class="versions">
|
|
||||||
<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>
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="item">
|
|
||||||
<i>
|
|
||||||
<slot name="icon"></slot>
|
|
||||||
</i>
|
|
||||||
<div class="details">
|
|
||||||
<h3>
|
|
||||||
<slot name="heading"></slot>
|
|
||||||
</h3>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.item {
|
|
||||||
margin-top: 2rem;
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.details {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
display: flex;
|
|
||||||
place-items: center;
|
|
||||||
place-content: center;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-bottom: 0.4rem;
|
|
||||||
color: var(--color-heading);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.item {
|
|
||||||
margin-top: 0;
|
|
||||||
padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
top: calc(50% - 25px);
|
|
||||||
left: -26px;
|
|
||||||
position: absolute;
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
background: var(--color-background);
|
|
||||||
border-radius: 8px;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:before {
|
|
||||||
content: ' ';
|
|
||||||
border-left: 1px solid var(--color-border);
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: calc(50% + 25px);
|
|
||||||
height: calc(50% - 25px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:after {
|
|
||||||
content: ' ';
|
|
||||||
border-left: 1px solid var(--color-border);
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: calc(50% + 25px);
|
|
||||||
height: calc(50% - 25px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:first-of-type:before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:last-of-type:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
|
|
||||||
<template>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
aria-hidden="true"
|
|
||||||
role="img"
|
|
||||||
class="iconify iconify--mdi"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
preserveAspectRatio="xMidYMid meet"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
|
|
||||||
fill="currentColor"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import { createApp } from 'vue'
|
|
||||||
import router from './router'
|
|
||||||
import MainApp from './MainApp.vue'
|
|
||||||
|
|
||||||
const app = createApp(MainApp)
|
|
||||||
app.use(router)
|
|
||||||
app.mount('#app')
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
|
||||||
import App from '../App.vue'
|
|
||||||
import ApiConfig from '../components/ApiConfig.vue'
|
|
||||||
|
|
||||||
const routes = [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: 'home',
|
|
||||||
component: App
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/config',
|
|
||||||
name: 'config',
|
|
||||||
component: ApiConfig
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const router = createRouter({
|
|
||||||
history: createWebHashHistory(),
|
|
||||||
routes
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { fileURLToPath, URL } from 'node:url'
|
|
||||||
|
|
||||||
import { defineConfig } from 'vite'
|
|
||||||
import vue from '@vitejs/plugin-vue'
|
|
||||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
|
||||||
|
|
||||||
// https://vite.dev/config/
|
|
||||||
export default defineConfig({
|
|
||||||
base: "/electron_h5",
|
|
||||||
plugins: [
|
|
||||||
vue(),
|
|
||||||
vueDevTools(),
|
|
||||||
],
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
outDir: 'electron_h5', // 指定输出目录为 electron_h5
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { app, shell, BrowserWindow, ipcMain, Menu, session, screen, dialog } from 'electron'
|
import { app, shell, BrowserWindow, ipcMain, Menu, session, screen, dialog } from 'electron'
|
||||||
import { electronApp, optimizer } from '@electron-toolkit/utils'
|
import { electronApp, optimizer } from '@electron-toolkit/utils'
|
||||||
import Store from 'electron-store'
|
import Store from 'electron-store'
|
||||||
import { createWindow, createDrageWindow, unregisterAllShortcuts } from './window.js'
|
import { createWindow, createDrageWindow, unregisterAllShortcuts, getMainWindow } from './window.js'
|
||||||
import { setupIPC } from './ipc.js'
|
import { setupIPC } from './ipc.js'
|
||||||
import { createTray, destroyTray,clearBrowserCache } from './tray.js'
|
import { createTray, destroyTray,clearBrowserCache } from './tray.js'
|
||||||
import XEUtils from 'xe-utils'
|
import XEUtils from 'xe-utils'
|
||||||
@@ -13,6 +13,7 @@ import { clearAllSessionData } from './utils/cacheUtils.js'
|
|||||||
import SingleInstanceManager from './utils/singleInstance.js'
|
import SingleInstanceManager from './utils/singleInstance.js'
|
||||||
import { setStoreValue, getStoreValue ,deleteStore} from './store.js'
|
import { setStoreValue, getStoreValue ,deleteStore} from './store.js'
|
||||||
import AutoLaunch from 'auto-launch'
|
import AutoLaunch from 'auto-launch'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
import WebSocketClient from './utils/WebSocketClient';
|
import WebSocketClient from './utils/WebSocketClient';
|
||||||
|
|
||||||
@@ -273,6 +274,12 @@ if (!isFirstInstance) {
|
|||||||
app.on('window-all-closed', async (event) => {
|
app.on('window-all-closed', async (event) => {
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
// 如果是重启过程,不执行任何清理操作
|
||||||
|
if (app.isRestarting) {
|
||||||
|
logger.info('检测到重启过程,跳过窗口关闭处理')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!app.isQuiting) {
|
if (!app.isQuiting) {
|
||||||
|
|
||||||
// 如果不是主动退出,则隐藏所有窗口
|
// 如果不是主动退出,则隐藏所有窗口
|
||||||
@@ -300,6 +307,12 @@ if (!isFirstInstance) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
app.on('before-quit', async (event) => {
|
app.on('before-quit', async (event) => {
|
||||||
|
// 如果是重启过程,不执行任何清理操作
|
||||||
|
if (app.isRestarting) {
|
||||||
|
logger.info('检测到重启过程,跳过before-quit处理')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 在应用程序即将退出时执行操作,例如保存数据
|
// 在应用程序即将退出时执行操作,例如保存数据
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@@ -317,6 +330,11 @@ if (!isFirstInstance) {
|
|||||||
|
|
||||||
// 在应用退出时注销所有快捷键
|
// 在应用退出时注销所有快捷键
|
||||||
app.on('will-quit', async (event) => {
|
app.on('will-quit', async (event) => {
|
||||||
|
// 如果是重启过程,不执行任何清理操作
|
||||||
|
if (app.isRestarting) {
|
||||||
|
logger.info('检测到重启过程,跳过will-quit处理')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
|||||||
@@ -334,4 +334,50 @@ export function setupIPC() {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 重启软件
|
||||||
|
ipcMain.handle('restartApp', async (event) => {
|
||||||
|
logger.info("=============================重启软件");
|
||||||
|
try {
|
||||||
|
// 标记为正在重启,避免其他退出逻辑干扰
|
||||||
|
app.isRestarting = true;
|
||||||
|
|
||||||
|
// 确保所有窗口都被正确关闭
|
||||||
|
const windows = BrowserWindow.getAllWindows();
|
||||||
|
logger.info(`准备关闭 ${windows.length} 个窗口`);
|
||||||
|
|
||||||
|
windows.forEach(window => {
|
||||||
|
if (!window.isDestroyed()) {
|
||||||
|
try {
|
||||||
|
window.close();
|
||||||
|
logger.info('窗口关闭成功');
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn('关闭窗口时出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 延迟执行重启,确保窗口关闭完成
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
logger.info('执行应用重启');
|
||||||
|
app.relaunch();
|
||||||
|
app.exit(0);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('重启应用失败,尝试强制退出:', error);
|
||||||
|
try {
|
||||||
|
app.quit();
|
||||||
|
} catch (quitError) {
|
||||||
|
logger.error('强制退出也失败:', quitError);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(`重启软件失败: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,62 @@ let tray = null
|
|||||||
|
|
||||||
import {checkForUpdates} from "./utils/updateUtils"
|
import {checkForUpdates} from "./utils/updateUtils"
|
||||||
|
|
||||||
|
// 安全重启应用函数
|
||||||
|
function safeRestartApp() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
try {
|
||||||
|
logger.info('开始安全重启应用')
|
||||||
|
|
||||||
|
// 标记为正在重启,避免其他退出逻辑干扰
|
||||||
|
app.isRestarting = true
|
||||||
|
|
||||||
|
// 确保所有窗口都被正确关闭
|
||||||
|
const windows = BrowserWindow.getAllWindows()
|
||||||
|
logger.info(`准备关闭 ${windows.length} 个窗口`)
|
||||||
|
|
||||||
|
windows.forEach(window => {
|
||||||
|
if (!window.isDestroyed()) {
|
||||||
|
try {
|
||||||
|
window.close()
|
||||||
|
logger.info('窗口关闭成功')
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn('关闭窗口时出错:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 延迟执行重启,确保窗口关闭完成
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
logger.info('执行应用重启')
|
||||||
|
app.relaunch()
|
||||||
|
app.exit(0)
|
||||||
|
resolve(true)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('重启应用失败,尝试强制退出:', error)
|
||||||
|
try {
|
||||||
|
app.quit()
|
||||||
|
} catch (quitError) {
|
||||||
|
logger.error('强制退出也失败:', quitError)
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
}, 1000) // 增加延迟时间到1秒
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('安全重启失败:', error)
|
||||||
|
try {
|
||||||
|
app.quit()
|
||||||
|
} catch (quitError) {
|
||||||
|
logger.error('强制退出失败:', quitError)
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
resolve(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function clearBrowserCache() {
|
export async function clearBrowserCache() {
|
||||||
try {
|
try {
|
||||||
// 使用统一的缓存清理函数
|
// 使用统一的缓存清理函数
|
||||||
@@ -100,31 +156,7 @@ export function createTray() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{ type: 'separator' },
|
|
||||||
{
|
|
||||||
label: '清除缓存',
|
|
||||||
click: async () => {
|
|
||||||
await clearBrowserCache()
|
|
||||||
|
|
||||||
// 删除配置文件
|
|
||||||
try {
|
|
||||||
const userDataPath = app.getPath('userData')
|
|
||||||
const configPath = join(userDataPath, 'config.json')
|
|
||||||
if (fs.existsSync(configPath)) {
|
|
||||||
fs.unlinkSync(configPath)
|
|
||||||
logger.info('配置文件删除成功')
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('删除配置文件失败:', error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重新加载所有窗口
|
|
||||||
const windows = BrowserWindow.getAllWindows()
|
|
||||||
for (const window of windows) {
|
|
||||||
window.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
label: '退出登录',
|
label: '退出登录',
|
||||||
|
|||||||
76
src/main/utils/networkUtils.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import logger from './logger';
|
||||||
|
import { getStoreValue } from '../store.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测网络连接是否正常
|
||||||
|
* @param {string} url - 要检测的URL,如果不提供则使用默认的客户端地址
|
||||||
|
* @param {number} timeout - 超时时间,默认5秒
|
||||||
|
* @returns {Promise<boolean>} - 返回网络连接状态
|
||||||
|
*/
|
||||||
|
export async function checkNetworkConnection(url = null, timeout = 5000) {
|
||||||
|
try {
|
||||||
|
// 如果没有提供URL,则使用存储的客户端地址
|
||||||
|
if (!url) {
|
||||||
|
const h5ClientUrl = getStoreValue("h5_client_url");
|
||||||
|
if (!h5ClientUrl) {
|
||||||
|
logger.warn('网络检测:未找到客户端地址配置');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
url = h5ClientUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`网络检测:开始检测 ${url} 的连接状态`);
|
||||||
|
|
||||||
|
// 发送HEAD请求检测网络连接
|
||||||
|
const response = await axios.head(url, {
|
||||||
|
timeout: timeout,
|
||||||
|
validateStatus: function (status) {
|
||||||
|
// 接受2xx和3xx的状态码
|
||||||
|
return status >= 200 && status < 400;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info(`网络检测:连接成功,状态码 ${response.status}`);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn(`网络检测:连接失败 - ${error.message}`);
|
||||||
|
|
||||||
|
// 如果是超时错误,记录更详细的信息
|
||||||
|
if (error.code === 'ECONNABORTED') {
|
||||||
|
logger.warn(`网络检测:请求超时 (${timeout}ms)`);
|
||||||
|
} else if (error.code === 'ENOTFOUND') {
|
||||||
|
logger.warn('网络检测:无法解析主机名');
|
||||||
|
} else if (error.code === 'ECONNREFUSED') {
|
||||||
|
logger.warn('网络检测:连接被拒绝');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测多个URL的网络连接
|
||||||
|
* @param {Array<string>} urls - 要检测的URL数组
|
||||||
|
* @param {number} timeout - 超时时间,默认5秒
|
||||||
|
* @returns {Promise<Object>} - 返回每个URL的检测结果
|
||||||
|
*/
|
||||||
|
export async function checkMultipleNetworkConnections(urls, timeout = 5000) {
|
||||||
|
const results = {};
|
||||||
|
|
||||||
|
for (const url of urls) {
|
||||||
|
results[url] = await checkNetworkConnection(url, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测默认客户端地址的网络连接
|
||||||
|
* @param {number} timeout - 超时时间,默认5秒
|
||||||
|
* @returns {Promise<boolean>} - 返回网络连接状态
|
||||||
|
*/
|
||||||
|
export async function checkDefaultClientConnection(timeout = 5000) {
|
||||||
|
return await checkNetworkConnection(null, timeout);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import icon from '../../resources/icon.png?asset'
|
|||||||
import { isApiDatasetsDocumentsPath, extractIdFromPath } from './utils/difyUtils.js'
|
import { isApiDatasetsDocumentsPath, extractIdFromPath } from './utils/difyUtils.js'
|
||||||
import XEUtils from 'xe-utils'
|
import XEUtils from 'xe-utils'
|
||||||
import logger from './utils/logger'
|
import logger from './utils/logger'
|
||||||
|
import { checkDefaultClientConnection } from './utils/networkUtils.js'
|
||||||
import { createMenu } from './menu.js'
|
import { createMenu } from './menu.js'
|
||||||
import { setStoreValue, getStoreValue,deleteStore } from './store.js'
|
import { setStoreValue, getStoreValue,deleteStore } from './store.js'
|
||||||
|
|
||||||
@@ -166,16 +167,38 @@ export async function createWindow() {
|
|||||||
// 加载存储的 URL
|
// 加载存储的 URL
|
||||||
mainWindow.loadURL(h5_client_url)
|
mainWindow.loadURL(h5_client_url)
|
||||||
|
|
||||||
|
// 监听页面加载失败事件
|
||||||
|
mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL) => {
|
||||||
|
logger.error(`主窗口页面加载失败: code=${errorCode}, desc=${errorDescription}, url=${validatedURL}`)
|
||||||
|
// 跳转到网络错误页面
|
||||||
|
|
||||||
|
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||||
|
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '/#/network_error')
|
||||||
|
} else {
|
||||||
|
mainWindow.loadFile(join(__dirname, '../renderer/index.html'), { hash: '/network_error' })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
// 接口超过30分钟不活动,则退出登录
|
// 接口超过30分钟不活动,则退出登录
|
||||||
await tokenExpireTimer()
|
await tokenExpireTimer()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setTimeout(()=>{
|
setTimeout(async ()=>{
|
||||||
try {
|
try {
|
||||||
// 注册全局快捷键
|
// 注册全局快捷键
|
||||||
registerShortcuts(mainWindow)
|
registerShortcuts(mainWindow)
|
||||||
|
|
||||||
|
// 先检测网络连接,如果网络正常再调用版本检测升级
|
||||||
|
const isNetworkConnected = await checkDefaultClientConnection(5000);
|
||||||
|
if (isNetworkConnected) {
|
||||||
|
logger.info('网络连接正常,开始检查版本更新');
|
||||||
checkForUpdates({},false)
|
checkForUpdates({},false)
|
||||||
|
} else {
|
||||||
|
logger.warn('网络连接异常,跳过版本检测升级');
|
||||||
|
}
|
||||||
}catch (e) {
|
}catch (e) {
|
||||||
logger.info(e)
|
logger.info(e)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Dify Market Manager</title>
|
<title>百千万AI</title>
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||||
<meta
|
<meta
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ onMounted(async () => {
|
|||||||
const saveConfig = async () => {
|
const saveConfig = async () => {
|
||||||
try {
|
try {
|
||||||
await window.electron.ipcRenderer.invoke('setStoreValue', 'h5_client_url', h5ClientUrl.value)
|
await window.electron.ipcRenderer.invoke('setStoreValue', 'h5_client_url', h5ClientUrl.value)
|
||||||
alert('保存成功')
|
|
||||||
// 关闭当前窗口
|
// 重启应用
|
||||||
window.electron.ipcRenderer.send('closeConfigWindow')
|
await window.electron.ipcRenderer.invoke('restartApp')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('保存失败:' + error.message)
|
alert('保存失败:' + error.message)
|
||||||
}
|
}
|
||||||
|
|||||||
130
src/renderer/src/components/network_error.vue
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div class="network-error">
|
||||||
|
<div class="error-container">
|
||||||
|
<div class="error-icon">
|
||||||
|
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" fill="#f44336"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h1 class="error-title">网络连接错误</h1>
|
||||||
|
<p class="error-message">无法连接到服务器,请检查您的网络连接</p>
|
||||||
|
<div class="error-actions">
|
||||||
|
<button @click="retryConnection" class="retry-btn">重启服务</button>
|
||||||
|
</div>
|
||||||
|
<div class="tray-tip">
|
||||||
|
<p class="tip-text">
|
||||||
|
💡 提示:在系统托盘中找到软件图标,右键单击 <strong>配置 -> 配置客户端地址</strong>,查看客户端地址是否正确以及<strong>是否有网络访问权限</strong>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'NetworkError',
|
||||||
|
methods: {
|
||||||
|
async retryConnection() {
|
||||||
|
try {
|
||||||
|
// 调用重启软件的方法
|
||||||
|
await window.electron.ipcRenderer.invoke('restartApp');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('重启软件失败:', error);
|
||||||
|
// 如果重启失败,回退到页面刷新
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
goToConfig() {
|
||||||
|
// 跳转到配置页面
|
||||||
|
this.$router.push('/config')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.network-error {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-container {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-icon {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-title {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retry-btn, .config-btn {
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retry-btn {
|
||||||
|
background-color: #2196f3;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retry-btn:hover {
|
||||||
|
background-color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-btn {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #333;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-btn:hover {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tray-tip {
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
color: #666;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text strong {
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
import App from '../App.vue'
|
import App from '../App.vue'
|
||||||
import ApiConfig from '../components/ApiConfig.vue'
|
import ApiConfig from '../components/ApiConfig.vue'
|
||||||
|
import NetworkError from '../components/network_error.vue'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@@ -12,6 +13,11 @@ const routes = [
|
|||||||
path: '/config',
|
path: '/config',
|
||||||
name: 'config',
|
name: 'config',
|
||||||
component: ApiConfig
|
component: ApiConfig
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/network_error',
|
||||||
|
name: 'network_error',
|
||||||
|
component: NetworkError
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||