feat(): 添加更新功能
This commit is contained in:
parent
92055dd6a0
commit
1b6e12e402
|
|
@ -0,0 +1 @@
|
|||
dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5eVJXUG1sdWpVNnBJUHpXSjFZWnczeVpPVjNZMEVvOGFkQlB5UFZDSFNEc0FBQkFBQUFBQUFBQUFBQUlBQUFBQVVmWE1BVXlmNXNqRFRmSEhSU3ltY3hqT1h4aE1hRVNEenJ2RUhkZ0JZaFJWc1owb1hpY3UwaEdqeTNQelRYaVd4M3E4WWR2MTloYWJSZFVTQm5scUhaTjRKOXlqeVlPRVpybWZTY2p2cUQzNkpDZGZGRzBtTEgvdFVBajNzdnBPTXVROFZXQXFUTGc9Cg==
|
||||
|
|
@ -0,0 +1 @@
|
|||
dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDY0Q0YxMzNBM0Q5OEU4NEMKUldSTTZKZzlPaFBQWkVXRVdBVHdTdlNvVnZSL2FFQkZtbFpRTzdjNGxHbjJsZ1R5MFRLdkpmYzMK
|
||||
|
|
@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||
|
||||
## 常用命令
|
||||
|
||||
项目使用 **npm** 作为包管理器(存在 package-lock.json)。
|
||||
项目使用 **pnpm** 作为包管理器(存在 package-lock.json)。
|
||||
|
||||
```bash
|
||||
# 启动开发模式(前端 + Tauri)
|
||||
|
|
@ -18,7 +18,7 @@ pnpm run tauri dev
|
|||
pnpm run dev
|
||||
|
||||
# 构建生产版本
|
||||
npm run tauri build
|
||||
pnpm run tauri build
|
||||
|
||||
# 前端类型检查 + 构建
|
||||
pnpm run build
|
||||
|
|
@ -60,7 +60,7 @@ cd src-tauri && cargo clippy
|
|||
|
||||
- `src-tauri/capabilities/default.json` - Tauri 权限配置(HTTP 白名单、插件权限)
|
||||
- `src-tauri/tauri.conf.json` - 应用配置(窗口、图标、bundle)
|
||||
- 用户配置文件路径:`%APPDATA%/tauri-app/config.json`(Windows)
|
||||
- 用户配置文件路径:`%APPDATA%/work-order-monitor/config.json`(Windows)
|
||||
|
||||
## 依赖的 Tauri 插件
|
||||
|
||||
|
|
|
|||
238
README_APP.md
238
README_APP.md
|
|
@ -1,137 +1,127 @@
|
|||
# 系统监测应用程序
|
||||
# 工单系统监测
|
||||
|
||||
这是一个基于 Tauri + Vue 开发的系统监测应用程序,具有以下功能:
|
||||
基于 **Tauri 2.x + Vue 3** 的工单监测桌面应用,用于监测 CRM 系统的待处理工单并发送系统通知。
|
||||
|
||||
## 功能特性
|
||||
## 环境要求
|
||||
|
||||
1. **用户设置界面** - 配置用户名和密码
|
||||
2. **系统托盘集成** - 应用启动后自动最小化到系统托盘
|
||||
3. **自动登录** - 保存用户凭据并支持自动登录
|
||||
4. **定时API调用** - 登录后每1分钟调用一次接口
|
||||
5. **系统通知** - 根据API返回值弹出系统消息
|
||||
6. **模块化架构** - 代码按功能模块组织,便于维护
|
||||
- Node.js >= 18
|
||||
- Rust (stable)
|
||||
- Visual Studio Build Tools(Windows,含 C++ 工具链)
|
||||
|
||||
## 开发
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
pnpm install
|
||||
|
||||
# 启动开发模式(前端 + Tauri)
|
||||
pnpm tauri dev
|
||||
|
||||
# 仅启动前端
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## 构建
|
||||
|
||||
签名密钥已包含在项目中(`.tauri/` 目录),构建脚本会自动加载,直接运行:
|
||||
|
||||
```bash
|
||||
pnpm run tauri-build
|
||||
```
|
||||
|
||||
构建产物位于 `src-tauri/target/release/bundle/nsis/`。
|
||||
|
||||
## 版本号管理
|
||||
|
||||
使用自定义脚本统一更新 `package.json`、`tauri.conf.json`、`Cargo.toml` 三个文件的版本号:
|
||||
|
||||
```bash
|
||||
node scripts/bump-version.mjs # 默认 patch: 0.2.0 → 0.2.1
|
||||
node scripts/bump-version.mjs minor # minor: 0.2.0 → 0.3.0
|
||||
node scripts/bump-version.mjs major # major: 0.2.0 → 1.0.0
|
||||
node scripts/bump-version.mjs 1.2.3 # 指定版本
|
||||
```
|
||||
|
||||
## 发布
|
||||
|
||||
构建完成后,运行发布脚本将安装包和更新元数据上传到远程服务器:
|
||||
|
||||
```bash
|
||||
node scripts/publish.mjs --notes "更新说明"
|
||||
```
|
||||
|
||||
脚本会自动:
|
||||
1. 从构建产物中读取 `.nsis.zip` 和 `.nsis.zip.sig`
|
||||
2. 生成 `update.json`(供应用内自动更新使用)
|
||||
3. 通过 SCP 上传到服务器 `192.168.2.127:/var/www/html/work-order-monitor/`
|
||||
|
||||
更新地址:`http://web.nps.yunvip123.cn/work-order-monitor/update.json`
|
||||
|
||||
## 完整发版流程
|
||||
|
||||
```bash
|
||||
# 1. 更新版本号
|
||||
node scripts/bump-version.mjs minor
|
||||
|
||||
# 2. 构建
|
||||
pnpm run tauri-build
|
||||
|
||||
# 3. 发布到服务器
|
||||
node scripts/publish.mjs --notes "v0.3.0 新功能说明"
|
||||
```
|
||||
|
||||
## 签名密钥
|
||||
|
||||
项目已内置 updater 签名密钥(`.tauri/signing-key` 和 `.tauri/signing-key.pub`),无密码保护,任何人克隆项目后即可直接构建。
|
||||
|
||||
如需重新生成密钥:
|
||||
|
||||
```bash
|
||||
pnpm tauri signer generate -w .tauri/signing-key -p "" --ci -f
|
||||
```
|
||||
|
||||
生成后需将 `.tauri/signing-key.pub` 的内容更新到 `src-tauri/tauri.conf.json` 的 `plugins.updater.pubkey` 字段。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
src-tauri/src/
|
||||
├── lib.rs # 主模块,应用程序入口和命令处理
|
||||
├── config.rs # 配置管理模块
|
||||
├── api.rs # API调用模块
|
||||
├── tray.rs # 系统托盘模块
|
||||
└── scheduler.rs # 定时任务模块
|
||||
src/ # 前端(Vue 3)
|
||||
├── App.vue # 主界面
|
||||
├── stores/monitor.ts # Pinia 状态管理(核心业务逻辑)
|
||||
├── components/
|
||||
│ ├── MonitorControl.vue # 监测面板(工单数据卡片)
|
||||
│ ├── LoginForm.vue # 登录表单
|
||||
│ ├── SettingsPanel.vue # 配置面板
|
||||
│ ├── StatusHeader.vue # 顶部状态栏
|
||||
│ ├── LogViewer.vue # 日志查看器
|
||||
│ ├── CloseDialog.vue # 关闭确认弹窗
|
||||
│ └── UpdateDialog.vue # 更新确认弹窗
|
||||
|
||||
src/
|
||||
└── App.vue # Vue设置界面
|
||||
src-tauri/ # Rust 后端
|
||||
├── src/lib.rs # 应用初始化、插件注册
|
||||
├── src/notification.rs # Windows Toast 通知
|
||||
├── tauri.conf.json # Tauri 配置
|
||||
├── capabilities/default.json # 权限配置
|
||||
|
||||
scripts/
|
||||
├── build.mjs # 构建(自动加载签名密钥)
|
||||
├── bump-version.mjs # 版本号管理
|
||||
└── publish.mjs # 构建发布
|
||||
```
|
||||
|
||||
## 使用说明
|
||||
## 监测的 API
|
||||
|
||||
### 1. 启动应用程序
|
||||
```bash
|
||||
# 开发模式
|
||||
pnpm tauri dev
|
||||
| 接口 | 说明 | 触发通知条件 |
|
||||
| --- | --- | --- |
|
||||
| `SystemUser/Login` | 登录获取 Session | - |
|
||||
| `DemandManage/QueryIndexCount` | 工单统计 | PendingCount / StaycloseCount / ConfirmCount > 0 |
|
||||
| `DemandManage/GetWorkOrderListPage` | 待审核工单列表 | DataCount > 0 |
|
||||
|
||||
# 构建生产版本
|
||||
pnpm tauri build
|
||||
```
|
||||
## Tauri 插件
|
||||
|
||||
### 2. 配置设置
|
||||
- 应用启动后会自动最小化到系统托盘
|
||||
- 右键点击托盘图标选择"显示设置"打开设置界面
|
||||
- 输入用户名和密码,点击"保存设置"
|
||||
|
||||
### 3. 登录和监测
|
||||
- 保存设置后点击"登录"按钮
|
||||
- 登录成功后会自动启动定时任务(每1分钟执行一次)
|
||||
- 系统会根据API返回值显示通知消息
|
||||
|
||||
### 4. 托盘操作
|
||||
- **左键点击托盘图标** - 显示设置界面
|
||||
- **右键点击托盘图标** - 显示菜单(显示设置/退出)
|
||||
- **关闭窗口** - 应用会隐藏到托盘而不是退出
|
||||
|
||||
## 配置说明
|
||||
|
||||
### API接口
|
||||
应用程序已配置为使用以下API接口:
|
||||
|
||||
- **登录接口**: `https://crm.yunvip123.com/api/SystemUser/Login`
|
||||
- **检查接口**: `https://crm.yunvip123.com/api/DemandManage/QueryIndexCount`
|
||||
|
||||
### 认证机制
|
||||
- 登录时获取 `ASP.NET_SessionId` Cookie
|
||||
- 所有后续请求都需要携带此Cookie进行认证
|
||||
|
||||
### API响应格式
|
||||
|
||||
**登录响应 (LoginResponse):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": null,
|
||||
"msg": "执行成功",
|
||||
"data": {
|
||||
"GID": "512860ad-aa4a-4268-a5d9-6c7d2e28680b",
|
||||
"SU_UserName": "A田森林"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**检查响应 (CheckResponse):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": null,
|
||||
"msg": "执行成功",
|
||||
"data": {
|
||||
"PendingCount": 0,
|
||||
"StaycloseCount": 0,
|
||||
"ConfirmCount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 通知逻辑
|
||||
- 当 `PendingCount`、`StaycloseCount`、`ConfirmCount` 三个值都为0时,不发送通知
|
||||
- 当任意一个值大于0时,发送系统通知,显示具体的工单数量
|
||||
|
||||
## 开发说明
|
||||
|
||||
### 添加新功能
|
||||
1. **新的API端点** - 在 `api.rs` 中添加新的方法
|
||||
2. **新的配置项** - 在 `config.rs` 中添加到 `AppConfig` 结构体
|
||||
3. **新的UI组件** - 在 `App.vue` 中添加新的界面元素
|
||||
4. **新的命令** - 在 `lib.rs` 中添加新的 Tauri 命令
|
||||
|
||||
### 错误处理
|
||||
- 所有模块都使用 `anyhow::Result` 进行错误处理
|
||||
- 错误信息会显示在UI的消息卡片中
|
||||
- 日志记录使用 `log` crate,可通过环境变量 `RUST_LOG` 控制级别
|
||||
|
||||
### 数据持久化
|
||||
- 用户配置保存在系统配置目录:`%APPDATA%/tauri-app/config.json` (Windows)
|
||||
- 配置文件使用JSON格式,包含用户名、密码等信息
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **安全性** - 密码以明文形式存储在配置文件中,生产环境建议加密
|
||||
2. **网络请求** - API调用失败时会显示错误通知
|
||||
3. **系统权限** - 需要通知权限来显示系统消息
|
||||
4. **托盘图标** - 使用应用程序默认图标,可根据登录状态切换不同图标
|
||||
|
||||
## TODO 项目
|
||||
|
||||
- [x] 配置实际的API地址和端点
|
||||
- [x] 实现Cookie认证机制
|
||||
- [x] 适配实际API响应格式
|
||||
- [x] 添加更多的配置选项(检查间隔等)
|
||||
- [x] 添加日志系统和日志显示
|
||||
- [x] 实现自动启动功能
|
||||
- [x] 添加网络连接状态检测
|
||||
- [x] 添加测试按钮(手动检查、停止/开始、最小化等)
|
||||
- [ ] 实现密码加密存储
|
||||
- [ ] 支持不同登录状态的托盘图标(图标文件)
|
||||
- [ ] 添加日志文件输出
|
||||
- [ ] 实现会话过期自动重新登录
|
||||
- [ ] 解决Windows编译环境问题(需要Visual Studio Build Tools)
|
||||
- `tauri-plugin-http` — HTTP 请求
|
||||
- `tauri-plugin-notification` — 系统通知
|
||||
- `tauri-plugin-autostart` — 开机自启动
|
||||
- `tauri-plugin-opener` — 打开外部链接
|
||||
- `tauri-plugin-updater` — 应用内自动更新
|
||||
- `tauri-plugin-process` — 进程管理(重启)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
const { NodeSSH } = require("node-ssh");
|
||||
const os = require("node:os");
|
||||
|
||||
const config = {
|
||||
host: "192.168.2.250",
|
||||
username: "admin",
|
||||
privateKeyPath: `${os.homedir()}\\.ssh\\id_rsa_2048`,
|
||||
localDirectory: "dist",
|
||||
remoteDirectory: "/D:/nginx/nginx-1.27.1/erp",
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const ssh = new NodeSSH();
|
||||
|
||||
await ssh.connect({
|
||||
host: config.host,
|
||||
username: config.username,
|
||||
privateKeyPath: config.privateKeyPath,
|
||||
});
|
||||
|
||||
const res = await ssh.putDirectory(
|
||||
config.localDirectory,
|
||||
config.remoteDirectory,
|
||||
{
|
||||
recursive: true,
|
||||
}
|
||||
);
|
||||
if (res) {
|
||||
console.log("传输完成", res);
|
||||
} else {
|
||||
console.error(res);
|
||||
}
|
||||
|
||||
const connection = ssh.getConnection();
|
||||
connection.destroy();
|
||||
// await ssh.dispose();
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "tauri-app",
|
||||
"version": "0.1.3",
|
||||
"name": "work-order-monitor",
|
||||
"version": "0.2.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tauri-app",
|
||||
"version": "0.1.3",
|
||||
"name": "work-order-monitor",
|
||||
"version": "0.2.1",
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"@tauri-apps/api": "^2.10.1",
|
||||
|
|
@ -14,13 +14,15 @@
|
|||
"@tauri-apps/plugin-http": "^2.5.7",
|
||||
"@tauri-apps/plugin-notification": "^2.3.3",
|
||||
"@tauri-apps/plugin-opener": "^2.5.3",
|
||||
"@tauri-apps/plugin-process": "^2.3.1",
|
||||
"@tauri-apps/plugin-updater": "^2.10.0",
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"dayjs": "^1.11.19",
|
||||
"pinia": "^3.0.4",
|
||||
"vue": "^3.5.29"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2",
|
||||
"@tauri-apps/cli": "^2.10.1",
|
||||
"@vitejs/plugin-vue": "^6.0.4",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.3.1",
|
||||
|
|
@ -957,9 +959,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli/-/cli-2.10.0.tgz",
|
||||
"integrity": "sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli/-/cli-2.10.1.tgz",
|
||||
"integrity": "sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"bin": {
|
||||
|
|
@ -973,23 +975,23 @@
|
|||
"url": "https://opencollective.com/tauri"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tauri-apps/cli-darwin-arm64": "2.10.0",
|
||||
"@tauri-apps/cli-darwin-x64": "2.10.0",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": "2.10.0",
|
||||
"@tauri-apps/cli-linux-arm64-gnu": "2.10.0",
|
||||
"@tauri-apps/cli-linux-arm64-musl": "2.10.0",
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": "2.10.0",
|
||||
"@tauri-apps/cli-linux-x64-gnu": "2.10.0",
|
||||
"@tauri-apps/cli-linux-x64-musl": "2.10.0",
|
||||
"@tauri-apps/cli-win32-arm64-msvc": "2.10.0",
|
||||
"@tauri-apps/cli-win32-ia32-msvc": "2.10.0",
|
||||
"@tauri-apps/cli-win32-x64-msvc": "2.10.0"
|
||||
"@tauri-apps/cli-darwin-arm64": "2.10.1",
|
||||
"@tauri-apps/cli-darwin-x64": "2.10.1",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": "2.10.1",
|
||||
"@tauri-apps/cli-linux-arm64-gnu": "2.10.1",
|
||||
"@tauri-apps/cli-linux-arm64-musl": "2.10.1",
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": "2.10.1",
|
||||
"@tauri-apps/cli-linux-x64-gnu": "2.10.1",
|
||||
"@tauri-apps/cli-linux-x64-musl": "2.10.1",
|
||||
"@tauri-apps/cli-win32-arm64-msvc": "2.10.1",
|
||||
"@tauri-apps/cli-win32-ia32-msvc": "2.10.1",
|
||||
"@tauri-apps/cli-win32-x64-msvc": "2.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-arm64": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.10.0.tgz",
|
||||
"integrity": "sha512-avqHD4HRjrMamE/7R/kzJPcAJnZs0IIS+1nkDP5b+TNBn3py7N2aIo9LIpy+VQq0AkN8G5dDpZtOOBkmWt/zjA==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.10.1.tgz",
|
||||
"integrity": "sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1004,9 +1006,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-x64": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.10.0.tgz",
|
||||
"integrity": "sha512-keDmlvJRStzVFjZTd0xYkBONLtgBC9eMTpmXnBXzsHuawV2q9PvDo2x6D5mhuoMVrJ9QWjgaPKBBCFks4dK71Q==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.10.1.tgz",
|
||||
"integrity": "sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -1021,9 +1023,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.10.0.tgz",
|
||||
"integrity": "sha512-e5u0VfLZsMAC9iHaOEANumgl6lfnJx0Dtjkd8IJpysZ8jp0tJ6wrIkto2OzQgzcYyRCKgX72aKE0PFgZputA8g==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.10.1.tgz",
|
||||
"integrity": "sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -1038,9 +1040,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.10.0.tgz",
|
||||
"integrity": "sha512-YrYYk2dfmBs5m+OIMCrb+JH/oo+4FtlpcrTCgiFYc7vcs6m3QDd1TTyWu0u01ewsCtK2kOdluhr/zKku+KP7HA==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.10.1.tgz",
|
||||
"integrity": "sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1055,9 +1057,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.10.0.tgz",
|
||||
"integrity": "sha512-GUoPdVJmrJRIXFfW3Rkt+eGK9ygOdyISACZfC/bCSfOnGt8kNdQIQr5WRH9QUaTVFIwxMlQyV3m+yXYP+xhSVA==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.10.1.tgz",
|
||||
"integrity": "sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1072,9 +1074,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.10.0.tgz",
|
||||
"integrity": "sha512-JO7s3TlSxshwsoKNCDkyvsx5gw2QAs/Y2GbR5UE2d5kkU138ATKoPOtxn8G1fFT1aDW4LH0rYAAfBpGkDyJJnw==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.10.1.tgz",
|
||||
"integrity": "sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
|
@ -1089,9 +1091,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.10.0.tgz",
|
||||
"integrity": "sha512-Uvh4SUUp4A6DVRSMWjelww0GnZI3PlVy7VS+DRF5napKuIehVjGl9XD0uKoCoxwAQBLctvipyEK+pDXpJeoHng==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.10.1.tgz",
|
||||
"integrity": "sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -1106,9 +1108,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-musl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.10.0.tgz",
|
||||
"integrity": "sha512-AP0KRK6bJuTpQ8kMNWvhIpKUkQJfcPFeba7QshOQZjJ8wOS6emwTN4K5g/d3AbCMo0RRdnZWwu67MlmtJyxC1Q==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.10.1.tgz",
|
||||
"integrity": "sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -1123,9 +1125,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.10.0.tgz",
|
||||
"integrity": "sha512-97DXVU3dJystrq7W41IX+82JEorLNY+3+ECYxvXWqkq7DBN6FsA08x/EFGE8N/b0LTOui9X2dvpGGoeZKKV08g==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.10.1.tgz",
|
||||
"integrity": "sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1140,9 +1142,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.10.0.tgz",
|
||||
"integrity": "sha512-EHyQ1iwrWy1CwMalEm9z2a6L5isQ121pe7FcA2xe4VWMJp+GHSDDGvbTv/OPdkt2Lyr7DAZBpZHM6nvlHXEc4A==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.10.1.tgz",
|
||||
"integrity": "sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -1157,9 +1159,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.10.0.tgz",
|
||||
"integrity": "sha512-NTpyQxkpzGmU6ceWBTY2xRIEaS0ZLbVx1HE1zTA3TY/pV3+cPoPPOs+7YScr4IMzXMtOw7tLw5LEXo5oIG3qaQ==",
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.10.1.tgz",
|
||||
"integrity": "sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -1209,6 +1211,24 @@
|
|||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-process": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz",
|
||||
"integrity": "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/plugin-updater": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tauri-apps/plugin-updater/-/plugin-updater-2.10.0.tgz",
|
||||
"integrity": "sha512-ljN8jPlnT0aSn8ecYhuBib84alxfMx6Hc8vJSKMJyzGbTPFZAC44T2I1QNFZssgWKrAlofvJqCC6Rr472JWfkQ==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz",
|
||||
|
|
|
|||
10
package.json
10
package.json
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "tauri-app",
|
||||
"name": "work-order-monitor",
|
||||
"private": true,
|
||||
"version": "0.1.3",
|
||||
"version": "0.2.2",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
"preview": "vite preview",
|
||||
"tauri": "tauri",
|
||||
"tauri-dev": "tauri dev",
|
||||
"tauri-build": "tauri build"
|
||||
"tauri-build": "node scripts/build.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
|
|
@ -18,13 +18,15 @@
|
|||
"@tauri-apps/plugin-http": "^2.5.7",
|
||||
"@tauri-apps/plugin-notification": "^2.3.3",
|
||||
"@tauri-apps/plugin-opener": "^2.5.3",
|
||||
"@tauri-apps/plugin-process": "^2.3.1",
|
||||
"@tauri-apps/plugin-updater": "^2.10.0",
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"dayjs": "^1.11.19",
|
||||
"pinia": "^3.0.4",
|
||||
"vue": "^3.5.29"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2",
|
||||
"@tauri-apps/cli": "^2.10.1",
|
||||
"@vitejs/plugin-vue": "^6.0.4",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.3.1",
|
||||
|
|
|
|||
118
pnpm-lock.yaml
118
pnpm-lock.yaml
|
|
@ -26,6 +26,12 @@ importers:
|
|||
'@tauri-apps/plugin-opener':
|
||||
specifier: ^2.5.3
|
||||
version: 2.5.3
|
||||
'@tauri-apps/plugin-process':
|
||||
specifier: ^2.3.1
|
||||
version: 2.3.1
|
||||
'@tauri-apps/plugin-updater':
|
||||
specifier: ^2.10.0
|
||||
version: 2.10.0
|
||||
ant-design-vue:
|
||||
specifier: ^4.2.6
|
||||
version: 4.2.6(vue@3.5.29(typescript@5.9.3))
|
||||
|
|
@ -40,8 +46,8 @@ importers:
|
|||
version: 3.5.29(typescript@5.9.3)
|
||||
devDependencies:
|
||||
'@tauri-apps/cli':
|
||||
specifier: ^2
|
||||
version: 2.8.4
|
||||
specifier: ^2.10.1
|
||||
version: 2.10.1
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^6.0.4
|
||||
version: 6.0.4(vite@7.3.1)(vue@3.5.29(typescript@5.9.3))
|
||||
|
|
@ -388,79 +394,79 @@ packages:
|
|||
'@tauri-apps/api@2.10.1':
|
||||
resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==}
|
||||
|
||||
'@tauri-apps/cli-darwin-arm64@2.8.4':
|
||||
resolution: {integrity: sha512-BKu8HRkYV01SMTa7r4fLx+wjgtRK8Vep7lmBdHDioP6b8XH3q2KgsAyPWfEZaZIkZ2LY4SqqGARaE9oilNe0oA==}
|
||||
'@tauri-apps/cli-darwin-arm64@2.10.1':
|
||||
resolution: {integrity: sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@tauri-apps/cli-darwin-x64@2.8.4':
|
||||
resolution: {integrity: sha512-imb9PfSd/7G6VAO7v1bQ2A3ZH4NOCbhGJFLchxzepGcXf9NKkfun157JH9mko29K6sqAwuJ88qtzbKCbWJTH9g==}
|
||||
'@tauri-apps/cli-darwin-x64@2.10.1':
|
||||
resolution: {integrity: sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf@2.8.4':
|
||||
resolution: {integrity: sha512-Ml215UnDdl7/fpOrF1CNovym/KjtUbCuPgrcZ4IhqUCnhZdXuphud/JT3E8X97Y03TZ40Sjz8raXYI2ET0exzw==}
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf@2.10.1':
|
||||
resolution: {integrity: sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@tauri-apps/cli-linux-arm64-gnu@2.8.4':
|
||||
resolution: {integrity: sha512-pbcgBpMyI90C83CxE5REZ9ODyIlmmAPkkJXtV398X3SgZEIYy5TACYqlyyv2z5yKgD8F8WH4/2fek7+jH+ZXAw==}
|
||||
'@tauri-apps/cli-linux-arm64-gnu@2.10.1':
|
||||
resolution: {integrity: sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tauri-apps/cli-linux-arm64-musl@2.8.4':
|
||||
resolution: {integrity: sha512-zumFeaU1Ws5Ay872FTyIm7z8kfzEHu8NcIn8M6TxbJs0a7GRV21KBdpW1zNj2qy7HynnpQCqjAYXTUUmm9JAOw==}
|
||||
'@tauri-apps/cli-linux-arm64-musl@2.10.1':
|
||||
resolution: {integrity: sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tauri-apps/cli-linux-riscv64-gnu@2.8.4':
|
||||
resolution: {integrity: sha512-qiqbB3Zz6IyO201f+1ojxLj65WYj8mixL5cOMo63nlg8CIzsP23cPYUrx1YaDPsCLszKZo7tVs14pc7BWf+/aQ==}
|
||||
'@tauri-apps/cli-linux-riscv64-gnu@2.10.1':
|
||||
resolution: {integrity: sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tauri-apps/cli-linux-x64-gnu@2.8.4':
|
||||
resolution: {integrity: sha512-TaqaDd9Oy6k45Hotx3pOf+pkbsxLaApv4rGd9mLuRM1k6YS/aw81YrsMryYPThrxrScEIUcmNIHaHsLiU4GMkw==}
|
||||
'@tauri-apps/cli-linux-x64-gnu@2.10.1':
|
||||
resolution: {integrity: sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tauri-apps/cli-linux-x64-musl@2.8.4':
|
||||
resolution: {integrity: sha512-ot9STAwyezN8w+bBHZ+bqSQIJ0qPZFlz/AyscpGqB/JnJQVDFQcRDmUPFEaAtt2UUHSWzN3GoTJ5ypqLBp2WQA==}
|
||||
'@tauri-apps/cli-linux-x64-musl@2.10.1':
|
||||
resolution: {integrity: sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tauri-apps/cli-win32-arm64-msvc@2.8.4':
|
||||
resolution: {integrity: sha512-+2aJ/g90dhLiOLFSD1PbElXX3SoMdpO7HFPAZB+xot3CWlAZD1tReUFy7xe0L5GAR16ZmrxpIDM9v9gn5xRy/w==}
|
||||
'@tauri-apps/cli-win32-arm64-msvc@2.10.1':
|
||||
resolution: {integrity: sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@tauri-apps/cli-win32-ia32-msvc@2.8.4':
|
||||
resolution: {integrity: sha512-yj7WDxkL1t9Uzr2gufQ1Hl7hrHuFKTNEOyascbc109EoiAqCp0tgZ2IykQqOZmZOHU884UAWI1pVMqBhS/BfhA==}
|
||||
'@tauri-apps/cli-win32-ia32-msvc@2.10.1':
|
||||
resolution: {integrity: sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@tauri-apps/cli-win32-x64-msvc@2.8.4':
|
||||
resolution: {integrity: sha512-XuvGB4ehBdd7QhMZ9qbj/8icGEatDuBNxyYHbLKsTYh90ggUlPa/AtaqcC1Fo69lGkTmq9BOKrs1aWSi7xDonA==}
|
||||
'@tauri-apps/cli-win32-x64-msvc@2.10.1':
|
||||
resolution: {integrity: sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@tauri-apps/cli@2.8.4':
|
||||
resolution: {integrity: sha512-ejUZBzuQRcjFV+v/gdj/DcbyX/6T4unZQjMSBZwLzP/CymEjKcc2+Fc8xTORThebHDUvqoXMdsCZt8r+hyN15g==}
|
||||
'@tauri-apps/cli@2.10.1':
|
||||
resolution: {integrity: sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g==}
|
||||
engines: {node: '>= 10'}
|
||||
hasBin: true
|
||||
|
||||
|
|
@ -476,6 +482,12 @@ packages:
|
|||
'@tauri-apps/plugin-opener@2.5.3':
|
||||
resolution: {integrity: sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ==}
|
||||
|
||||
'@tauri-apps/plugin-process@2.3.1':
|
||||
resolution: {integrity: sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==}
|
||||
|
||||
'@tauri-apps/plugin-updater@2.10.0':
|
||||
resolution: {integrity: sha512-ljN8jPlnT0aSn8ecYhuBib84alxfMx6Hc8vJSKMJyzGbTPFZAC44T2I1QNFZssgWKrAlofvJqCC6Rr472JWfkQ==}
|
||||
|
||||
'@types/estree@1.0.8':
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
|
||||
|
|
@ -970,52 +982,52 @@ snapshots:
|
|||
|
||||
'@tauri-apps/api@2.10.1': {}
|
||||
|
||||
'@tauri-apps/cli-darwin-arm64@2.8.4':
|
||||
'@tauri-apps/cli-darwin-arm64@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-darwin-x64@2.8.4':
|
||||
'@tauri-apps/cli-darwin-x64@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf@2.8.4':
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-linux-arm64-gnu@2.8.4':
|
||||
'@tauri-apps/cli-linux-arm64-gnu@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-linux-arm64-musl@2.8.4':
|
||||
'@tauri-apps/cli-linux-arm64-musl@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-linux-riscv64-gnu@2.8.4':
|
||||
'@tauri-apps/cli-linux-riscv64-gnu@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-linux-x64-gnu@2.8.4':
|
||||
'@tauri-apps/cli-linux-x64-gnu@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-linux-x64-musl@2.8.4':
|
||||
'@tauri-apps/cli-linux-x64-musl@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-win32-arm64-msvc@2.8.4':
|
||||
'@tauri-apps/cli-win32-arm64-msvc@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-win32-ia32-msvc@2.8.4':
|
||||
'@tauri-apps/cli-win32-ia32-msvc@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli-win32-x64-msvc@2.8.4':
|
||||
'@tauri-apps/cli-win32-x64-msvc@2.10.1':
|
||||
optional: true
|
||||
|
||||
'@tauri-apps/cli@2.8.4':
|
||||
'@tauri-apps/cli@2.10.1':
|
||||
optionalDependencies:
|
||||
'@tauri-apps/cli-darwin-arm64': 2.8.4
|
||||
'@tauri-apps/cli-darwin-x64': 2.8.4
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf': 2.8.4
|
||||
'@tauri-apps/cli-linux-arm64-gnu': 2.8.4
|
||||
'@tauri-apps/cli-linux-arm64-musl': 2.8.4
|
||||
'@tauri-apps/cli-linux-riscv64-gnu': 2.8.4
|
||||
'@tauri-apps/cli-linux-x64-gnu': 2.8.4
|
||||
'@tauri-apps/cli-linux-x64-musl': 2.8.4
|
||||
'@tauri-apps/cli-win32-arm64-msvc': 2.8.4
|
||||
'@tauri-apps/cli-win32-ia32-msvc': 2.8.4
|
||||
'@tauri-apps/cli-win32-x64-msvc': 2.8.4
|
||||
'@tauri-apps/cli-darwin-arm64': 2.10.1
|
||||
'@tauri-apps/cli-darwin-x64': 2.10.1
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf': 2.10.1
|
||||
'@tauri-apps/cli-linux-arm64-gnu': 2.10.1
|
||||
'@tauri-apps/cli-linux-arm64-musl': 2.10.1
|
||||
'@tauri-apps/cli-linux-riscv64-gnu': 2.10.1
|
||||
'@tauri-apps/cli-linux-x64-gnu': 2.10.1
|
||||
'@tauri-apps/cli-linux-x64-musl': 2.10.1
|
||||
'@tauri-apps/cli-win32-arm64-msvc': 2.10.1
|
||||
'@tauri-apps/cli-win32-ia32-msvc': 2.10.1
|
||||
'@tauri-apps/cli-win32-x64-msvc': 2.10.1
|
||||
|
||||
'@tauri-apps/plugin-autostart@2.5.1':
|
||||
dependencies:
|
||||
|
|
@ -1033,6 +1045,14 @@ snapshots:
|
|||
dependencies:
|
||||
'@tauri-apps/api': 2.10.1
|
||||
|
||||
'@tauri-apps/plugin-process@2.3.1':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.10.1
|
||||
|
||||
'@tauri-apps/plugin-updater@2.10.0':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.10.1
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@vitejs/plugin-vue@6.0.4(vite@7.3.1)(vue@3.5.29(typescript@5.9.3))':
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* 构建脚本 - 自动加载项目内置签名密钥后执行 tauri build
|
||||
*/
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { execSync } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
const keyPath = resolve(root, ".tauri/signing-key");
|
||||
|
||||
try {
|
||||
process.env.TAURI_SIGNING_PRIVATE_KEY = readFileSync(keyPath, "utf-8").trim();
|
||||
process.env.TAURI_SIGNING_PRIVATE_KEY_PASSWORD = "";
|
||||
} catch {
|
||||
console.error(`错误: 未找到签名密钥 ${keyPath}`);
|
||||
console.error("请运行: pnpm tauri signer generate -w .tauri/signing-key -p \"\" --ci");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
execSync("pnpm tauri build", { stdio: "inherit", cwd: root });
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* @file /scripts/bump-version.mjs
|
||||
* @description 统一更新 Tauri 项目版本号
|
||||
* @author tsl (randy1924@163.com)
|
||||
* @date 2026-03-23 10:23:42
|
||||
* @lastModified 2026-03-23 10:25:08
|
||||
* @lastModifiedBy tsl (randy1924@163.com)
|
||||
* @example node scripts/bump-version.mjs [patch|minor|major|x.y.z]
|
||||
* @default patch
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
|
||||
// 读取当前版本
|
||||
function getCurrentVersion() {
|
||||
const pkg = JSON.parse(readFileSync(resolve(root, "package.json"), "utf-8"));
|
||||
return pkg.version;
|
||||
}
|
||||
|
||||
// 根据 bump 类型计算新版本
|
||||
function bumpVersion(current, type) {
|
||||
const parts = current.replace(/-.*$/, "").split(".").map(Number);
|
||||
switch (type) {
|
||||
case "major":
|
||||
return `${parts[0] + 1}.0.0`;
|
||||
case "minor":
|
||||
return `${parts[0]}.${parts[1] + 1}.0`;
|
||||
case "patch":
|
||||
return `${parts[0]}.${parts[1]}.${parts[2] + 1}`;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const arg = process.argv[2] || "patch";
|
||||
const BUMP_TYPES = ["patch", "minor", "major"];
|
||||
const current = getCurrentVersion();
|
||||
let version;
|
||||
|
||||
if (BUMP_TYPES.includes(arg)) {
|
||||
version = bumpVersion(current, arg);
|
||||
} else if (/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/.test(arg)) {
|
||||
version = arg;
|
||||
} else {
|
||||
console.error(`错误: 无效参数 "${arg}",应为 patch / minor / major 或 x.y.z 格式`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = [
|
||||
{
|
||||
path: "package.json",
|
||||
update(content) {
|
||||
const json = JSON.parse(content);
|
||||
const old = json.version;
|
||||
json.version = version;
|
||||
return { result: JSON.stringify(json, null, 2) + "\n", old };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "src-tauri/tauri.conf.json",
|
||||
update(content) {
|
||||
const json = JSON.parse(content);
|
||||
const old = json.version;
|
||||
json.version = version;
|
||||
return { result: JSON.stringify(json, null, 2) + "\n", old };
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "src-tauri/Cargo.toml",
|
||||
update(content) {
|
||||
let old = "";
|
||||
let replaced = false;
|
||||
const result = content.replace(
|
||||
/^version\s*=\s*"([^"]*)"/m,
|
||||
(match, v) => {
|
||||
if (replaced) return match;
|
||||
replaced = true;
|
||||
old = v;
|
||||
return `version = "${version}"`;
|
||||
}
|
||||
);
|
||||
return { result, old };
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
console.log(`\n${current} → ${version} (${BUMP_TYPES.includes(arg) ? arg : "指定版本"})\n`);
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = resolve(root, file.path);
|
||||
const content = readFileSync(filePath, "utf-8");
|
||||
const { result, old } = file.update(content);
|
||||
writeFileSync(filePath, result, "utf-8");
|
||||
console.log(` ✔ ${file.path} ${old} → ${version}`);
|
||||
}
|
||||
|
||||
console.log("\n全部更新完成!");
|
||||
console.log("提示: package-lock.json 和 Cargo.lock 会在下次 install/build 时自动同步\n");
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* @file /scripts/publish.mjs
|
||||
* @description 构建后生成 update.json 并上传到远程服务器
|
||||
* @usage node scripts/publish.mjs [--notes "更新说明"]
|
||||
*
|
||||
* 前置条件:
|
||||
* 1. 已运行 `pnpm run tauri-build` 生成构建产物
|
||||
* 2. 远程服务器 SSH 可达(192.168.2.127:22)
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, readdirSync, existsSync } from "node:fs";
|
||||
import { resolve, dirname, basename } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = resolve(__dirname, "..");
|
||||
|
||||
// ===== 配置 =====
|
||||
const REMOTE_USER = "root_test";
|
||||
const REMOTE_HOST = "192.168.2.127";
|
||||
const REMOTE_PORT = 22;
|
||||
const REMOTE_DIR = "/var/www/html/work-order-monitor";
|
||||
const BASE_URL = "http://web.nps.yunvip123.cn/work-order-monitor";
|
||||
|
||||
// ===== 解析参数 =====
|
||||
const args = process.argv.slice(2);
|
||||
let notes = "";
|
||||
const notesIdx = args.indexOf("--notes");
|
||||
if (notesIdx !== -1 && args[notesIdx + 1]) {
|
||||
notes = args[notesIdx + 1];
|
||||
}
|
||||
|
||||
// ===== 读取版本号 =====
|
||||
const pkg = JSON.parse(readFileSync(resolve(root, "package.json"), "utf-8"));
|
||||
const version = pkg.version;
|
||||
|
||||
// ===== 查找构建产物 =====
|
||||
const bundleDir = resolve(root, "src-tauri/target/release/bundle/nsis");
|
||||
|
||||
if (!existsSync(bundleDir)) {
|
||||
console.error(`错误: 未找到构建目录 ${bundleDir}`);
|
||||
console.error("请先运行: pnpm run tauri-build");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = readdirSync(bundleDir);
|
||||
const setupFile = files.find((f) => f.includes(version) && f.endsWith("-setup.exe"));
|
||||
const sigFile = files.find((f) => f.includes(version) && f.endsWith("-setup.exe.sig"));
|
||||
|
||||
if (!setupFile || !sigFile) {
|
||||
console.error(`错误: 未找到版本 ${version} 的 -setup.exe 或 -setup.exe.sig 文件`);
|
||||
console.error(`目录内容: ${files.join(", ")}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const setupPath = resolve(bundleDir, setupFile);
|
||||
const sigPath = resolve(bundleDir, sigFile);
|
||||
const signature = readFileSync(sigPath, "utf-8").trim();
|
||||
|
||||
console.log(`\n版本: ${version}`);
|
||||
console.log(`安装包: ${setupFile}`);
|
||||
console.log(`签名文件: ${sigFile}`);
|
||||
console.log(`签名: ${signature.substring(0, 40)}...`);
|
||||
|
||||
// ===== 生成 update.json =====
|
||||
const encodedFileName = encodeURIComponent(setupFile);
|
||||
const updateJson = {
|
||||
version,
|
||||
notes: notes || `v${version} 更新`,
|
||||
pub_date: new Date().toISOString(),
|
||||
platforms: {
|
||||
"windows-x86_64": {
|
||||
url: `${BASE_URL}/${encodedFileName}`,
|
||||
signature,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const updateJsonPath = resolve(bundleDir, "update.json");
|
||||
writeFileSync(updateJsonPath, JSON.stringify(updateJson, null, 2), "utf-8");
|
||||
console.log(`\nupdate.json 已生成`);
|
||||
console.log(JSON.stringify(updateJson, null, 2));
|
||||
|
||||
// ===== 上传到远程服务器 =====
|
||||
console.log(`\n正在上传到 ${REMOTE_HOST}:${REMOTE_DIR} ...`);
|
||||
|
||||
try {
|
||||
// 确保远程目录存在
|
||||
execSync(
|
||||
`ssh -p ${REMOTE_PORT} ${REMOTE_USER}@${REMOTE_HOST} "mkdir -p ${REMOTE_DIR}"`,
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
|
||||
// 上传安装包
|
||||
console.log(` 上传 ${setupFile} ...`);
|
||||
execSync(
|
||||
`scp -P ${REMOTE_PORT} "${setupPath}" ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/`,
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
|
||||
// 上传 update.json
|
||||
console.log(` 上传 update.json ...`);
|
||||
execSync(
|
||||
`scp -P ${REMOTE_PORT} "${updateJsonPath}" ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/`,
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
|
||||
console.log("\n全部上传完成!");
|
||||
console.log(`更新地址: ${BASE_URL}/update.json`);
|
||||
console.log(`下载地址: ${BASE_URL}/${encodedFileName}\n`);
|
||||
} catch (e) {
|
||||
console.error("\n上传失败:", e.message);
|
||||
console.error("请检查 SSH 连接是否正常,或手动上传以下文件:");
|
||||
console.error(` 1. ${setupPath}`);
|
||||
console.error(` 2. ${updateJsonPath}`);
|
||||
console.error(` → 目标: ${REMOTE_HOST}:${REMOTE_DIR}/`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
@ -47,6 +47,15 @@ version = "1.0.102"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-broadcast"
|
||||
version = "0.7.2"
|
||||
|
|
@ -717,6 +726,17 @@ dependencies = [
|
|||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.20"
|
||||
|
|
@ -1018,6 +1038,17 @@ dependencies = [
|
|||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
|
|
@ -2114,6 +2145,7 @@ checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
|
|||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"libc",
|
||||
"redox_syscall 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2225,6 +2257,12 @@ version = "0.3.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "minisign-verify"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
|
|
@ -2286,10 +2324,10 @@ dependencies = [
|
|||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-probe 0.1.6",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework 2.11.1",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
|
@ -2548,6 +2586,18 @@ dependencies = [
|
|||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-osa-kit"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-quartz-core"
|
||||
version = "0.3.2"
|
||||
|
|
@ -2649,6 +2699,12 @@ version = "0.1.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.110"
|
||||
|
|
@ -2677,6 +2733,20 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "osakit"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b"
|
||||
dependencies = [
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
"objc2-osa-kit",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.18.3"
|
||||
|
|
@ -2726,7 +2796,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.5.18",
|
||||
"smallvec",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
|
@ -3305,6 +3375,15 @@ dependencies = [
|
|||
"bitflags 2.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.6"
|
||||
|
|
@ -3436,15 +3515,20 @@ dependencies = [
|
|||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-util",
|
||||
"js-sys",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"rustls-platform-verifier",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-http",
|
||||
|
|
@ -3512,6 +3596,18 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
|
||||
dependencies = [
|
||||
"openssl-probe 0.2.1",
|
||||
"rustls-pki-types",
|
||||
"schannel",
|
||||
"security-framework 3.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.14.0"
|
||||
|
|
@ -3522,6 +3618,33 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
|
||||
dependencies = [
|
||||
"core-foundation 0.10.1",
|
||||
"core-foundation-sys",
|
||||
"jni",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-platform-verifier-android",
|
||||
"rustls-webpki",
|
||||
"security-framework 3.5.1",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-platform-verifier-android"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.9"
|
||||
|
|
@ -3633,6 +3756,19 @@ dependencies = [
|
|||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "3.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"core-foundation 0.10.1",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.15.0"
|
||||
|
|
@ -3923,7 +4059,7 @@ dependencies = [
|
|||
"objc2-foundation",
|
||||
"objc2-quartz-core",
|
||||
"raw-window-handle",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.5.18",
|
||||
"tracing",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
|
|
@ -4137,6 +4273,17 @@ dependencies = [
|
|||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.16"
|
||||
|
|
@ -4195,24 +4342,6 @@ dependencies = [
|
|||
"windows 0.61.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-app"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-autostart",
|
||||
"tauri-plugin-http",
|
||||
"tauri-plugin-notification",
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-store",
|
||||
"windows 0.58.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-build"
|
||||
version = "2.5.5"
|
||||
|
|
@ -4394,6 +4523,16 @@ dependencies = [
|
|||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-process"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a"
|
||||
dependencies = [
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-store"
|
||||
version = "2.4.2"
|
||||
|
|
@ -4410,6 +4549,39 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-updater"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fe8e9bebd88fc222938ffdfbdcfa0307081423bd01e3252fc337d8bde81fc61"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"dirs 6.0.0",
|
||||
"flate2",
|
||||
"futures-util",
|
||||
"http",
|
||||
"infer",
|
||||
"log",
|
||||
"minisign-verify",
|
||||
"osakit",
|
||||
"percent-encoding",
|
||||
"reqwest 0.13.2",
|
||||
"rustls",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tar",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tokio",
|
||||
"url",
|
||||
"windows-sys 0.60.2",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "2.10.0"
|
||||
|
|
@ -5305,6 +5477,15 @@ dependencies = [
|
|||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.6"
|
||||
|
|
@ -5984,6 +6165,26 @@ dependencies = [
|
|||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "work-order-monitor"
|
||||
version = "0.2.2"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-autostart",
|
||||
"tauri-plugin-http",
|
||||
"tauri-plugin-notification",
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-process",
|
||||
"tauri-plugin-store",
|
||||
"tauri-plugin-updater",
|
||||
"windows 0.58.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.2"
|
||||
|
|
@ -6056,6 +6257,16 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.1"
|
||||
|
|
@ -6220,6 +6431,18 @@ dependencies = [
|
|||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "4.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
"indexmap 2.13.0",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "tauri-app"
|
||||
version = "0.1.2"
|
||||
name = "work-order-monitor"
|
||||
version = "0.2.2"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
|
@ -11,7 +11,7 @@ edition = "2021"
|
|||
# The `_lib` suffix may seem redundant but it is necessary
|
||||
# to make the lib name unique and wouldn't conflict with the bin name.
|
||||
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
||||
name = "tauri_app_lib"
|
||||
name = "work_order_monitor_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
|
|
@ -28,6 +28,8 @@ serde = { version = "1", features = ["derive"] }
|
|||
serde_json = "1"
|
||||
log = "0.4"
|
||||
env_logger = "0.10"
|
||||
tauri-plugin-updater = "2.10.0"
|
||||
tauri-plugin-process = "2.3.1"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows = { version = "0.58", features = [
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
"core:window:allow-set-title",
|
||||
"core:window:allow-unminimize",
|
||||
"core:image:default",
|
||||
"core:image:allow-from-path"
|
||||
"core:image:allow-from-path",
|
||||
"updater:default",
|
||||
"process:allow-restart"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ val tauriProperties = Properties().apply {
|
|||
|
||||
android {
|
||||
compileSdk = 36
|
||||
namespace = "com.administrator.tauri_app"
|
||||
namespace = "com.yunpu.workordermonitor"
|
||||
defaultConfig {
|
||||
manifestPlaceholders["usesCleartextTraffic"] = "false"
|
||||
applicationId = "com.administrator.tauri_app"
|
||||
applicationId = "com.yunpu.workordermonitor"
|
||||
minSdk = 24
|
||||
targetSdk = 36
|
||||
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.administrator.tauri_app
|
||||
package com.yunpu.workordermonitor
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<resources>
|
||||
<string name="app_name">tauri-app</string>
|
||||
<string name="main_activity_title">tauri-app</string>
|
||||
<string name="app_name">work-order-monitor</string>
|
||||
<string name="main_activity_title">work-order-monitor</string>
|
||||
</resources>
|
||||
|
|
@ -91,6 +91,8 @@ pub fn run() {
|
|||
MacosLauncher::LaunchAgent,
|
||||
Some(vec![]),
|
||||
))
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.setup(|app| {
|
||||
start_notification_callback_server(app.handle().clone());
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
tauri_app_lib::run()
|
||||
work_order_monitor_lib::run()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "工单系统监测",
|
||||
"version": "0.1.3",
|
||||
"identifier": "com.administrator.tauri-app",
|
||||
"version": "0.2.2",
|
||||
"identifier": "com.yunpu.workordermonitor",
|
||||
"build": {
|
||||
"beforeDevCommand": "pnpm dev",
|
||||
"devUrl": "http://localhost:1420",
|
||||
|
|
@ -23,7 +23,10 @@
|
|||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": ["nsis"],
|
||||
"targets": [
|
||||
"nsis"
|
||||
],
|
||||
"createUpdaterArtifacts": true,
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
|
|
@ -35,5 +38,17 @@
|
|||
"icons/32x32.png",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
},
|
||||
"plugins": {
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDY0Q0YxMzNBM0Q5OEU4NEMKUldSTTZKZzlPaFBQWkVXRVdBVHdTdlNvVnZSL2FFQkZtbFpRTzdjNGxHbjJsZ1R5MFRLdkpmYzMK",
|
||||
"endpoints": [
|
||||
"http://web.nps.yunvip123.cn/work-order-monitor/update.json"
|
||||
],
|
||||
"dangerousInsecureTransportProtocol": true,
|
||||
"windows": {
|
||||
"installMode": "passive"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import SettingsPanel from "./components/SettingsPanel.vue";
|
|||
import LogViewer from "./components/LogViewer.vue";
|
||||
import AppStatusBar, { type StatusBarItem } from "./components/AppStatusBar.vue";
|
||||
import CloseDialog from "./components/CloseDialog.vue";
|
||||
import UpdateDialog from "./components/UpdateDialog.vue";
|
||||
import { useMonitorStore } from "./stores/monitor";
|
||||
|
||||
const activeTab = ref("monitor");
|
||||
|
|
@ -81,6 +82,7 @@ onUnmounted(() => store.cleanup());
|
|||
</a-layout>
|
||||
|
||||
<CloseDialog />
|
||||
<UpdateDialog />
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useMonitorStore } from "../stores/monitor";
|
||||
|
||||
const store = useMonitorStore();
|
||||
|
||||
const progressPercent = computed(() => {
|
||||
if (!store.updateProgress || !store.updateProgress.total) return 0;
|
||||
return Math.round((store.updateProgress.downloaded / store.updateProgress.total) * 100);
|
||||
});
|
||||
|
||||
const downloadedMB = computed(() => {
|
||||
if (!store.updateProgress) return "0";
|
||||
return (store.updateProgress.downloaded / 1024 / 1024).toFixed(1);
|
||||
});
|
||||
|
||||
const totalMB = computed(() => {
|
||||
if (!store.updateProgress || !store.updateProgress.total) return "0";
|
||||
return (store.updateProgress.total / 1024 / 1024).toFixed(1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:open="store.showUpdateDialog"
|
||||
title="发现新版本"
|
||||
:width="400"
|
||||
centered
|
||||
:closable="!store.isUpdating"
|
||||
:maskClosable="!store.isUpdating"
|
||||
>
|
||||
<div class="update-body">
|
||||
<div v-if="!store.isUpdating">
|
||||
<p class="version-info">
|
||||
新版本 <span class="version-tag">v{{ store.updateInfo?.version }}</span> 已发布
|
||||
</p>
|
||||
<div v-if="store.updateInfo?.notes" class="update-notes">
|
||||
<p class="notes-title">更新说明:</p>
|
||||
<p class="notes-content">{{ store.updateInfo.notes }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="update-progress">
|
||||
<p>正在下载更新...</p>
|
||||
<a-progress :percent="progressPercent" :status="progressPercent >= 100 ? 'success' : 'active'" />
|
||||
<p class="progress-detail">{{ downloadedMB }} / {{ totalMB }} MB</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<template v-if="!store.isUpdating">
|
||||
<a-button @click="store.dismissUpdate()">稍后提醒</a-button>
|
||||
<a-button type="primary" @click="store.confirmUpdate()">立即更新</a-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-button disabled>更新中,请稍候...</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.update-body {
|
||||
padding: 4px 0 8px;
|
||||
}
|
||||
.version-info {
|
||||
margin: 0 0 12px;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
}
|
||||
.version-tag {
|
||||
font-weight: 600;
|
||||
color: #1677ff;
|
||||
}
|
||||
.notes-title {
|
||||
margin: 0 0 4px;
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
}
|
||||
.notes-content {
|
||||
margin: 0;
|
||||
padding: 8px 12px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
color: #555;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.update-progress {
|
||||
text-align: center;
|
||||
}
|
||||
.update-progress p {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
.progress-detail {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 4px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -18,6 +18,8 @@ import {
|
|||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
import { check, type Update } from "@tauri-apps/plugin-updater";
|
||||
import { relaunch } from "@tauri-apps/plugin-process";
|
||||
|
||||
export const APP_NAME = "工单系统监测";
|
||||
const API_BASE = "https://crm.yunvip123.com/api";
|
||||
|
|
@ -76,6 +78,10 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
});
|
||||
const showCloseDialog = ref(false);
|
||||
const postponeResumeTime = ref<number | null>(null);
|
||||
const showUpdateDialog = ref(false);
|
||||
const updateInfo = ref<{ version: string; notes: string; date: string } | null>(null);
|
||||
const updateProgress = ref<{ total: number; downloaded: number } | null>(null);
|
||||
const isUpdating = ref(false);
|
||||
|
||||
// ===== 内部状态 =====
|
||||
let sessionId = "";
|
||||
|
|
@ -85,7 +91,9 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
let postponeTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
let unlistenNotification: UnlistenFn | null = null;
|
||||
let unlistenClose: UnlistenFn | null = null;
|
||||
let pendingUpdate: Update | null = null;
|
||||
let trayIconInstance: TrayIcon | null = null;
|
||||
let cachedSvgImg: HTMLImageElement | null = null;
|
||||
|
||||
// ===== 工具函数 =====
|
||||
function formatTime(date: Date): string {
|
||||
|
|
@ -541,6 +549,60 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
}
|
||||
|
||||
// ===== 配置更新 =====
|
||||
|
||||
async function checkForUpdates() {
|
||||
try {
|
||||
addLog("INFO", "正在检查应用更新...", "UPDATER");
|
||||
const update = await check();
|
||||
if (update) {
|
||||
pendingUpdate = update;
|
||||
updateInfo.value = {
|
||||
version: update.version,
|
||||
notes: update.body || "",
|
||||
date: update.date || "",
|
||||
};
|
||||
showUpdateDialog.value = true;
|
||||
addLog("INFO", `发现新版本: ${update.version}`, "UPDATER");
|
||||
} else {
|
||||
addLog("INFO", "当前已是最新版本", "UPDATER");
|
||||
}
|
||||
} catch (e: any) {
|
||||
addLog("WARN", `检查更新失败: ${e.message || e}`, "UPDATER");
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmUpdate() {
|
||||
if (!pendingUpdate) return;
|
||||
isUpdating.value = true;
|
||||
updateProgress.value = { total: 0, downloaded: 0 };
|
||||
try {
|
||||
addLog("INFO", "开始下载更新...", "UPDATER");
|
||||
await pendingUpdate.downloadAndInstall((event) => {
|
||||
if (event.event === "Started" && event.data.contentLength) {
|
||||
updateProgress.value = { total: event.data.contentLength, downloaded: 0 };
|
||||
} else if (event.event === "Progress") {
|
||||
if (updateProgress.value) {
|
||||
updateProgress.value.downloaded += event.data.chunkLength;
|
||||
}
|
||||
} else if (event.event === "Finished") {
|
||||
addLog("INFO", "更新下载完成,即将重启...", "UPDATER");
|
||||
}
|
||||
});
|
||||
await relaunch();
|
||||
} catch (e: any) {
|
||||
addLog("ERROR", `更新安装失败: ${e.message || e}`, "UPDATER");
|
||||
message.value = "更新安装失败";
|
||||
isUpdating.value = false;
|
||||
updateProgress.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
function dismissUpdate() {
|
||||
showUpdateDialog.value = false;
|
||||
pendingUpdate = null;
|
||||
updateInfo.value = null;
|
||||
}
|
||||
|
||||
async function updateConfig() {
|
||||
isLoading.value = true;
|
||||
try {
|
||||
|
|
@ -563,29 +625,59 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
|
||||
// ===== 系统托盘 =====
|
||||
|
||||
/** 用 Canvas 渲染彩色圆形背景 + 白色"工"字,返回 RGBA 像素数据 */
|
||||
function makeTrayIconRGBA(r: number, g: number, b: number, size = 32): Uint8Array {
|
||||
/** 加载 SVG 图片(带缓存) */
|
||||
async function loadSvgImage(): Promise<HTMLImageElement> {
|
||||
if (cachedSvgImg) return cachedSvgImg;
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new window.Image();
|
||||
img.onload = () => { cachedSvgImg = img; resolve(img); };
|
||||
img.onerror = reject;
|
||||
img.src = "/gong.svg";
|
||||
});
|
||||
}
|
||||
|
||||
/** 加载 SVG → Canvas 渲染 → 像素替色 → 返回 RGBA 数据 */
|
||||
async function makeTrayIconRGBA(r: number, g: number, b: number, size = 32): Promise<Uint8Array> {
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
const ctx = canvas.getContext("2d")!;
|
||||
|
||||
// 圆形背景
|
||||
ctx.clearRect(0, 0, size, size);
|
||||
ctx.beginPath();
|
||||
ctx.arc(size / 2, size / 2, size / 2 - 1, 0, Math.PI * 2);
|
||||
ctx.fillStyle = `rgb(${r},${g},${b})`;
|
||||
ctx.fill();
|
||||
try {
|
||||
const svgImg = await loadSvgImage();
|
||||
|
||||
// 白色"工"字
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.font = `bold ${Math.round(size * 0.62)}px "Microsoft YaHei","SimHei",sans-serif`;
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText("工", size / 2, size / 2 + 1);
|
||||
ctx.drawImage(svgImg, 0, 0, size, size);
|
||||
const imageData = ctx.getImageData(0, 0, size, size);
|
||||
const data = imageData.data;
|
||||
|
||||
const imageData = ctx.getImageData(0, 0, size, size);
|
||||
return new Uint8Array(imageData.data.buffer);
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
// 根据亮度判断:暗像素(文字) → 白色,亮像素(背景) → 状态色
|
||||
const brightness = (data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114);
|
||||
if (brightness < 128) {
|
||||
data[i] = data[i + 1] = data[i + 2] = 255;
|
||||
} else {
|
||||
data[i] = r;
|
||||
data[i + 1] = g;
|
||||
data[i + 2] = b;
|
||||
}
|
||||
data[i + 3] = 255;
|
||||
}
|
||||
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
} catch {
|
||||
// SVG 加载失败,回退到纯 Canvas 绘制
|
||||
addLog("WARN", "SVG 图标加载失败,使用回退方案", "SYSTEM");
|
||||
ctx.fillStyle = `rgb(${r},${g},${b})`;
|
||||
ctx.fillRect(0, 0, size, size);
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.font = `bold ${Math.round(size * 0.62)}px "Microsoft YaHei","SimHei",sans-serif`;
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText("工", size / 2, size / 2 + 1);
|
||||
}
|
||||
|
||||
const finalData = ctx.getImageData(0, 0, size, size);
|
||||
return new Uint8Array(finalData.data.buffer);
|
||||
}
|
||||
|
||||
/** 根据当前应用状态更新托盘图标和提示文字 */
|
||||
|
|
@ -620,7 +712,7 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
tooltip = `${APP_NAME} - 监测中`;
|
||||
}
|
||||
|
||||
const icon = await Image.new(makeTrayIconRGBA(...color), 32, 32);
|
||||
const icon = await Image.new(await makeTrayIconRGBA(...color), 32, 32);
|
||||
await trayIconInstance.setIcon(icon);
|
||||
await trayIconInstance.setTooltip(tooltip);
|
||||
} catch (e: any) {
|
||||
|
|
@ -686,7 +778,7 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
const menu = await buildTrayMenu();
|
||||
|
||||
// 初始状态:灰色(未开始)
|
||||
const icon = await Image.new(makeTrayIconRGBA(158, 158, 158), 32, 32);
|
||||
const icon = await Image.new(await makeTrayIconRGBA(158, 158, 158), 32, 32);
|
||||
|
||||
trayIconInstance = await TrayIcon.new({
|
||||
icon,
|
||||
|
|
@ -763,6 +855,7 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
}
|
||||
|
||||
checkNetworkStatus();
|
||||
checkForUpdates();
|
||||
|
||||
if (config.value.auto_monitor && rememberPassword.value) {
|
||||
const canAutoStart = loginMode.value === "token"
|
||||
|
|
@ -795,12 +888,14 @@ export const useMonitorStore = defineStore("monitor", () => {
|
|||
isLoggedIn, isMonitoring, isPostponed, postponeResumeTime, autoStartEnabled,
|
||||
logs, networkStatus, config, ticketCounts,
|
||||
showCloseDialog,
|
||||
showUpdateDialog, updateInfo, updateProgress, isUpdating,
|
||||
// 方法
|
||||
initialize, cleanup,
|
||||
addLog, clearLogs, clearMessage, saveSettings, exportLogs,
|
||||
startMonitoring, stopMonitoring, resumeMonitoring, manualCheck,
|
||||
testNotification, checkNetworkStatus, updateConfig,
|
||||
minimizeToTray, handleCloseAction,
|
||||
checkForUpdates, confirmUpdate, dismissUpdate,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue