feat: 初始化项目基础架构和核心功能

- 添加项目基础结构:Cargo.toml、.gitignore、设备UID和密钥文件
- 实现前端Vue3项目结构:路由、登录页面、设备管理页面
- 添加核心协议定义(crates/protocol):设备状态、资产、USB事件等
- 实现客户端监控模块:系统状态收集、资产收集
- 实现服务端基础API和插件系统
- 添加数据库迁移脚本:设备管理、资产跟踪、告警系统等
- 实现前端设备状态展示和基本交互
- 添加使用时长统计和水印功能插件
This commit is contained in:
iven
2026-04-05 00:57:51 +08:00
commit fd6fb5cca0
87 changed files with 19576 additions and 0 deletions

70
migrations/001_init.sql Normal file
View File

@@ -0,0 +1,70 @@
-- 001_init.sql: Core tables (users, devices, device_status)
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'admin' CHECK(role IN ('admin', 'viewer')),
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS devices (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL UNIQUE,
hostname TEXT NOT NULL,
ip_address TEXT NOT NULL,
mac_address TEXT,
os_version TEXT,
client_version TEXT,
device_secret TEXT, -- HMAC key for message authentication
status TEXT NOT NULL DEFAULT 'offline' CHECK(status IN ('online', 'offline')),
last_heartbeat TEXT,
registered_at TEXT NOT NULL DEFAULT (datetime('now')),
group_name TEXT DEFAULT 'default'
);
CREATE TABLE IF NOT EXISTS device_status (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
cpu_usage REAL,
memory_usage REAL,
memory_total_mb INTEGER,
disk_usage REAL,
disk_total_mb INTEGER,
network_rx_rate INTEGER,
network_tx_rate INTEGER,
running_procs INTEGER,
top_processes TEXT,
reported_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
UNIQUE(device_uid)
);
CREATE TABLE IF NOT EXISTS device_status_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
cpu_usage REAL,
memory_usage REAL,
disk_usage REAL,
network_rx_rate INTEGER,
network_tx_rate INTEGER,
running_procs INTEGER,
reported_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS device_groups (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
parent_id INTEGER REFERENCES device_groups(id),
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Insert default group
INSERT OR IGNORE INTO device_groups (name, description) VALUES ('default', 'Default device group');
-- Indexes
CREATE INDEX IF NOT EXISTS idx_devices_status ON devices(status);
CREATE INDEX IF NOT EXISTS idx_device_status_uid ON device_status(device_uid);
CREATE INDEX IF NOT EXISTS idx_status_history_device_time ON device_status_history(device_uid, reported_at);
CREATE INDEX IF NOT EXISTS idx_status_history_time ON device_status_history(reported_at);

42
migrations/002_assets.sql Normal file
View File

@@ -0,0 +1,42 @@
-- 002_assets.sql: Asset management tables
CREATE TABLE IF NOT EXISTS hardware_assets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
cpu_model TEXT,
cpu_cores INTEGER,
memory_total_mb INTEGER,
disk_model TEXT,
disk_total_mb INTEGER,
gpu_model TEXT,
motherboard TEXT,
serial_number TEXT,
reported_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
UNIQUE(device_uid)
);
CREATE TABLE IF NOT EXISTS software_assets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
name TEXT NOT NULL,
version TEXT,
publisher TEXT,
install_date TEXT,
install_path TEXT,
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
UNIQUE(device_uid, name, version)
);
CREATE TABLE IF NOT EXISTS asset_changes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
change_type TEXT NOT NULL CHECK(change_type IN ('hardware', 'software_added', 'software_removed')),
change_detail TEXT NOT NULL,
detected_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_software_device ON software_assets(device_uid);
CREATE INDEX IF NOT EXISTS idx_asset_changes_time ON asset_changes(detected_at);
CREATE INDEX IF NOT EXISTS idx_asset_changes_device ON asset_changes(device_uid);

28
migrations/003_usb.sql Normal file
View File

