Compare commits

...

10 Commits

Author SHA1 Message Date
tsl aa01a63fcd feat(monitor): 新增暂停1小时监测功能 2026-07-06 10:43:48 +08:00
tsl 305fcfae06 refactor: ♻️ 使用router跳转页面 2026-04-17 10:11:17 +08:00
tsl 13f92f79b6 refactor: ♻️ 优化存储 2026-04-17 08:58:20 +08:00
tsl 8137d414da feat: 更新接口 2026-04-16 10:30:18 +08:00
tsl 82c2b0f1bd refactor: ♻️ 优化请求接口 2026-04-16 09:50:30 +08:00
tsl cc30c088c4 refactor(monitor): ♻️ 优化代码 2026-04-01 10:05:53 +08:00
tsl 0b2c1ca83f refactor: ♻️ 重构文件结构 2026-03-31 17:08:30 +08:00
tsl 1b6e12e402 feat(): 添加更新功能 2026-03-25 10:06:25 +08:00
tsl 92055dd6a0 feat(): 添加待审核 2026-03-23 09:10:32 +08:00
tsl 17618ec3a0 feat(): 优化状态栏 2026-03-10 15:20:06 +08:00
142 changed files with 16379 additions and 4479 deletions

124
.claude/CLAUDE.md Normal file
View File

@ -0,0 +1,124 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
这是一个基于 **Tauri 2.x + Vue 3** 的工单监测桌面应用,用于监测 CRM 系统crm.yunvip123.com的待处理工单并发送系统通知。
## 常用命令
项目使用 **pnpm** 作为包管理器。
```bash
# 启动开发模式(前端 + Tauri
pnpm run tauri-dev
# 仅启动前端开发服务器
pnpm run dev
# 前端类型检查 + 构建
pnpm run build
# 构建 Tauri 生产版本(含签名/安装包)
pnpm run tauri-build
# 构建并发布
pnpm run deploy
# 版本号管理(默认 patch
pnpm run version # patch
pnpm run version:minor
pnpm run version:major
# 代码检查
pnpm run lint
pnpm run lint:fix
# 规范提交commitizen + cz-git
pnpm run commit
# Rust 后端检查
cd src-tauri && cargo check
cd src-tauri && cargo clippy
```
## 架构概述
**前端驱动架构**所有业务逻辑API 调用、定时任务、通知)都在 Vue 前端实现Rust 后端仅负责系统级功能(窗口管理、插件注册)。
### 前端分层src/
**StoresPinia**
- `stores/monitor.ts` — 核心业务:登录、轮询检查工单、推迟/暂停逻辑、托盘联动
- `stores/app.ts` — 全局配置(轮询间隔、自启动、静默启动等),配置持久化到 `localStorage`key: `crm_config`
- `stores/log.ts` — 运行日志管理
- `stores/network.ts` — 网络状态检测
**Composables**
- `composables/useNotification.ts` — 系统通知封装(`tauri-plugin-notification`
- `composables/useTray.ts` — 系统托盘创建、图标/菜单动态更新
- `composables/useUpdater.ts` — 应用自动更新(`tauri-plugin-updater`
- `composables/useMonitor.ts` — 监测相关辅助逻辑
**Constants**
- `constants/api.ts` — 所有 API URL 集中定义(`LOGIN_URL`、`CHECK_URL`、`WORK_ORDER_URL`
- `constants/app.ts` — 应用级常量
**Utils**
- `utils/storage.ts` — localStorage 读写封装
- `utils/common.ts` — 通用工具函数(`formatTime` 等)
### Rust 后端src-tauri/src/
- `lib.rs` — 应用初始化、插件注册、窗口关闭事件处理(关闭→隐藏到托盘,发出 `close-requested` 事件)
### 关键数据流
1. `App.vue` 初始化:加载配置 → 加载凭据 → 初始化托盘 → 监听通知动作事件 + 关闭事件
2. `monitorStore.startMonitoring()` 执行登录(密码或 Token 模式),成功后启动 `setInterval` 轮询
3. 工单有待处理项时调用 `useNotification.notify()`,通知动作(推迟/去处理)通过 Tauri 事件回传
4. 托盘图标/菜单通过 `watch([isMonitoring, isPostponed, ticketCounts])` 自动同步
### API 集成
- 登录:`POST https://crm.yunvip123.com/api/SystemUser/Login`
- 工单查询:`GET https://crm.yunvip123.com/api/DemandManage/QueryIndexCount`
- 认证方式:登录响应 `set-cookie` 中提取 `ASP.NET_SessionId`,后续请求携带
- HTTP 白名单配置在 `src-tauri/capabilities/default.json`
### 通知触发条件
`PendingCount`(待处理)、`StaycloseCount`(待关闭)、`ConfirmCount`(待确认)任意 > 0 时触发。
## 代码规范
- Vue 组件使用 `<script setup lang="ts">` + `<style lang="scss" scoped>`
- 方法定义优先使用 `function` 关键字(而非箭头函数赋值)
- `props` 尽量提供 `default` 默认值;在 `script` 中使用 `props` 时通过 `toRefs(props)` 解构
- 新增成员变量和方法须加注释
## 关键配置文件
- `src-tauri/capabilities/default.json` — Tauri 权限配置HTTP 白名单、插件权限)
- `src-tauri/tauri.conf.json` — 应用配置窗口、图标、bundle、updater 端点)
- `.env` / `.env.development` / `.env.production` — 环境变量
- `vite.config.ts` — Vite 配置,开发服务器端口 1420HMR 端口 1421
## 依赖的 Tauri 插件
- `tauri-plugin-http` — HTTP 请求
- `tauri-plugin-notification` — 系统通知
- `tauri-plugin-autostart` — 开机自启动
- `tauri-plugin-opener` — 打开外部链接
- `tauri-plugin-updater` — 应用自动更新
- `tauri-plugin-store` — 持久化存储
- `tauri-plugin-process` — 进程控制
## Windows 编译要求
需要安装 Visual Studio Build Tools包含 C++ 工具链)才能编译 Rust 后端。

8
.claude/rules/js-ts.md Normal file
View File

@ -0,0 +1,8 @@
---
paths:
- "**/*.{js,mjs,cjs,jsx,ts,tsx}"
---
# JavaScript/TypeScript
- 尽量使用`function`定义方法

9
.claude/rules/uniapp.md Normal file
View File

@ -0,0 +1,9 @@
---
paths:
- "**/*.vue"
---
# Uniapp
- 组件文件命名使用`easycom`规范,示例:`components/组件名称/组件名称.vue`。
- 如果在`src/components`中符合`easycom`命名规范的,且在`pages.json`中配置`easycom.autoscan`不为`false`的组件,无需在使用是引入。

12
.claude/rules/vue3.md Normal file
View File

@ -0,0 +1,12 @@
---
paths:
- "**/*.vue"
---
# Vue 3
- 新建文件默认使用<script setup>
- 样式默认使用<style lang="scss" scoped>
- 尽量使用`function`定义方法
- `props`尽量使用`default`默认值初始化,包括`Object`类型中的属性值
- 如果在`script`中用到了`props`,则使用`toRefs(props)`解构

View File

