feat: 添加新插件支持及多项功能改进

- 新增磁盘加密、打印审计和剪贴板管控插件支持
- 优化水印插件显示效果,支持中文及更多Unicode字符
- 改进硬件资产收集逻辑,更准确获取磁盘和显卡信息
- 增强API错误处理,添加详细日志记录
- 完善前端界面,新增插件管理页面
- 修复多个UI问题,优化页面过渡效果
- 添加环境变量覆盖配置功能
- 实现插件状态管理API
- 更新文档和变更日志
- 添加安装程序脚本支持
This commit is contained in:
iven
2026-04-10 22:21:05 +08:00
parent 3d39f0e426
commit b5333d8c93
101 changed files with 4487 additions and 661 deletions

View File

@@ -4,7 +4,7 @@ use tokio::sync::mpsc::Sender;
use tracing::{info, error};
pub async fn start_collecting(tx: Sender<Frame>, device_uid: String) {
let interval = Duration::from_secs(86400);
let interval = Duration::from_secs(43200);
if let Err(e) = collect_and_send(&tx, &device_uid).await {
error!("Initial asset collection failed: {}", e);
@@ -50,18 +50,14 @@ fn collect_hardware(device_uid: &str) -> anyhow::Result<HardwareAsset> {
// Memory
let memory_total_mb = sys.total_memory() / 1024 / 1024;
// Disk — pick the largest non-removable disk
// Disk — use PowerShell for real hardware model, sysinfo for total capacity
let disks = sysinfo::Disks::new_with_refreshed_list();
let (disk_model, disk_total_mb) = disks.iter()
.filter(|d| d.kind() == sysinfo::DiskKind::HDD || d.kind() == sysinfo::DiskKind::SSD)
.max_by_key(|d| d.total_space())
.map(|d| {
let total = d.total_space() / 1024 / 1024;
let name = d.name().to_string_lossy().to_string();
let model = if name.is_empty() { "Unknown".to_string() } else { name };
(model, total)
})
.unwrap_or_else(|| ("Unknown".to_string(), 0));
let disk_total_mb: u64 = disks.iter()
.map(|d| d.total_space() / 1024 / 1024)
.sum::<u64>()
.max(1)
.saturating_sub(1); // avoid reporting 0 if no disks
let disk_model = collect_disk_model().unwrap_or_else(|| "Unknown".to_string());
// GPU, motherboard, serial — Windows-specific via PowerShell
let (gpu_model, motherboard, serial_number) = collect_system_details();
@@ -81,12 +77,12 @@ fn collect_hardware(device_uid: &str) -> anyhow::Result<HardwareAsset> {
#[cfg(target_os = "windows")]
fn collect_system_details() -> (Option<String>, Option<String>, Option<String>) {
// GPU: query all controllers, filter out virtual/IDDDriver devices, prefer real GPU
// GPU: query all controllers, only exclude explicit virtual/placeholder devices
let gpu = {
let gpus = powershell_lines(
"Get-CimInstance Win32_VideoController | Where-Object { $_.Name -notmatch 'IddDriver|Virtual|Basic Render|Microsoft Basic Display|Remote Desktop|Mirror Driver' } | Select-Object -ExpandProperty Name"
"Get-CimInstance Win32_VideoController | Where-Object { $_.Name -notmatch 'IddDriver|Virtual Display|Basic Render|Microsoft Basic Display Adapter|Mirror Driver' } | Select-Object -ExpandProperty Name"
);
// Prefer NVIDIA/AMD/Intel, fallback to first non-virtual
info!("Detected GPUs: {:?}", gpus);
gpus.into_iter().next()
};
let mb_manufacturer = powershell_first("Get-CimInstance Win32_BaseBoard | Select-Object -ExpandProperty Manufacturer");
@@ -102,6 +98,20 @@ fn collect_system_details() -> (Option<String>, Option<String>, Option<String>)
(gpu, motherboard, serial_number)
}
/// Get real disk hardware model via PowerShell Get-PhysicalDisk.
#[cfg(target_os = "windows")]
fn collect_disk_model() -> Option<String> {
let models = powershell_lines(
"Get-PhysicalDisk | Select-Object -ExpandProperty FriendlyName"
);
models.into_iter().next()
}
#[cfg(not(target_os = "windows"))]
fn collect_disk_model() -> Option<String> {
None
}
#[cfg(not(target_os = "windows"))]
fn collect_system_details() -> (Option<String>, Option<String>, Option<String>) {
(None, None, None)
@@ -150,6 +160,7 @@ fn collect_windows_software(device_uid: &str) -> Vec<SoftwareAsset> {
use std::process::Command;
let ps_cmd = r#"
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$paths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",