@@ -0,0 +1,28 @@
-- 003_usb.sql: USB control tables
CREATE TABLE IF NOT EXISTS usb_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
vendor_id TEXT,
product_id TEXT,
serial_number TEXT,
device_name TEXT,
event_type TEXT NOT NULL CHECK(event_type IN ('inserted', 'removed', 'blocked')),
event_time TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS usb_policies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
policy_type TEXT NOT NULL CHECK(policy_type IN ('all_block', 'whitelist', 'blacklist')),
target_group TEXT,
rules TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_usb_events_device_time ON usb_events(device_uid, event_time);
CREATE INDEX IF NOT EXISTS idx_usb_events_time ON usb_events(event_time);
CREATE INDEX IF NOT EXISTS idx_usb_policies_target ON usb_policies(target_group);

46
migrations/004_alerts.sql Normal file
View File

@@ -0,0 +1,46 @@
-- 004_alerts.sql: Alert system tables
CREATE TABLE IF NOT EXISTS alert_rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
rule_type TEXT NOT NULL CHECK(rule_type IN ('device_offline', 'cpu_high', 'memory_high', 'disk_high', 'usb_unauthorized', 'usb_unauth', 'asset_change')),
condition TEXT NOT NULL,
severity TEXT NOT NULL DEFAULT 'medium' CHECK(severity IN ('low', 'medium', 'high', 'critical')),
enabled INTEGER NOT NULL DEFAULT 1,
notify_email TEXT,
notify_webhook TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS alert_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
rule_id INTEGER REFERENCES alert_rules(id),
device_uid TEXT REFERENCES devices(device_uid) ON DELETE SET NULL,
alert_type TEXT NOT NULL,
severity TEXT NOT NULL DEFAULT 'medium' CHECK(severity IN ('low', 'medium', 'high', 'critical')),
detail TEXT NOT NULL,
handled INTEGER NOT NULL DEFAULT 0,
handled_by TEXT,
handled_at TEXT,
triggered_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Admin audit log
CREATE TABLE IF NOT EXISTS admin_audit_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id),
action TEXT NOT NULL,
target_type TEXT,
target_id TEXT,
detail TEXT,
ip_address TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_alert_records_time ON alert_records(triggered_at);
CREATE INDEX IF NOT EXISTS idx_alert_records_device ON alert_records(device_uid, triggered_at);
CREATE INDEX IF NOT EXISTS idx_alert_records_unhandled ON alert_records(handled) WHERE handled = 0;
CREATE INDEX IF NOT EXISTS idx_audit_log_user_time ON admin_audit_log(user_id, created_at);
CREATE INDEX IF NOT EXISTS idx_audit_log_time ON admin_audit_log(created_at);

View File

@@ -0,0 +1,23 @@
-- 005_plugins_web_filter.sql: Web Filter plugin (上网拦截)
CREATE TABLE IF NOT EXISTS web_filter_rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
rule_type TEXT NOT NULL CHECK(rule_type IN ('blacklist', 'whitelist', 'category')),
pattern TEXT NOT NULL,
target_type TEXT NOT NULL DEFAULT 'global' CHECK(target_type IN ('global', 'group', 'device')),
target_id TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS web_access_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
url TEXT NOT NULL,
action TEXT NOT NULL CHECK(action IN ('allowed', 'blocked')),
timestamp TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_web_filter_rules_type ON web_filter_rules(rule_type, enabled);
CREATE INDEX IF NOT EXISTS idx_web_access_log_device_time ON web_access_log(device_uid, timestamp);
CREATE INDEX IF NOT EXISTS idx_web_access_log_time ON web_access_log(timestamp);

View File

@@ -0,0 +1,24 @@
-- 006_plugins_usage_timer.sql: Usage Timer plugin (时长记录)
CREATE TABLE IF NOT EXISTS usage_daily (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
date TEXT NOT NULL,
total_active_minutes INTEGER NOT NULL DEFAULT 0,
total_idle_minutes INTEGER NOT NULL DEFAULT 0,
first_active_at TEXT,
last_active_at TEXT,
UNIQUE(device_uid, date)
);
CREATE TABLE IF NOT EXISTS app_usage_daily (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
date TEXT NOT NULL,
app_name TEXT NOT NULL,
usage_minutes INTEGER NOT NULL DEFAULT 0,
UNIQUE(device_uid, date, app_name)
);
CREATE INDEX IF NOT EXISTS idx_usage_daily_date ON usage_daily(date);
CREATE INDEX IF NOT EXISTS idx_app_usage_daily_date ON app_usage_daily(date);

View File