@ -1,24 +1,39 @@
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Read",
"Edit",
"Write",
"Bash(pnpm build *)",
"Bash(pnpm install:*)",
"Bash(pnpm add:*)",
"Bash(pnpm run:*)",
"Bash(pnpm test:*)",
"Bash(pnpm view:*)",
"Bash(pnpm list:*)",
"Bash(git diff:*)",
"Bash(git status:*)",
"Bash(git log:*)",
"Bash(grep:*)",
"Bash(findstr:*)",
"Bash(netstat:*)",
"Bash(where:*)",
"Bash(echo:*)",
"WebFetch(domain:tauri.app)",
"Bash(npm install @tauri-apps/plugin-http @tauri-apps/plugin-autostart)",
"Bash(npx tauri build)",
"Bash(cargo update)",
"Bash(cargo build)",
"Bash(where link.exe)",
"Bash(PATH=\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64:$PATH\" cargo build)",
"Bash(export PATH=\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64:$PATH\")",
"Bash(CC=\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe\" CXX=\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe\" INCLUDE=\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/include;C:/Program Files \\(x86\\)/Windows Kits/10/Include/10.0.26100.0/ucrt;C:/Program Files \\(x86\\)/Windows Kits/10/Include/10.0.26100.0/um;C:/Program Files \\(x86\\)/Windows Kits/10/Include/10.0.26100.0/shared\" LIB=\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/lib/x64;C:/Program Files \\(x86\\)/Windows Kits/10/Lib/10.0.26100.0/um/x64;C:/Program Files \\(x86\\)/Windows Kits/10/Lib/10.0.26100.0/ucrt/x64\" PATH=\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64:$PATH\" cargo build)",
"Bash(echo $PATH)",
"Bash(echo \"PATH=$PATH\")",
"Bash(cmd.exe /C \"\"\"C:/Program Files \\(x86\\)/Microsoft Visual Studio/2022/BuildTools/VC/Auxiliary/Build/vcvars64.bat\"\" && cargo build\")",
"Bash(cmd.exe //C \"\"\"C:\\\\Program Files \\(x86\\)\\\\Microsoft Visual Studio\\\\2022\\\\BuildTools\\\\VC\\\\Auxiliary\\\\Build\\\\vcvars64.bat\"\" >nul 2>&1 & cargo build\")",
"Bash(cmd.exe //C \"D:\\\\Projects\\\\tauri\\\\tauri-app\\\\build.bat\")",
"Bash(npx vue-tsc --noEmit)",
"Bash(tasklist)",
"Bash(taskkill //F //IM tauri-app.exe)",
"Bash(taskkill //F //IM vite.exe)",
"Bash(cmd.exe //C \"D:\\\\Projects\\\\tauri\\\\tauri-app\\\\run.bat\")",
"Bash(cmd /c \"\"\"C:\\\\Program Files \\(x86\\)\\\\Microsoft Visual Studio\\\\2022\\\\BuildTools\\\\VC\\\\Auxiliary\\\\Build\\\\vcvars64.bat\"\" >nul 2>&1 && set\")",
"Bash(cmd /c \"\"\"C:\\\\Program Files \\(x86\\)\\\\Microsoft Visual Studio\\\\2022\\\\BuildTools\\\\VC\\\\Auxiliary\\\\Build\\\\vcvars64.bat\"\" && set\")",
@ -31,13 +46,8 @@
"Bash(powershell.exe -NoProfile -Command \"where.exe cl.exe\")",
"Bash(powershell.exe -NoProfile -Command \"Get-ItemProperty ''HKCU:\\\\Environment'' | Select-Object -ExpandProperty PATH | Select-String ''HostX64''\")",
"Bash(cargo check)",
"Bash(pnpm run tauri dev)",
"Bash(netstat -ano)",
"Bash(findstr :1420)",
"Bash(pnpm run tauri build)",
"Bash(start \"\" \"D:\\\\Projects\\\\tauri\\\\tauri-app\\\\src-tauri\\\\target\\\\release\\\\bundle\\\\nsis\\\\tauri-app_0.1.0_x64-setup.exe\")",
"Bash(pnpm run build)",
"Bash(pnpm add pinia)"
]
"Bash(start \"\" \"D:\\\\Projects\\\\tauri\\\\tauri-app\\\\src-tauri\\\\target\\\\release\\\\bundle\\\\nsis\\\\tauri-app_0.1.0_x64-setup.exe\")"
],
"ask": ["Read(./.env)", "Read(./.env.*)", "Read(./secrets/**)", "Bash(git push *)", "Bash(rm -rf *)"]
}
}

3
.czrc Normal file
View File

@ -0,0 +1,3 @@
{
"path": "cz-git"
}

14
.editorconfig Normal file
View File

@ -0,0 +1,14 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.ps1]
charset = utf-8-bom
end_of_line = crlf
indent_size = 4

2
.env Normal file
View File

@ -0,0 +1,2 @@
VITE_APP_NAME=工单系统监测
VITE_API_BASE=https://crm.yunvip123.com/api

2
.env.development Normal file
View File

@ -0,0 +1,2 @@
# 开发环境
VITE_APP_NAME=工单系统监测【开发版】

2
.env.production Normal file
View File

@ -0,0 +1,2 @@
# 生产环境
VITE_APP_NAME=工单系统监测

1
.husky/commit-msg Normal file
View File

@ -0,0 +1 @@
pnpm exec commitlint --edit $1

1
.husky/pre-commit Normal file
View File

@ -0,0 +1 @@
pnpm lint-staged

4
.lintstagedrc.json Normal file
View File

@ -0,0 +1,4 @@
{
"*.{js,ts,vue}": ["eslint --fix", "prettier --write"],
"*.{css,less,json,md}": ["prettier --write"]
}

2
.serena/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/cache
/project.local.yml

152
.serena/project.yml Normal file
View File

@ -0,0 +1,152 @@
# the name by which the project can be referenced within Serena
project_name: "tauri-app"
# list of languages for which language servers are started; choose from:
# al bash clojure cpp csharp
# csharp_omnisharp dart elixir elm erlang
# fortran fsharp go groovy haskell
# java julia kotlin lua markdown
# matlab nix pascal perl php
# php_phpactor powershell python python_jedi r
# rego ruby ruby_solargraph rust scala
# swift terraform toml typescript typescript_vts
# vue yaml zig
# (This list may be outdated. For the current list, see values of Language enum here:
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# Note:
# - For C, use cpp
# - For JavaScript, use typescript
# - For Free Pascal/Lazarus, use pascal
# Special requirements:
# Some languages require additional setup/installations.
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
# When using multiple languages, the first language server that supports a given file will be used for that file.
# The first language is the default language and the respective language server will be used as a fallback.
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
languages:
- vue
# the encoding used by text files in the project
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
encoding: "utf-8"
# line ending convention to use when writing source files.
# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default)
# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings.
line_ending:
# The language backend to use for this project.
# If not set, the global setting from serena_config.yml is used.
# Valid values: LSP, JetBrains
# Note: the backend is fixed at startup. If a project with a different backend
# is activated post-init, an error will be returned.
language_backend:
# whether to use project's .gitignore files to ignore files
ignore_all_files_in_gitignore: true
# advanced configuration option allowing to configure language server-specific options.
# Maps the language key to the options.
# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available.
# No documentation on options means no options are available.
ls_specific_settings: {}
# list of additional paths to ignore in this project.
# Same syntax as gitignore, so you can use * and **.
# Note: global ignored_paths from serena_config.yml are also applied additively.
ignored_paths: []
# whether the project is in read-only mode
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
# Added on 2025-04-18
read_only: false
# list of tool names to exclude.
# This extends the existing exclusions (e.g. from the global configuration)
#
# Below is the complete list of tools for convenience.
# To make sure you have the latest list of tools, and to view their descriptions,
# execute `uv run scripts/print_tool_overview.py`.
#
# * `activate_project`: Activates a project by name.
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
# * `create_text_file`: Creates/overwrites a file in the project directory.
# * `delete_lines`: Deletes a range of lines within a file.
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
# * `execute_shell_command`: Executes a shell command.
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
# * `initial_instructions`: Gets the initial instructions for the current project.
# Should only be used in settings where the system prompt cannot be set,
# e.g. in clients you have no control over, like Claude Desktop.
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
# * `insert_at_line`: Inserts content at a given line in a file.
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
# * `list_memories`: Lists memories in Serena's project-specific memory store.
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
# * `read_file`: Reads a file within the project directory.
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
# * `remove_project`: Removes a project from the Serena configuration.
# * `replace_lines`: Replaces a range of lines within a file with new content.
# * `replace_symbol_body`: Replaces the full definition of a symbol.
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
# * `search_for_pattern`: Performs a search for a pattern in the project.
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
# * `switch_modes`: Activates modes by providing a list of their names
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
excluded_tools: []
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default).
# This extends the existing inclusions (e.g. from the global configuration).
included_optional_tools: []
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
fixed_tools: []
# list of mode names to that are always to be included in the set of active modes
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this setting overrides the global configuration.
# Set this to [] to disable base modes for this project.
# Set this to a list of mode names to always include the respective modes for this project.
base_modes:
# list of mode names that are to be activated by default.
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# This setting can, in turn, be overridden by CLI parameters (--mode).
default_modes:
# initial prompt for the project. It will always be given to the LLM upon activating the project
# (contrary to the memories, which are loaded on demand).
initial_prompt: ""
# time budget (seconds) per tool call for the retrieval of additional symbol information
# such as docstrings or parameter information.
# This overrides the corresponding setting in the global configuration; see the documentation there.
# If null or missing, use the setting from the global configuration.
symbol_info_budget:
# list of regex patterns which, when matched, mark a memory entry as readonly.
# Extends the list from the global configuration, merging the two lists.
read_only_memory_patterns: []
# list of regex patterns for memories to completely ignore.
# Matching memories will not appear in list_memories or activate_project output
# and cannot be accessed via read_memory or write_memory.
# To access ignored memory files, use the read_file tool on the raw file path.
# Extends the list from the global configuration, merging the two lists.
# Example: ["_archive/.*", "_episodes/.*"]
ignored_memory_patterns: []

1
.tauri/signing-key Normal file
View File

@ -0,0 +1 @@
dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5eVJXUG1sdWpVNnBJUHpXSjFZWnczeVpPVjNZMEVvOGFkQlB5UFZDSFNEc0FBQkFBQUFBQUFBQUFBQUlBQUFBQVVmWE1BVXlmNXNqRFRmSEhSU3ltY3hqT1h4aE1hRVNEenJ2RUhkZ0JZaFJWc1owb1hpY3UwaEdqeTNQelRYaVd4M3E4WWR2MTloYWJSZFVTQm5scUhaTjRKOXlqeVlPRVpybWZTY2p2cUQzNkpDZGZGRzBtTEgvdFVBajNzdnBPTXVROFZXQXFUTGc9Cg==

1
.tauri/signing-key.pub Normal file
View File

@ -0,0 +1 @@
dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDY0Q0YxMzNBM0Q5OEU4NEMKUldSTTZKZzlPaFBQWkVXRVdBVHdTdlNvVnZSL2FFQkZtbFpRTzdjNGxHbjJsZ1R5MFRLdkpmYzMK

View File

@ -1,74 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
这是一个基于 **Tauri 2.x + Vue 3** 的工单监控桌面应用,用于监控 CRM 系统crm.yunvip123.com的待处理工单并发送系统通知。
## 常用命令
项目使用 **npm** 作为包管理器(存在 package-lock.json
```bash
# 启动开发模式(前端 + Tauri
pnpm run tauri dev
# 仅启动前端开发服务器
pnpm run dev
# 构建生产版本
npm run tauri build
# 前端类型检查 + 构建
pnpm run build
# Rust 后端检查
cd src-tauri && cargo check
cd src-tauri && cargo clippy
```
## 架构概述
**前端驱动架构**所有业务逻辑API 调用、定时任务、通知)都在 Vue 前端实现Rust 后端仅负责系统级功能。
### 前端src/
- `src/App.vue` - 主界面,包含全部业务逻辑:用户认证、监控调度、通知、网络检测、配置管理、系统托盘
- 使用 Vue 3 Composition API`<script setup>`
- Vite 开发服务器端口1420HMR 端口1421
- 系统托盘使用 `@tauri-apps/api/tray``@tauri-apps/api/menu` 实现
### Rust 后端src-tauri/src/
- `lib.rs` - 应用初始化、插件注册、窗口关闭事件处理(关闭→隐藏到托盘)
### Tauri 命令
无自定义命令(所有功能通过前端 API 实现)
### API 集成
- 登录:`POST https://crm.yunvip123.com/api/SystemUser/Login`
- 工单查询:`GET https://crm.yunvip123.com/api/DemandManage/QueryIndexCount`
- 认证方式ASP.NET_SessionId Cookie
- HTTP 白名单配置在 `src-tauri/capabilities/default.json`
### 通知触发条件
当以下任意计数 > 0 时触发系统通知:
- `PendingCount`(待处理)
- `StaycloseCount`(待关闭)
- `ConfirmCount`(待确认)
## 关键配置
- `src-tauri/capabilities/default.json` - Tauri 权限配置HTTP 白名单、插件权限)
- `src-tauri/tauri.conf.json` - 应用配置窗口、图标、bundle
- 用户配置文件路径:`%APPDATA%/tauri-app/config.json`Windows
## 依赖的 Tauri 插件
- `tauri-plugin-http` - HTTP 请求
- `tauri-plugin-notification` - 系统通知
- `tauri-plugin-autostart` - 开机自启动
- `tauri-plugin-opener` - 打开外部链接
## Windows 编译要求
需要安装 Visual Studio Build Tools包含 C++ 工具链)才能编译 Rust 后端。

144
README.md
View File

@ -1,7 +1,137 @@
# Tauri + Vue + TypeScript
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Vue - Official](https://marketplace.visualstudio.com/items?itemName=Vue.volar) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
# 工单系统监测
基于 **Tauri 2.x + Vue 3 + TypeScript** 的工单监测桌面应用,用于监测 CRM 系统的待处理工单并发送系统通知。
## 环境要求
- Node.js >= 18
- Ruststable
- Visual Studio Build ToolsWindows含 C++ 工具链)
- pnpm
**推荐 IDE** [VS Code](https://code.visualstudio.com/) + [Vue - Official](https://marketplace.visualstudio.com/items?itemName=Vue.volar) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
## 开发
```bash
# 安装依赖
pnpm install
# 启动开发模式(前端 + Tauri
pnpm run tauri-dev
# 仅启动前端开发服务器
pnpm run dev
```
## 构建
签名密钥已包含在项目中(`.tauri/` 目录),构建脚本会自动加载,直接运行:
```bash
pnpm run tauri-build
```
构建产物位于 `src-tauri/target/release/bundle/nsis/`
## 版本号管理
使用自定义脚本统一更新 `package.json`、`tauri.conf.json`、`Cargo.toml` 三个文件的版本号:
```bash
pnpm run version:patch # 补丁版本 x.y.Z → x.y.Z+1
pnpm run version:minor # 次版本 x.Y.z → x.Y+1.0
pnpm run version:major # 主版本 X.y.z → X+1.0.0
pnpm run version -- 1.2.3 # 指定版本号
```
## 发布
构建完成后,运行发布脚本将安装包和更新元数据上传到远程服务器:
```bash
pnpm run publish -- --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. 更新版本号
pnpm run version:minor
# 2. 构建
pnpm run tauri-build
# 3. 发布到服务器
pnpm run publish -- --notes "v0.3.0 新功能说明"
```
或一键构建 + 发布:
```bash
pnpm run release
```
## 签名密钥
项目已内置 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/ # 前端Vue 3
├── App.vue # 主界面
├── stores/monitor.ts # Pinia 状态管理(核心业务逻辑)
├── components/
│ ├── MonitorControl.vue # 监测面板(工单数据卡片)
│ ├── LoginForm.vue # 登录表单
│ ├── SettingsPanel.vue # 配置面板
│ ├── StatusHeader.vue # 顶部状态栏
│ ├── LogViewer.vue # 日志查看器
│ ├── CloseDialog.vue # 关闭确认弹窗
│ └── UpdateDialog.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
| 接口 | 说明 | 触发通知条件 |
| ----------------------------------- | ---------------- | ------------------------------------------------ |
| `SystemUser/Login` | 登录获取 Session | - |
| `DemandManage/QueryIndexCount` | 工单统计 | PendingCount / StaycloseCount / ConfirmCount > 0 |
| `DemandManage/GetWorkOrderListPage` | 待审核工单列表 | DataCount > 0 |
## Tauri 插件
- `tauri-plugin-http` — HTTP 请求
- `tauri-plugin-notification` — 系统通知
- `tauri-plugin-autostart` — 开机自启动
- `tauri-plugin-opener` — 打开外部链接
- `tauri-plugin-updater` — 应用内自动更新
- `tauri-plugin-process` — 进程管理(重启)

View File

@ -1,137 +0,0 @@
# 系统监控应用程序
这是一个基于 Tauri + Vue 开发的系统监控应用程序,具有以下功能:
## 功能特性
1. **用户设置界面** - 配置用户名和密码
2. **系统托盘集成** - 应用启动后自动最小化到系统托盘
3. **自动登录** - 保存用户凭据并支持自动登录
4. **定时API调用** - 登录后每1分钟调用一次接口
5. **系统通知** - 根据API返回值弹出系统消息
6. **模块化架构** - 代码按功能模块组织,便于维护
## 项目结构
```
src-tauri/src/
├── lib.rs # 主模块,应用程序入口和命令处理
├── config.rs # 配置管理模块
├── api.rs # API调用模块
├── tray.rs # 系统托盘模块
└── scheduler.rs # 定时任务模块
src/
└── App.vue # Vue设置界面
```
## 使用说明
### 1. 启动应用程序
```bash
# 开发模式
pnpm tauri dev
# 构建生产版本
pnpm tauri build
```
### 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

132
commitlint.config.cjs Normal file
View File

@ -0,0 +1,132 @@
/**
* feat新增功能
* fixbug 修复
* docs文档更新
* style不影响程序逻辑的代码修改(修改空白字符格式缩进补全缺失的分号等没有改变代码逻辑)
* refactor重构代码(既没有新增功能也没有修复 bug)
* perf性能, 体验优化
* test新增测试用例或是更新现有测试
* build主要目的是修改项目构建系统(例如 viterollup 的配置等)的提交
* ci主要目的是修改项目持续集成流程的提交
* chore不属于以上类型的其他类型比如构建流程, 依赖管理
* revert回滚某个更早之前的提交
*/
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
// 限制提交类型
"type-enum": [
2,
"always",
[
"feat",
"fix",
"docs",
"style",
"refactor",
"perf",
"test",
"build",
"ci",
"chore",
"revert",
],
],
// scope 可选,如果提供必须是以下之一
"scope-enum": [
2,
"always",
[
"monitor", // 监测核心逻辑
"auth", // 认证/登录
"notify", // 通知
"tray", // 系统托盘
"config", // 配置管理
"store", // 状态管理
"ui", // 界面/组件
"tauri", // Rust/Tauri 后端
"network", // 网络检测
"update", // 自动更新
"deps", // 依赖更新
"release", // 版本发布
],
],
// subject 不能为空
"subject-empty": [2, "never"],
// subject 不能以句号结尾
"subject-full-stop": [2, "never", "."],
// subject 不限制大小写
"subject-case": [0],
// type 必须小写
"type-case": [2, "always", "lower-case"],
// scope 必须小写
"scope-case": [2, "always", "lower-case"],
// subject 最小长度
"subject-min-length": [2, "always", 4],
// subject 最大长度
"subject-max-length": [2, "always", 100],
// header 最大长度(type + scope + subject)
"header-max-length": [2, "always", 120],
// body 每行最大长度
"body-max-line-length": [2, "always", 200],
// footer 每行最大长度
"footer-max-line-length": [2, "always", 200],
},
prompt: {
useEmoji: true,
emojiAlign: "center",
allowCustomIssuePrefix: false,
allowEmptyIssuePrefix: false,
// 定义 scope 选项
scopes: [
{ value: "monitor", name: "monitor: 监测核心逻辑" },
{ value: "auth", name: "auth: 认证/登录" },
{ value: "notify", name: "notify: 通知" },
{ value: "tray", name: "tray: 系统托盘" },
{ value: "config", name: "config: 配置管理" },
{ value: "store", name: "store: 状态管理" },
{ value: "ui", name: "ui: 界面/组件" },
{ value: "tauri", name: "tauri: Rust/Tauri 后端" },
{ value: "network", name: "network: 网络检测" },
{ value: "update", name: "update: 自动更新" },
{ value: "deps", name: "deps: 依赖更新" },
{ value: "release", name: "release: 版本发布" },
],
allowCustomScopes: false,
allowEmptyScopes: true,
messages: {
type: '选择你要提交的类型:',
scope: '选择一个提交范围(可选):',
customScope: '请输入自定义范围:',
subject: '请简短描述这次改动:\n',
body: '请详细描述这次改动(可选,用 "|" 换行):\n',
breaking: '是否有破坏性变更(可选,用 "|" 换行):\n',
footerPrefixesSelect: '选择关联的 ISSUE 类型(可选):',
customFooterPrefix: '输入 ISSUE 前缀:',
footer: '列出关联的 ISSUE如: #31, #34:\n',
generatingByAI: '正在通过 AI 生成提交信息...',
generatedSelectByAI: '选择一个 AI 生成的 subject:',
confirmCommit: '是否确认提交以上信息?',
},
minSubjectLength: 4,
defaultSubject: '',
types: [
{ value: 'feat', name: 'feat: 新增功能', emoji: ':sparkles:' },
{ value: 'fix', name: 'fix: 修复缺陷', emoji: ':bug:' },
{ value: 'docs', name: 'docs: 文档变更', emoji: ':memo:' },
{ value: 'style', name: 'style: 代码格式(不影响逻辑)', emoji: ':lipstick:' },
{ value: 'refactor', name: 'refactor: 重构(既非新功能,也不是修 bug', emoji: ':recycle:' },
{ value: 'perf', name: 'perf: 性能优化', emoji: ':zap:' },
{ value: 'test', name: 'test: 添加或修改测试', emoji: ':white_check_mark:' },
{ value: 'build', name: 'build: 构建系统或外部依赖变更', emoji: ':package:' },
{ value: 'ci', name: 'ci: CI 配置文件和脚本变更', emoji: ':ferris_wheel:' },
{ value: 'chore', name: 'chore: 其它不修改 src 或测试的改动', emoji: ':hammer:' },
{ value: 'revert', name: 'revert: 回退之前的 commit', emoji: ':rewind:' },
],
issuePrefixs: [
{ value: 'link', name: 'link: 关联 ISSUE' },
{ value: 'close', name: 'close: 关闭 ISSUE' },
],
},
};