@@ -0,0 +1,24 @@
-- 007_plugins_software_blocker.sql: Software Blocker plugin (软件禁止安装)
CREATE TABLE IF NOT EXISTS software_blacklist (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name_pattern TEXT NOT NULL,
category TEXT CHECK(category IN ('game', 'social', 'vpn', 'mining', 'custom')),
action TEXT NOT NULL DEFAULT 'block' CHECK(action IN ('block', 'alert')),
target_type TEXT NOT NULL DEFAULT 'global' CHECK(target_type IN ('global', 'group', 'device')),
target_id TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS software_violations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
software_name TEXT NOT NULL,
action_taken TEXT NOT NULL CHECK(action_taken IN ('blocked_install', 'auto_uninstalled', 'alerted')),
timestamp TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_software_blacklist_enabled ON software_blacklist(enabled);
CREATE INDEX IF NOT EXISTS idx_software_violations_device ON software_violations(device_uid, timestamp);
CREATE INDEX IF NOT EXISTS idx_software_violations_time ON software_violations(timestamp);

View File

@@ -0,0 +1,23 @@
-- 008_plugins_popup_blocker.sql: Popup Blocker plugin (弹窗拦截)
CREATE TABLE IF NOT EXISTS popup_filter_rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
rule_type TEXT NOT NULL CHECK(rule_type IN ('block', 'allow')),
window_title TEXT,
window_class TEXT,
process_name TEXT,
target_type TEXT NOT NULL DEFAULT 'global' CHECK(target_type IN ('global', 'group', 'device')),
target_id TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS popup_block_stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
blocked_count INTEGER NOT NULL DEFAULT 0,
date TEXT NOT NULL,
UNIQUE(device_uid, date)
);
CREATE INDEX IF NOT EXISTS idx_popup_rules_enabled ON popup_filter_rules(rule_type, enabled);

View File

@@ -0,0 +1,16 @@
-- 009_plugins_usb_file_audit.sql: USB File Audit plugin (U盘文件操作记录)
CREATE TABLE IF NOT EXISTS usb_file_operations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_uid TEXT NOT NULL REFERENCES devices(device_uid) ON DELETE CASCADE,
usb_serial TEXT,
drive_letter TEXT,
operation TEXT NOT NULL CHECK(operation IN ('create', 'delete', 'rename', 'modify')),
file_path TEXT NOT NULL,
file_size INTEGER,
timestamp TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_usb_file_ops_device ON usb_file_operations(device_uid, timestamp);
CREATE INDEX IF NOT EXISTS idx_usb_file_ops_time ON usb_file_operations(timestamp);
CREATE INDEX IF NOT EXISTS idx_usb_file_ops_usb ON usb_file_operations(usb_serial, timestamp);

View File

@@ -0,0 +1,27 @@
-- 010_plugins_watermark.sql: Screen Watermark plugin (水印管理)
CREATE TABLE IF NOT EXISTS watermark_config (
id INTEGER PRIMARY KEY AUTOINCREMENT,
target_type TEXT NOT NULL DEFAULT 'global' CHECK(target_type IN ('global', 'group', 'device')),
target_id TEXT,
content TEXT NOT NULL DEFAULT '公司名称 | {username} | {date}',
font_size INTEGER NOT NULL DEFAULT 14,
opacity REAL NOT NULL DEFAULT 0.15,
color TEXT NOT NULL DEFAULT '#808080',
angle INTEGER NOT NULL DEFAULT -30,
enabled INTEGER NOT NULL DEFAULT 1,
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Plugin enable/disable state per device group
CREATE TABLE IF NOT EXISTS plugin_state (
id INTEGER PRIMARY KEY AUTOINCREMENT,
plugin_name TEXT NOT NULL UNIQUE CHECK(plugin_name IN (
'web_filter', 'usage_timer', 'software_blocker',
'popup_blocker', 'usb_file_audit', 'watermark'
)),
enabled INTEGER NOT NULL DEFAULT 0,
target_type TEXT NOT NULL DEFAULT 'global',
target_id TEXT,
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);

View File

@@ -0,0 +1,18 @@
-- 011_token_security.sql: Token rotation and revocation tracking
CREATE TABLE IF NOT EXISTS revoked_token_families (
family TEXT NOT NULL PRIMARY KEY,
user_id INTEGER NOT NULL,
revoked_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS refresh_tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
family TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
expires_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_revoked_families_user ON revoked_token_families(user_id);
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id);