View File

@ -0,0 +1,102 @@
fetch("https://crm.yunvip123.com/api/DemandManage/GetWorkOrderListPage", {
headers: {
accept: "application/json, text/javascript, */*; q=0.01",
"accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"sec-ch-ua":
'"Not:A-Brand";v="99", "Google Chrome";v="145", "Chromium";v="145"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"x-requested-with": "XMLHttpRequest",
},
referrer:
"https://crm.yunvip123.com/WebUI/DemandManagement/DemandListNew.html?v=2.0.4.12",
body: "DL_ProductID=&DL_ID=&isSelect=8&Solution=&OrderType=&DL_TaskName=&CreatGID=&CreatTimeStart=&CreatTimeEnd=&SloveGID=&SloveTimeStart=&SloveTimeEnd=&ShowTable=DemandList&isShow=3&IsExport=0&PageIndex=1&PageSize=20",
method: "POST",
mode: "cors",
credentials: "include",
});
const requsetBody = {
DL_ProductID: null,
DL_ID: null,
isSelect: 8,
Solution: null,
OrderType: null,
DL_TaskName: null,
CreatGID: null,
CreatTimeStart: null,
CreatTimeEnd: null,
SloveGID: null,
SloveTimeStart: null,
SloveTimeEnd: null,
ShowTable: null,
DemandList: null,
isShow: 3,
IsExport: 0,
PageIndex: 1,
PageSize: 20,
};
const responseBody = {
success: true,
code: null,
msg: "执行成功",
data: {
PageTotal: 1,
PageSize: 20,
DataCount: 1,
PageIndex: 1,
DataList: [
{
ID: 58624,
DL_OrderType: 2,
DL_Status: 350,
DL_StatusID: null,
DL_ProductID: 64,
DL_ProductName: "六个羽友",
DL_ID: 1039,
DL_ItemID: "六个羽友2.21",
DL_ProblemDegree: "1",
DL_Priority: null,
DL_TaskName: "一次批量订场,立即支付页面转圈圈",
DL_ProblemSource: "",
DL_CreatorGID: "229707a9-8eac-4540-b1d0-f64ce87ce054",
DL_Creator: "龚诚",
DL_CreateTime: "2026-03-05 13:54:06",
DL_AffirmGID: "229707a9-8eac-4540-b1d0-f64ce87ce054",
DL_AffirmName: "龚诚",
DL_ConfirmTime: null,
DL_AffirmRemark: null,
DL_AssignGID: "512860ad-aa4a-4268-a5d9-6c7d2e28680b",
DL_AssignName: "A田森林",
DL_AssignRemark: null,
DL_SolveGID: null,
DL_SolveName: null,
DL_SolveTime: null,
DL_SolveRemark: null,
DL_CloseGID: null,
DL_CloseName: null,
DL_CloseTime: null,
DL_CloseRemark: null,
DL_Remark: null,
DL_AuditStatus: null,
DL_DemandContent:
' <p class="txtContent"><font color="#333333">一次批量订场(32个场次),立即支付页面转圈圈</font></p><p class="txtContent"><img src="https://img1.yunvip123.com/202603/134171636069619186.png" style="max-width: 100% !important; vertical-align: middle !important;"><img src="https://img1.yunvip123.com/202603/134171636323013515.png" style="max-width: 100% !important; vertical-align: middle !important;"></p><p class="txtContent"></p>\n ',
DL_TestContent: "",
DL_DemandName: "一次批量订场,立即支付页面转圈圈",
DL_OrderLevel: 50,
DL_RepeatID: null,
DL_RepeatStatus: null,
DL_Identitying: null,
DL_WorkHour: null,
DL_ConfirmState: null,
},
],
StatisticsInfo: null,
TrendData: null,
},
};

View File

@ -6,7 +6,8 @@
* 所有接口都要带 cookie: ASP.NET_SessionId=td0mirxws4klqpm0bydhvgjj
*/
const requestData = "UserAcount=&PassWord=123456&VerifyCode=&Account=18688886666_777&ValidateCode=";
const requestData =
"UserAcount=&PassWord=123456&VerifyCode=&Account=18688886666_777&ValidateCode=";
const responseBody = {
success: true,

32
data/api/README.md Normal file
View File

@ -0,0 +1,32 @@
# API 开发与类型定义流程
当前接口与类型定义以 OpenAPI 文档为准:
- 源文件:`data/api/默认模块.openapi.json`
- 来源:该文件由 **Apifox 导出**
- 内容:包含接口定义、字段说明、请求/响应示例
## 1. 更新 OpenAPI 文档
- 在 Apifox 中维护接口后,导出最新 OpenAPI 文件并覆盖 `data/api/默认模块.openapi.json`
- 新增/修改接口时先以该文件为唯一事实来源Single Source of Truth
## 2. 生成/更新接口层 (src/api/)
- 根据 `paths` 中的接口定义,更新 `src/api/` 下的请求函数(路径、方法、请求参数)。
- 保持现有业务兼容时,可新增标准方法并保留旧方法别名。
## 3. 生成/更新类型定义 (src/api/types/)
- 根据 OpenAPI 中的 schema、字段说明和示例维护 `src/api/types/` 下类型。
- 在 `src/api/types/index.ts` 统一导出类型。
- 新增字段时补充必要注释,命名与接口字段保持一致。
## 4. 使用与校验
- 在业务层使用 `ApiResponse<T>` 包装响应类型。
- 修改后执行类型检查:
```bash
npm run type-check
```

23
data/api/client.ts Normal file
View File

@ -0,0 +1,23 @@
import fs from "node:fs";
import path from "node:path";
import axios from "axios";
import dotenv from "dotenv";
dotenv.config({ path: path.resolve(process.cwd(), ".env.local") });
const client = axios.create({
baseURL: "https://crm.yunvip123.com/api",
headers: {
"Content-Type": "application/json",
Host: "crm.yunvip123.com",
},
});
/** 保存响应到接口所在目录的 response.json */
export function saveResponse(dirPath: string, data: any) {
const filePath = path.join(dirPath, "response.json");
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
console.log(`[SUCCESS] 已保存至: ${path.relative(process.cwd(), filePath)}`);
}
export default client;

24
data/api/login/request.ts Normal file
View File

@ -0,0 +1,24 @@
import path from "path";
import { fileURLToPath } from "url";
import client, { saveResponse } from "../client.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export async function login() {
const username = process.env.TEST_USERNAME;
const password = process.env.TEST_PASSWORD;
const response = await client.post("/SystemUser/Login", {
Account: username,
PassWord: password,
});
saveResponse(__dirname, response.data);
const setCookie = response.headers["set-cookie"];
if (setCookie) {
client.defaults.headers.common["Cookie"] = setCookie[0].split(";")[0];
}
return response.data;
}

View File

@ -0,0 +1,508 @@
{
"success": true,
"code": null,
"msg": "执行成功",
"data": {
"GID": "512860ad-aa4a-4268-a5d9-6c7d2e28680b",
"SR_GID": "44a2ccd1-bd45-4114-a999-2f2222510e44",
"SD_GID": "f124825e-f2b8-414e-b03c-cfca47a9922e",
"SU_Account": "18688886666_777",
"SU_Password": "PdvNK8uJWJU=",
"SU_AdminType": 11,
"SU_IsDisable": 0,
"SU_UserName": "A田森林",
"SU_Telephone": "",
"SU_LastLoginTime": null,
"SU_CreateTime": "2022-05-27 16:04:24",
"SU_Creator": null,
"SU_Flag": null,
"SU_Code": "777",
"SU_BrowseRole": 2,
"SU_QQCode": "",
"SU_WeChatImageUrl": null,
"SU_IsShunt": 0,
"MaxReception": 0,
"AG_GID": "0000",
"SU_WeChatCode": null,
"SU_UserType": 320,
"SR_Name": "7-开发人员",
"SD_Name": null,
"AG_Domain": null,
"AG_Type": 0,
"AG_SoftwareName": null,
"AG_Contacter": null,
"DL_CreatNum": null,
"DL_SloveNum": null,
"BUGNum": null,
"DMNum": null,
"TESNum": null,
"ACNum": null,
"WorkHour": null,
"WaitCloseNum": null,
"CloseNum": null,
"SRRole": [
{
"GID": "1de667e5-079b-4631-8bad-2077164be47a",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "获取菜单列表",
"RS_LinkUrl": "/api/SystemMenu/GetListMenu",
"RS_IsShow": 1,
"RS_Sort": 13,
"RS_CreateTime": "2018-04-11 10:27:18",
"RS_Code": null
},
{
"GID": "d6e92461-2511-4c9f-93b0-a8e413520d48",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "修改工单",
"RS_LinkUrl": "/api/DemandManage/EditWorkOrder",
"RS_IsShow": 0,
"RS_Sort": 4,
"RS_CreateTime": "2025-03-04 09:14:57",
"RS_Code": ""
},
{
"GID": "bffee97c-139c-4735-a76d-dbe9c4d64637",
"MM_GID": "a9c87517-4da2-4f98-a5b9-35bf277fb375",
"RS_Name": "查询日志记录",
"RS_LinkUrl": "/api/SystemLog/QueryList",
"RS_IsShow": 1,
"RS_Sort": 100,
"RS_CreateTime": "2019-11-21 13:43:57",
"RS_Code": null
},
{
"GID": "b8bd82f6-e9fa-4e8a-b77c-86803610fc7f",
"MM_GID": "a9c87517-4da2-4f98-a5b9-35bf277fb375",
"RS_Name": "系统日志分页",
"RS_LinkUrl": "/api/SystemLog/QueryPage",
"RS_IsShow": 0,
"RS_Sort": 1,
"RS_CreateTime": "2018-10-25 19:55:07",
"RS_Code": null
},
{
"GID": "a3b894b1-1064-42ca-90c8-6c005439d2ec",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "根据菜单GID获取对应资源",
"RS_LinkUrl": "/api/SystemResource/GetListResourceByMenuGID",
"RS_IsShow": 1,
"RS_Sort": 5,
"RS_CreateTime": "2018-04-10 09:51:47",
"RS_Code": null
},
{
"GID": "9600f960-3b5f-4e1e-ae84-1e607919ff30",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "解决工单",
"RS_LinkUrl": "/api/DemandManage/ResolveWorkOrders",
"RS_IsShow": 0,
"RS_Sort": 13,
"RS_CreateTime": "2025-03-04 09:17:51",
"RS_Code": ""
},
{
"GID": "4bac85dc-9f40-432d-a851-2f97408d83b6",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "编辑工时",
"RS_LinkUrl": "/api/DemandManage/EditWorkHour",
"RS_IsShow": 1,
"RS_Sort": 6,
"RS_CreateTime": "2025-03-04 09:15:45",
"RS_Code": null
},
{
"GID": "c696815b-da5c-4d9f-ba12-6087ca7beedc",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "获取项目列表",
"RS_LinkUrl": "/api/ProjectMange/GetProject",
"RS_IsShow": 0,
"RS_Sort": 2,
"RS_CreateTime": "2025-03-04 09:14:19",
"RS_Code": ""
},
{
"GID": "ab7ed673-4bce-4865-9688-fa1fd9d31fd7",
"MM_GID": "797aff6a-ecb9-4120-831d-150f96c8d963",
"RS_Name": "编辑项目状态",
"RS_LinkUrl": "/api/ProjectMange/EditProjectState",
"RS_IsShow": 1,
"RS_Sort": 100,
"RS_CreateTime": "2022-09-29 09:25:17",
"RS_Code": null
},
{
"GID": "7b30e174-7472-4d8c-a243-0d5bab682e8e",
"MM_GID": "797aff6a-ecb9-4120-831d-150f96c8d963",
"RS_Name": "更新统计",
"RS_LinkUrl": "/api/ProjectMange/GetProjectStat",
"RS_IsShow": 1,
"RS_Sort": 120,
"RS_CreateTime": "2020-07-27 10:10:37",
"RS_Code": "P42"
},
{
"GID": "e283a777-a7a1-48e9-abb4-030bb0f21990",
"MM_GID": "2e73c23f-f635-45a3-8ed3-1f75245c099c",
"RS_Name": "添加工单",
"RS_LinkUrl": "/api/DemandManage/AddDemandList",
"RS_IsShow": 1,
"RS_Sort": 110,
"RS_CreateTime": "2019-12-02 09:57:30",
"RS_Code": "E42"
},
{
"GID": "a9934927-1756-4b31-a718-2cb4bd7fb9b7",
"MM_GID": "2e73c23f-f635-45a3-8ed3-1f75245c099c",
"RS_Name": "删除工单",
"RS_LinkUrl": "/api/DemandManage/DelDemandList",
"RS_IsShow": 1,
"RS_Sort": 140,
"RS_CreateTime": "2020-07-27 10:01:17",
"RS_Code": "E40"
},
{
"GID": "615b1a1e-f0a2-4596-9cd0-b10e5831db3c",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "删除工单信息",
"RS_LinkUrl": "/api/DemandManage/DeleteWorkOrders",
"RS_IsShow": 1,
"RS_Sort": 5,
"RS_CreateTime": "2025-03-04 09:15:18",
"RS_Code": null
},
{
"GID": "279b5274-3b1c-4d4a-a958-e4da67908c2b",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "工单确认状态",
"RS_LinkUrl": "/api/DemandManage/EditConfirm",
"RS_IsShow": 0,
"RS_Sort": 7,
"RS_CreateTime": "2025-03-04 09:16:19",
"RS_Code": ""
},
{
"GID": "148ddcdf-a466-42af-ac7c-dd5a89043c39",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "关闭工单",
"RS_LinkUrl": "/api/DemandManage/CloseWorkOrders",
"RS_IsShow": 0,
"RS_Sort": 9,
"RS_CreateTime": "2025-03-04 09:16:49",
"RS_Code": ""
},
{
"GID": "35af5158-e717-40c9-8278-30886a926cc9",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "修改密码",
"RS_LinkUrl": "/api/SystemUser/ChangePwd",
"RS_IsShow": 1,
"RS_Sort": 23,
"RS_CreateTime": "2018-05-04 11:19:09",
"RS_Code": null
},
{
"GID": "dd91bb92-4977-4844-ba71-769572a35c65",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "根据角色GID获取对应资源",
"RS_LinkUrl": "/api/SystemRole/GetMenuResourceBySR_GID",
"RS_IsShow": 1,
"RS_Sort": 6,
"RS_CreateTime": "2018-04-10 09:52:34",
"RS_Code": null
},
{
"GID": "e62504e6-1e2c-46c8-9d5b-62352a3aea20",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "获取待处理与待关闭工单统计",
"RS_LinkUrl": "/api/DemandManage/QueryIndexCount",
"RS_IsShow": 0,
"RS_Sort": 100,
"RS_CreateTime": "2020-07-27 10:06:35",
"RS_Code": null
},
{
"GID": "e3913650-20d9-4dfc-98b6-24f9cfee6066",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "获取工单列表数据",
"RS_LinkUrl": "/api/DemandManage/GetWorkOrderListPage",
"RS_IsShow": 0,
"RS_Sort": 1,
"RS_CreateTime": "2025-03-04 09:13:51",
"RS_Code": ""
},
{
"GID": "05277dcc-acdf-400c-972a-ac09100d9ecf",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "创建工单",
"RS_LinkUrl": "/api/DemandManage/AddDemandList",
"RS_IsShow": 0,
"RS_Sort": 3,
"RS_CreateTime": "2025-03-04 09:14:44",
"RS_Code": ""
},
{
"GID": "634305c7-c82d-4ded-89ce-fe2f56bf8e98",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "获取用户公告",
"RS_LinkUrl": "/api/UsersNotice/GetUsersNoticeList",
"RS_IsShow": 0,
"RS_Sort": 0,
"RS_CreateTime": "2021-04-20 13:29:23",
"RS_Code": null
},
{
"GID": "cd8a461e-61cf-475d-a102-0c847eddfefc",
"MM_GID": "797aff6a-ecb9-4120-831d-150f96c8d963",
"RS_Name": "项目分页",
"RS_LinkUrl": "/api/ProjectMange/GetProjectPage",
"RS_IsShow": 0,
"RS_Sort": 90,
"RS_CreateTime": "2019-12-02 09:16:30",
"RS_Code": ""
},
{
"GID": "1dbe692c-f31c-4dff-86e2-aa457e21061d",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "获取个人资料",
"RS_LinkUrl": "/api/SystemUser/GetObjectUser",
"RS_IsShow": 1,
"RS_Sort": 21,
"RS_CreateTime": "2018-05-04 11:18:24",
"RS_Code": null
},
{
"GID": "bd9518e0-70e1-47c7-8c6a-5c13694f1af5",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "历史记录",
"RS_LinkUrl": "/api/SystemLog/QueryList",
"RS_IsShow": 0,
"RS_Sort": 100,
"RS_CreateTime": "2019-11-21 13:41:15",
"RS_Code": ""
},
{
"GID": "8613c0af-89c7-4398-b017-55d2ae2ca157",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "用户列表",
"RS_LinkUrl": "/api/SystemUser/GetListUser",
"RS_IsShow": 0,
"RS_Sort": 1,
"RS_CreateTime": "2018-04-09 19:50:58",
"RS_Code": null
},
{
"GID": "e513c484-5ec0-4380-a477-c83623b4782b",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "工单列表",
"RS_LinkUrl": "/api/DemandManage/GetDemandList",
"RS_IsShow": 1,
"RS_Sort": 100,
"RS_CreateTime": "2019-12-02 09:21:38",
"RS_Code": ""
},
{
"GID": "21040880-1df6-494d-866a-b10fc257393d",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "查询产品",
"RS_LinkUrl": "/api/ProductManage/GetProductMange",
"RS_IsShow": 1,
"RS_Sort": 100,
"RS_CreateTime": "2019-12-02 09:26:23",
"RS_Code": null
},
{
"GID": "baa47e69-9143-4860-84d7-e99c60eeb417",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "完成工单",
"RS_LinkUrl": "/api/DemandManage/FinishWorkOrders",
"RS_IsShow": 0,
"RS_Sort": 8,
"RS_CreateTime": "2025-03-04 09:16:36",
"RS_Code": ""
},
{
"GID": "e79ef9d5-f0ae-4efb-a747-2097d64c857e",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "工单分页",
"RS_LinkUrl": "/api/DemandManage/GetDemandListPage",
"RS_IsShow": 0,
"RS_Sort": 100,
"RS_CreateTime": "2019-12-02 09:20:16",
"RS_Code": ""
},
{
"GID": "ad92007d-a867-4bee-b719-4e94323c2700",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "编辑备注",
"RS_LinkUrl": "/api/DemandManage/EditWorkOrdersRemark",
"RS_IsShow": 0,
"RS_Sort": 10,
"RS_CreateTime": "2025-03-04 09:17:05",
"RS_Code": ""
},
{
"GID": "2acdfb25-66e3-4473-8f2c-c802122f515b",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "指派工单",
"RS_LinkUrl": "/api/DemandManage/AssignWorkOrder",
"RS_IsShow": 0,
"RS_Sort": 100,
"RS_CreateTime": "2025-03-16 22:34:16",
"RS_Code": ""
},
{
"GID": "a1ce3461-58cd-4b45-8292-71cb73472128",
"MM_GID": "2e73c23f-f635-45a3-8ed3-1f75245c099c",
"RS_Name": "编辑需求",
"RS_LinkUrl": "/api/DemandManage/EditDemandList",
"RS_IsShow": 1,
"RS_Sort": 120,
"RS_CreateTime": "2019-12-02 09:57:58",
"RS_Code": "E41"
},
{
"GID": "31c9f51d-764e-45d5-aaef-82917ddc7013",
"MM_GID": "797aff6a-ecb9-4120-831d-150f96c8d963",
"RS_Name": "项目备注",
"RS_LinkUrl": "/api/ProjectMange/AddProjectRemark",
"RS_IsShow": 1,
"RS_Sort": 130,
"RS_CreateTime": "2020-07-27 10:09:48",
"RS_Code": "P43"
},
{
"GID": "d96bb278-771f-4411-bb22-a74d0141defd",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "获取部门列表",
"RS_LinkUrl": "/api/SystemDepartment/GetListDepartment",
"RS_IsShow": 0,
"RS_Sort": 2,
"RS_CreateTime": "2018-04-09 20:44:31",
"RS_Code": null
},
{
"GID": "1dc15655-57fc-4505-94e2-90cc3df73e13",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "修改当前个人资料",
"RS_LinkUrl": "/api/SystemUser/EditProfile",
"RS_IsShow": 1,
"RS_Sort": 22,
"RS_CreateTime": "2018-05-04 11:18:36",
"RS_Code": null
},
{
"GID": "52b98bfb-d55f-457d-a3ff-7bf2eefa55a3",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "添加测试结果",
"RS_LinkUrl": "/api/DemandManage/TestWorkOrdersResult",
"RS_IsShow": 0,
"RS_Sort": 11,
"RS_CreateTime": "2025-03-04 09:17:20",
"RS_Code": ""
},
{
"GID": "03d7a89b-298f-4113-9090-d12fccb7aab4",
"MM_GID": "797aff6a-ecb9-4120-831d-150f96c8d963",
"RS_Name": "关闭项目",
"RS_LinkUrl": "/api/ProjectMange/CloseProject",
"RS_IsShow": 1,
"RS_Sort": 100,
"RS_CreateTime": "2021-01-12 17:13:10",
"RS_Code": "P45"
},
{
"GID": "fcc70c6a-03bb-4739-8676-e4ac42390c5c",
"MM_GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"RS_Name": "修改公告已读状态",
"RS_LinkUrl": "/api/UsersNotice/EditState",
"RS_IsShow": 0,
"RS_Sort": 0,
"RS_CreateTime": "2021-04-20 13:38:11",
"RS_Code": null
},
{
"GID": "76478667-e6be-49ea-b82d-f9f98350e186",
"MM_GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"RS_Name": "激活工单",
"RS_LinkUrl": "/api/DemandManage/ActivateWorkOrder",
"RS_IsShow": 0,
"RS_Sort": 12,
"RS_CreateTime": "2025-03-04 09:17:35",
"RS_Code": ""
}
],
"MenuInfoList": [
{
"GID": "fd47e5a8-d361-4cc5-864f-7e19dfd2856e",
"MM_Name": "工单统计",
"MM_LinkUrl": "/WebUI/DemandManagement/WorkOrderStat.html",
"MM_ParentID": "4dd3c69a-01e7-4aed-9c75-a94037ac9b5d",
"MM_Sort": 1,
"MM_Mark": null,
"MM_Ico": "",
"ResourceList": null
},
{
"GID": "797aff6a-ecb9-4120-831d-150f96c8d963",
"MM_Name": "项目管理",
"MM_LinkUrl": "/WebUI/ProjectMange/ProjectList.html",
"MM_ParentID": "",
"MM_Sort": 4,
"MM_Mark": null,
"MM_Ico": "",
"ResourceList": null
},
{
"GID": "d88b1caa-b4cf-407f-bc25-9339ae2e5ece",
"MM_Name": "工单列表",
"MM_LinkUrl": "/WebUI/DemandManagement/DemandListNew.html",
"MM_ParentID": "",
"MM_Sort": 9,
"MM_Mark": null,
"MM_Ico": "",
"ResourceList": null
},
{
"GID": "4dd3c69a-01e7-4aed-9c75-a94037ac9b5d",
"MM_Name": "统计报表",
"MM_LinkUrl": "",
"MM_ParentID": "",
"MM_Sort": 15,
"MM_Mark": null,
"MM_Ico": "",
"ResourceList": null
},
{
"GID": "9ebc0631-149e-4d07-927d-5da9aaea1656",
"MM_Name": "系统管理",
"MM_LinkUrl": "",
"MM_ParentID": "",
"MM_Sort": 20,
"MM_Mark": null,
"MM_Ico": "",
"ResourceList": null
},
{
"GID": "a9c87517-4da2-4f98-a5b9-35bf277fb375",
"MM_Name": "系统日志",
"MM_LinkUrl": "/WebUI/System/SystemLogList.html",
"MM_ParentID": "9ebc0631-149e-4d07-927d-5da9aaea1656",
"MM_Sort": 99,
"MM_Mark": null,
"MM_Ico": "",
"ResourceList": null
},
{
"GID": "2168612e-126c-4df3-a535-35fba7459c1a",
"MM_Name": "公共资源",
"MM_LinkUrl": "",
"MM_ParentID": "",
"MM_Sort": 100,
"MM_Mark": null,
"MM_Ico": "",
"ResourceList": null
}
]
}
}

21
data/api/run.ts Normal file
View File

@ -0,0 +1,21 @@
import { login } from "./login/request.js";
async function main() {
try {
console.log("--- 开始更新 API 响应数据 ---");
await login();
const { getWorkOrderList } = await import("./work_order_list/request.js");
const { getStatusCount } = await import("./status_count/request.js");
await Promise.all([getWorkOrderList(), getStatusCount()]);
console.log("--- 所有接口数据已更新 ---");
} catch (error: any) {
console.error("[ERROR]", error.message || error);
process.exit(1);
}
}
main();

View File

@ -0,0 +1,11 @@
import path from "path";
import { fileURLToPath } from "url";
import client, { saveResponse } from "../client.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export async function getStatusCount() {
const response = await client.post("/DemandManage/QueryIndexCount", {});
saveResponse(__dirname, response.data);
return response.data;
}

View File

@ -0,0 +1,10 @@
{
"success": true,
"code": null,
"msg": "执行成功",
"data": {
"PendingCount": 1,
"StaycloseCount": 0,
"ConfirmCount": 0
}
}

View File

@ -0,0 +1,18 @@
import path from "path";
import { fileURLToPath } from "url";
import client, { saveResponse } from "../client.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export async function getWorkOrderList() {
const response = await client.post("/DemandManage/GetWorkOrderListPage", {
isSelect: 8,
isShow: 3,
IsExport: 0,
PageIndex: 1,
PageSize: 20,
});
saveResponse(__dirname, response.data);
return response.data;
}

View File

@ -0,0 +1,58 @@
{
"success": true,
"code": null,
"msg": "执行成功",
"data": {
"PageTotal": 1,
"PageSize": 20,
"DataCount": 1,
"PageIndex": 1,
"DataList": [
{
"ID": 58624,
"DL_OrderType": 2,
"DL_Status": 350,
"DL_StatusID": null,
"DL_ProductID": 64,
"DL_ProductName": "六个羽友",
"DL_ID": 1039,
"DL_ItemID": "六个羽友2.21",
"DL_ProblemDegree": "1",
"DL_Priority": "1",
"DL_TaskName": "一次批量订场,立即支付页面转圈圈",
"DL_ProblemSource": "",
"DL_CreatorGID": "229707a9-8eac-4540-b1d0-f64ce87ce054",
"DL_Creator": "龚诚",
"DL_CreateTime": "2026-03-05 13:54:06",
"DL_AffirmGID": "229707a9-8eac-4540-b1d0-f64ce87ce054",
"DL_AffirmName": "龚诚",
"DL_ConfirmTime": null,
"DL_AffirmRemark": null,
"DL_AssignGID": "512860ad-aa4a-4268-a5d9-6c7d2e28680b",
"DL_AssignName": "A田森林",
"DL_AssignRemark": null,
"DL_SolveGID": null,
"DL_SolveName": null,
"DL_SolveTime": null,
"DL_SolveRemark": null,
"DL_CloseGID": null,
"DL_CloseName": null,
"DL_CloseTime": null,
"DL_CloseRemark": null,
"DL_Remark": null,
"DL_AuditStatus": null,
"DL_DemandContent": " <p class=\"txtContent\"><font color=\"#333333\">一次批量订场(32个场次),立即支付页面转圈圈</font></p><p class=\"txtContent\"><img src=\"https://img1.yunvip123.com/202603/134171636069619186.png\" style=\"max-width: 100% !important; vertical-align: middle !important;\"><img src=\"https://img1.yunvip123.com/202603/134171636323013515.png\" style=\"max-width: 100% !important; vertical-align: middle !important;\"></p><p class=\"txtContent\"></p>\n ",
"DL_TestContent": "",
"DL_DemandName": "一次批量订场,立即支付页面转圈圈",
"DL_OrderLevel": 50,
"DL_RepeatID": null,
"DL_RepeatStatus": null,
"DL_Identitying": null,
"DL_WorkHour": null,
"DL_ConfirmState": null
}
],
"StatisticsInfo": null,
"TrendData": null
}
}

File diff suppressed because it is too large Load Diff

39
data/deploy.js Normal file
View File

@ -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();

151
eslint.config.js Normal file
View File

@ -0,0 +1,151 @@
import js from "@eslint/js";
import prettier from "eslint-config-prettier";
import importPlugin, {
createNodeResolver,
flatConfigs,
} from "eslint-plugin-import-x";
import prettierPlugin from "eslint-plugin-prettier";
import vuePlugin from "eslint-plugin-vue";
import globals from "globals";
import ts from "typescript-eslint";
export default [
// 全局忽略
{
ignores: [
"**/node_modules/*",
"**/dist/*",
"build/",
"public/",
"docs/",
"bin/",
"pnpm-lock.yaml",
".vscode/",
".idea/",
".husky/",
"Dockerfile",
".hbuilderx/",
".vite/",
"uni_modules/",
"libs/",
"static/",
"patches/",
"wxcomponents/",
"lib/",
"scripts/",
"src-tauri/",
"**/*.bak.*",
],
},
// 应用推荐规则
js.configs.recommended,
...ts.configs.recommended,
// Vue 推荐规则
...vuePlugin.configs["flat/recommended"],
// prettier 必须在所有规则之后,关闭与 prettier 冲突的格式规则
prettier,
// 基础配置
{
files: ["**/*.{js,mjs,cjs,ts,vue}"],
plugins: { prettier: prettierPlugin, "import-x": importPlugin },
settings: {
"import-x/resolver-next": [
createNodeResolver(),
(
await import("eslint-import-resolver-typescript")
).createTypeScriptImportResolver({
project: ["tsconfig.json"],
}),
],
},
languageOptions: {
globals: {
...globals.node,
...globals.browser,
},
ecmaVersion: "latest",
sourceType: "module",
parserOptions: {
ecmaFeatures: {
impliedStrict: true,
},
},
},
rules: {
...flatConfigs.recommended.rules,
// Prettier 规则
"prettier/prettier": "warn",
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
// Import 规则
"import-x/no-self-import": "error",
"import-x/no-cycle": "error",
"import-x/no-useless-path-segments": "error",
"import-x/no-extraneous-dependencies": "error",
"import-x/no-mutable-exports": "error",
"import-x/no-named-as-default": "error",
"import-x/no-named-as-default-member": "error",
"import-x/no-duplicates": "warn",
"import-x/no-deprecated": "warn",
"import-x/newline-after-import": "warn",
"import-x/first": "warn",
"import-x/order": [
"warn",
{
groups: [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
"object",
"type",
],
alphabetize: {
order: "asc",
},
},
],
// TypeScript 宽松规则(对已有代码降级)
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-empty-object-type": "warn",
"@typescript-eslint/no-unused-vars": [
"warn",
{ varsIgnorePattern: "^_", argsIgnorePattern: "^_" },
],
},
},
// Vue 文件专属配置:在 script 块中使用 TypeScript 解析器
{
files: ["**/*.vue"],
languageOptions: {
parserOptions: {
parser: ts.parser,
extraFileExtensions: [".vue"],
sourceType: "module",
},
},
},
// 测试文件覆盖配置
{
files: ["**/__tests__/*.{j,t}s?(x)", "**/tests/unit/**/*.spec.{j,t}s?(x)"],
languageOptions: {
globals: {
...globals.mocha,
...globals.jest,
},
},
},
];

2107
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,71 @@
{
"name": "tauri-app",
"name": "work-order-monitor",
"private": true,
"version": "0.1.0",
"version": "0.2.3",
"type": "module",
"packageManager": "pnpm@9.15.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"tauri": "tauri",
"tauri-dev": "tauri dev",
"tauri-build": "tauri build"
"tauri-build": "node scripts/build.mjs",
"version": "node scripts/bump-version.mjs",
"version:patch": "node scripts/bump-version.mjs patch",
"version:minor": "node scripts/bump-version.mjs minor",
"version:major": "node scripts/bump-version.mjs major",
"publish": "node scripts/publish.mjs",
"deploy": "npm run tauri-build && npm run publish",
"type-check": "vue-tsc --noEmit",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"commit": "git-cz",
"preinstall": "npx only-allow pnpm",
"prepare": "husky"
},
"dependencies": {
"@ant-design/icons-vue": "^7.0.1",
"@tauri-apps/api": "^2.10.1",
"@tauri-apps/plugin-autostart": "^2.5.1",
"@tauri-apps/plugin-http": "^2.5.7",
"@tauri-apps/plugin-http": "^2.5.8",
"@tauri-apps/plugin-notification": "^2.3.3",
"@tauri-apps/plugin-opener": "^2.5.3",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-store": "^2.4.2",
"@tauri-apps/plugin-updater": "^2.10.1",
"ant-design-vue": "^4.2.6",
"dayjs": "^1.11.20",
"lodash-es": "^4.18.1",
"pinia": "^3.0.4",
"vue": "^3.5.29"
"vue": "^3.5.32",
"vue-router": "^4.6.4"
},
"devDependencies": {
"@tauri-apps/cli": "^2",
"@vitejs/plugin-vue": "^6.0.4",
"@commitlint/cli": "^20.5.0",
"@commitlint/config-conventional": "^20.5.0",
"@eslint/js": "^10.0.1",
"@tauri-apps/cli": "^2.10.1",
"@types/lodash-es": "^4.17.12",
"@vitejs/plugin-vue": "^6.0.6",
"axios": "^1.15.0",
"commitizen": "^4.3.1",
"cz-git": "^1.12.0",
"dotenv": "^17.4.2",
"eslint": "^10.2.0",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import-x": "^4.16.2",
"eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-vue": "^10.8.0",
"globals": "^17.5.0",
"husky": "^9.1.7",
"lint-staged": "^16.4.0",
"sass-embedded": "^1.99.0",
"tsx": "^4.21.0",
"typescript": "~5.9.3",
"vite": "^7.3.1",
"vue-tsc": "^3.2.5"
"typescript-eslint": "^8.58.2",
"vite": "^7.3.2",
"vue-tsc": "^3.2.6"
}
}

File diff suppressed because it is too large Load Diff

36
prettier.config.js Normal file
View File

@ -0,0 +1,36 @@
// https://prettier.io/docs/en/configuration.html
export default {
tabWidth: 4,
endOfLine: "lf",
overrides: [
{
files: [
"*.js",
"*.mjs",
"*.jsx",
"*.ts",
"*.tsx",
"*.vue",
"*.json",
"*.yml",
"*.yaml",
],
options: {
tabWidth: 2,
},
},
{
files: ["*.html", "*.vue", "*.json"],
options: {
printWidth: 120,
},
},
{
files: ["*.ps1"],
options: {
endOfLine: "crlf",
tabWidth: 4,
},
},
],
};

8
public/gong.svg Normal file
View File

@ -0,0 +1,8 @@
<svg width="256" height="256" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<rect stroke="#000" id="svg_2" height="256" width="259" y="1" x="-3" fill="#fff"/>
<text stroke-width="4" font-weight="normal" xml:space="preserve" text-anchor="start" font-family="'Alumni Sans'" font-size="128" id="svg_1" y="166.5" x="64" stroke="#000" fill="#000000"></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 393 B

24
scripts/build.mjs Normal file
View File

@ -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 });

103
scripts/bump-version.mjs Normal file
View File

@ -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");

120
scripts/publish.mjs Normal file
View File

@ -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);
}

267
src-tauri/Cargo.lock generated
View File

@ -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.0"
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.3"
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"

View File

@ -1,6 +1,6 @@
[package]
name = "tauri-app"
version = "0.1.0"
name = "work-order-monitor"
version = "0.2.3"
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 = [

View File

@ -1,45 +1,43 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"opener:default",
"notification:default",
{
"identifier": "http:default",
"allow": [
{ "url": "https://crm.yunvip123.com/**" },
{ "url": "https://www.baidu.com/**" }
]
},
{
"identifier": "http:allow-fetch",
"allow": [
{ "url": "https://crm.yunvip123.com/**" },
{ "url": "https://www.baidu.com/**" }
]
},
"http:allow-fetch-cancel",
"http:allow-fetch-read-body",
"http:allow-fetch-send",
"autostart:default",
"autostart:allow-enable",
"autostart:allow-disable",
"autostart:allow-is-enabled",
"core:tray:default",
"core:tray:allow-new",
"core:tray:allow-set-icon",
"core:tray:allow-set-menu",
"core:tray:allow-set-tooltip",
"core:window:allow-close",
"core:window:allow-destroy",
"core:window:allow-show",
"core:window:allow-hide",
"core:window:allow-set-focus",
"core:window:allow-unminimize",
"core:image:default",
"core:image:allow-from-path"
]
}
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"opener:default",
"notification:default",
{
"identifier": "http:default",
"allow": [{ "url": "https://crm.yunvip123.com/**" }, { "url": "https://www.baidu.com/**" }]
},
{
"identifier": "http:allow-fetch",
"allow": [{ "url": "https://crm.yunvip123.com/**" }, { "url": "https://www.baidu.com/**" }]
},
"http:allow-fetch-cancel",
"http:allow-fetch-read-body",
"http:allow-fetch-send",
"autostart:default",
"autostart:allow-enable",
"autostart:allow-disable",
"autostart:allow-is-enabled",
"core:tray:default",
"core:tray:allow-new",
"core:tray:allow-set-icon",
"core:tray:allow-set-menu",
"core:tray:allow-set-tooltip",
"core:window:allow-close",
"core:window:allow-destroy",
"core:window:allow-show",
"core:window:allow-hide",
"core:window:allow-set-focus",
"core:window:allow-set-title",
"core:window:allow-unminimize",
"core:image:default",
"core:image:allow-from-path",
"updater:default",
"process:allow-restart",
"store:default"
]
}

View File

@ -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()

View File

@ -1,4 +1,4 @@
package com.administrator.tauri_app
package com.yunpu.workordermonitor
import android.os.Bundle
import androidx.activity.enableEdgeToEdge

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 641 B

View File

@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 353 B

BIN
src-tauri/icons/64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 903 B

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Some files were not shown because too many files have changed in this diff Show More