pull/3/head
commit
b20c5ad72d
@ -1,152 +0,0 @@
|
||||
-- CasualtySightPlus 数据库表结构
|
||||
-- 数据库: Client
|
||||
-- 创建日期: 2025-06-18
|
||||
|
||||
USE Client;
|
||||
|
||||
-- 1. UAV设备表 (无人机)
|
||||
CREATE TABLE IF NOT EXISTS uav_devices (
|
||||
id VARCHAR(50) PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL DEFAULT 'UAV设备',
|
||||
state INT DEFAULT 0 COMMENT '设备状态: 0=离线, 1=在线, 2=工作中, 3=错误',
|
||||
ip VARCHAR(15),
|
||||
port INT,
|
||||
longitude DOUBLE,
|
||||
latitude DOUBLE,
|
||||
signal_strength INT DEFAULT 0 COMMENT '信号强度 0-100',
|
||||
last_heartbeat TIMESTAMP NULL COMMENT '最后心跳时间',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_state (state),
|
||||
INDEX idx_location (longitude, latitude)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='无人机设备表';
|
||||
|
||||
-- 2. Dog机器人表 (地面机器人)
|
||||
CREATE TABLE IF NOT EXISTS dog_devices (
|
||||
id VARCHAR(50) PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL DEFAULT '地面机器人',
|
||||
state INT DEFAULT 0 COMMENT '设备状态: 0=离线, 1=在线, 2=工作中, 3=错误',
|
||||
ip VARCHAR(15),
|
||||
port INT,
|
||||
longitude DOUBLE,
|
||||
latitude DOUBLE,
|
||||
signal_strength INT DEFAULT 0 COMMENT '信号强度 0-100',
|
||||
last_heartbeat TIMESTAMP NULL COMMENT '最后心跳时间',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_state (state),
|
||||
INDEX idx_location (longitude, latitude)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='地面机器人设备表';
|
||||
|
||||
-- 3. 伤员记录表
|
||||
CREATE TABLE IF NOT EXISTS injury_records (
|
||||
id VARCHAR(50) PRIMARY KEY,
|
||||
rank INT COMMENT '伤员等级',
|
||||
longitude DOUBLE,
|
||||
latitude DOUBLE,
|
||||
flag INT DEFAULT 1 COMMENT '有效标志: 0=无效, 1=有效',
|
||||
severity INT DEFAULT 0 COMMENT '严重程度: 0=轻微, 1=中等, 2=严重, 3=危重',
|
||||
description TEXT COMMENT '伤情描述',
|
||||
discovered_by VARCHAR(50) COMMENT '发现设备ID',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_flag (flag),
|
||||
INDEX idx_severity (severity),
|
||||
INDEX idx_location (longitude, latitude)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='伤员记录表';
|
||||
|
||||
-- 4. 系统配置表
|
||||
CREATE TABLE IF NOT EXISTS system_config (
|
||||
config_key VARCHAR(100) PRIMARY KEY,
|
||||
config_value TEXT,
|
||||
config_type VARCHAR(20) DEFAULT 'string' COMMENT '配置类型: string, int, float, boolean, json',
|
||||
description VARCHAR(500),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表';
|
||||
|
||||
-- 5. 用户会话表
|
||||
CREATE TABLE IF NOT EXISTS user_sessions (
|
||||
session_id VARCHAR(100) PRIMARY KEY,
|
||||
user_name VARCHAR(50),
|
||||
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
ip_address VARCHAR(45),
|
||||
user_agent TEXT,
|
||||
status INT DEFAULT 1 COMMENT '会话状态: 0=已注销, 1=活跃',
|
||||
INDEX idx_user (user_name),
|
||||
INDEX idx_status (status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户会话表';
|
||||
|
||||
-- 6. 设备操作日志表
|
||||
CREATE TABLE IF NOT EXISTS device_operation_logs (
|
||||
log_id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
device_id VARCHAR(50),
|
||||
device_type VARCHAR(20) COMMENT '设备类型: uav, dog',
|
||||
operation VARCHAR(50) COMMENT '操作类型: connect, disconnect, control, move',
|
||||
operation_result VARCHAR(20) DEFAULT 'success' COMMENT '操作结果: success, failed, timeout',
|
||||
operator VARCHAR(50) COMMENT '操作员',
|
||||
operation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
details JSON COMMENT '操作详细信息',
|
||||
INDEX idx_device (device_id),
|
||||
INDEX idx_operation_time (operation_time),
|
||||
INDEX idx_device_type (device_type)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设备操作日志表';
|
||||
|
||||
-- 插入默认系统配置
|
||||
INSERT INTO system_config (config_key, config_value, config_type, description) VALUES
|
||||
('app.version', '2.0.0', 'string', '应用程序版本'),
|
||||
('app.theme', 'military', 'string', '默认主题'),
|
||||
('database.connection_timeout', '30000', 'int', '数据库连接超时时间(毫秒)'),
|
||||
('ui.auto_refresh_interval', '5000', 'int', '界面自动刷新间隔(毫秒)'),
|
||||
('ui.device_card_style', 'modern', 'string', '设备卡片样式'),
|
||||
('map.default_center_lat', '39.9', 'float', '地图默认中心纬度'),
|
||||
('map.default_center_lon', '116.4', 'float', '地图默认中心经度'),
|
||||
('map.default_zoom', '12', 'int', '地图默认缩放级别'),
|
||||
('device.heartbeat_interval', '10000', 'int', '设备心跳间隔(毫秒)'),
|
||||
('device.connection_timeout', '30000', 'int', '设备连接超时(毫秒)')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
config_value = VALUES(config_value),
|
||||
updated_at = CURRENT_TIMESTAMP;
|
||||
|
||||
-- 为兼容现有代码,创建旧表名的视图
|
||||
CREATE OR REPLACE VIEW uavdatabase AS
|
||||
SELECT
|
||||
id,
|
||||
state,
|
||||
ip,
|
||||
port,
|
||||
longitude as lon,
|
||||
latitude as lat
|
||||
FROM uav_devices;
|
||||
|
||||
CREATE OR REPLACE VIEW dogdatabase AS
|
||||
SELECT
|
||||
id,
|
||||
state,
|
||||
ip,
|
||||
port,
|
||||
longitude as lon,
|
||||
latitude as lat
|
||||
FROM dog_devices;
|
||||
|
||||
CREATE OR REPLACE VIEW injurydatabase AS
|
||||
SELECT
|
||||
id,
|
||||
rank as injuryrank,
|
||||
longitude as lon,
|
||||
latitude as lat,
|
||||
flag
|
||||
FROM injury_records;
|
||||
|
||||
-- 显示创建的表
|
||||
SHOW TABLES;
|
||||
|
||||
-- 显示表结构概要
|
||||
SELECT
|
||||
TABLE_NAME as '表名',
|
||||
TABLE_COMMENT as '说明',
|
||||
TABLE_ROWS as '记录数'
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = 'Client'
|
||||
ORDER BY TABLE_NAME;
|
@ -1,486 +0,0 @@
|
||||
# CasualtySightPlus 项目结构重构规划
|
||||
|
||||
## 当前项目结构分析
|
||||
|
||||
### 现有目录结构
|
||||
```
|
||||
Client/
|
||||
├── include/ # 头文件目录
|
||||
│ ├── DogDatabase.h
|
||||
│ ├── InjuryAnalysisUI.h
|
||||
│ ├── InjuryDatabase.h
|
||||
│ ├── UAVDatabase.h
|
||||
│ ├── guidingui.h
|
||||
│ └── injurydisiplayui.h
|
||||
├── src/ # 源码目录
|
||||
│ ├── DogDatabase.cpp
|
||||
│ ├── InjuryAnalysisUI.cpp
|
||||
│ ├── InjuryDatabase.cpp
|
||||
│ ├── UAVDatabase.cpp
|
||||
│ ├── guidingui.cpp
|
||||
│ ├── injurydisiplayui.cpp
|
||||
│ └── main.cpp
|
||||
├── ui/ # UI表单文件
|
||||
│ ├── InjuryAnalysisUI.ui
|
||||
│ ├── guidingui.ui
|
||||
│ └── injurydisiplayui.ui
|
||||
├── res/ # 资源文件
|
||||
│ ├── html/
|
||||
│ ├── icon/
|
||||
│ ├── image/
|
||||
│ └── qml/
|
||||
├── build/ # 构建目录
|
||||
└── AudioModule/ # 音频模块
|
||||
```
|
||||
|
||||
### 现有数据库架构分析
|
||||
|
||||
#### 1. UAVDatabase (无人机数据库)
|
||||
- **连接方式**: 已使用MySQL (`QMYSQL`)
|
||||
- **表结构**: `uavdatabase` 表
|
||||
- id (VARCHAR)
|
||||
- state (INT)
|
||||
- ip (VARCHAR)
|
||||
- port (INT)
|
||||
- lon (DOUBLE)
|
||||
- lat (DOUBLE)
|
||||
- **连接信息**: 数据库名: `fly_land_database`, 用户: `root`
|
||||
|
||||
#### 2. DogDatabase (地面机器人数据库)
|
||||
- **连接方式**: 已使用MySQL (`QMYSQL`)
|
||||
- **表结构**: `dogdatabase` 表
|
||||
- id (VARCHAR)
|
||||
- state (INT)
|
||||
- ip (VARCHAR)
|
||||
- port (INT)
|
||||
- lon (DOUBLE)
|
||||
- lat (DOUBLE)
|
||||
- **单例模式**: 线程安全实现
|
||||
|
||||
#### 3. InjuryDatabase (伤员信息数据库)
|
||||
- **连接方式**: 已使用MySQL (`QMYSQL`)
|
||||
- **表结构**: `injurydatabase` 表
|
||||
- id (VARCHAR)
|
||||
- injuryrank (INT)
|
||||
- lon (DOUBLE)
|
||||
- lat (DOUBLE)
|
||||
- flag (INT)
|
||||
|
||||
## 重构后的项目结构规划
|
||||
|
||||
### 新的目录结构
|
||||
```
|
||||
Client/
|
||||
├── src/
|
||||
│ ├── core/ # 核心业务逻辑
|
||||
│ │ ├── database/ # 数据库层
|
||||
│ │ │ ├── managers/ # 数据库管理器
|
||||
│ │ │ ├── models/ # 数据模型
|
||||
│ │ │ └── connections/ # 连接管理
|
||||
│ │ ├── services/ # 业务服务层
|
||||
│ │ └── utils/ # 工具类
|
||||
│ ├── ui/ # 用户界面层
|
||||
│ │ ├── main/ # 主界面
|
||||
│ │ ├── components/ # 可复用组件
|
||||
│ │ │ ├── DeviceCard/ # 设备卡片组件
|
||||
│ │ │ ├── StatusPanel/ # 状态面板组件
|
||||
│ │ │ └── MapViewer/ # 地图显示组件
|
||||
│ │ ├── dialogs/ # 对话框
|
||||
│ │ └── widgets/ # 自定义Widget
|
||||
│ ├── resources/ # 资源文件
|
||||
│ │ ├── styles/ # 样式文件
|
||||
│ │ ├── themes/ # 主题配置
|
||||
│ │ ├── images/ # 图片资源
|
||||
│ │ ├── icons/ # 图标资源
|
||||
│ │ ├── qml/ # QML文件
|
||||
│ │ └── html/ # HTML文件
|
||||
│ └── main.cpp
|
||||
├── include/ # 公共头文件
|
||||
├── forms/ # UI表单文件 (.ui)
|
||||
├── build/ # 构建输出目录
|
||||
├── config/ # 配置文件
|
||||
├── docs/ # 项目文档
|
||||
├── tests/ # 测试文件
|
||||
└── scripts/ # 构建脚本
|
||||
```
|
||||
|
||||
### 数据库层重构规划
|
||||
|
||||
#### 1. 连接管理器 (ConnectionManager)
|
||||
```cpp
|
||||
// src/core/database/connections/ConnectionManager.h
|
||||
class ConnectionManager {
|
||||
public:
|
||||
static ConnectionManager* getInstance();
|
||||
QSqlDatabase getConnection(const QString& connectionName = "default");
|
||||
bool initialize(const DatabaseConfig& config);
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
QMap<QString, QSqlDatabase> m_connections;
|
||||
DatabaseConfig m_config;
|
||||
};
|
||||
```
|
||||
|
||||
#### 2. 数据库配置管理
|
||||
```cpp
|
||||
// src/core/database/DatabaseConfig.h
|
||||
struct DatabaseConfig {
|
||||
QString host = "localhost";
|
||||
int port = 3306;
|
||||
QString database = "fly_land_database";
|
||||
QString username = "root";
|
||||
QString password;
|
||||
int maxConnections = 10;
|
||||
int connectionTimeout = 30000;
|
||||
};
|
||||
```
|
||||
|
||||
#### 3. 基础数据访问对象 (BaseDAO)
|
||||
```cpp
|
||||
// src/core/database/BaseDAO.h
|
||||
template<typename T>
|
||||
class BaseDAO {
|
||||
public:
|
||||
virtual bool insert(const T& entity) = 0;
|
||||
virtual bool update(const T& entity) = 0;
|
||||
virtual bool deleteById(const QString& id) = 0;
|
||||
virtual T findById(const QString& id) = 0;
|
||||
virtual QList<T> findAll() = 0;
|
||||
virtual QList<T> findByCondition(const QString& condition) = 0;
|
||||
|
||||
protected:
|
||||
QSqlDatabase getDatabase();
|
||||
bool executeQuery(const QString& sql, const QVariantList& params = {});
|
||||
};
|
||||
```
|
||||
|
||||
#### 4. 改进的数据模型
|
||||
```cpp
|
||||
// src/core/database/models/UAVModel.h
|
||||
struct UAVModel {
|
||||
QString id;
|
||||
QString name;
|
||||
int state;
|
||||
QString ip;
|
||||
int port;
|
||||
double longitude;
|
||||
double latitude;
|
||||
int signalStrength;
|
||||
QDateTime lastHeartbeat;
|
||||
QDateTime createdAt;
|
||||
QDateTime updatedAt;
|
||||
|
||||
// 序列化支持
|
||||
QJsonObject toJson() const;
|
||||
static UAVModel fromJson(const QJsonObject& json);
|
||||
};
|
||||
```
|
||||
|
||||
### UI组件重构规划
|
||||
|
||||
#### 1. 设备卡片组件 (DeviceCard)
|
||||
```cpp
|
||||
// src/ui/components/DeviceCard/DeviceCard.h
|
||||
class DeviceCard : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeviceCard(QWidget* parent = nullptr);
|
||||
void setDevice(const DeviceInfo& device);
|
||||
void updateStatus(DeviceStatus status);
|
||||
void setCardStyle(CardStyle style);
|
||||
|
||||
signals:
|
||||
void deviceSelected(const QString& deviceId);
|
||||
void controlRequested(const QString& deviceId);
|
||||
void locationRequested(const QString& deviceId);
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
void updateStatusIndicator();
|
||||
void applyCardStyle();
|
||||
|
||||
private:
|
||||
DeviceInfo m_device;
|
||||
QLabel* m_nameLabel;
|
||||
QLabel* m_statusLabel;
|
||||
QLabel* m_ipLabel;
|
||||
QLabel* m_locationLabel;
|
||||
QProgressBar* m_signalBar;
|
||||
QPushButton* m_detailsBtn;
|
||||
QPushButton* m_controlBtn;
|
||||
QPushButton* m_locateBtn;
|
||||
};
|
||||
```
|
||||
|
||||
#### 2. 状态面板组件 (StatusPanel)
|
||||
```cpp
|
||||
// src/ui/components/StatusPanel/StatusPanel.h
|
||||
class StatusPanel : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit StatusPanel(QWidget* parent = nullptr);
|
||||
void addStatusItem(const QString& name, const QVariant& value);
|
||||
void updateStatusItem(const QString& name, const QVariant& value);
|
||||
void setUpdateInterval(int msec);
|
||||
|
||||
private slots:
|
||||
void refreshStatus();
|
||||
|
||||
private:
|
||||
QTimer* m_refreshTimer;
|
||||
QMap<QString, QLabel*> m_statusLabels;
|
||||
QVBoxLayout* m_layout;
|
||||
};
|
||||
```
|
||||
|
||||
#### 3. 主界面重构 (MainWindow)
|
||||
```cpp
|
||||
// src/ui/main/MainWindow.h
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void onDeviceSelected(const QString& deviceId);
|
||||
void onStatusChanged(const QString& deviceId, DeviceStatus status);
|
||||
void refreshDeviceList();
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
void setupMenus();
|
||||
void setupStatusBar();
|
||||
void setupDockWidgets();
|
||||
void connectSignals();
|
||||
|
||||
private:
|
||||
DeviceListWidget* m_deviceList;
|
||||
MapViewerWidget* m_mapViewer;
|
||||
StatusPanel* m_statusPanel;
|
||||
QDockWidget* m_deviceDock;
|
||||
QDockWidget* m_statusDock;
|
||||
};
|
||||
```
|
||||
|
||||
### 样式系统规划
|
||||
|
||||
#### 1. 主题管理器 (ThemeManager)
|
||||
```cpp
|
||||
// src/core/ui/ThemeManager.h
|
||||
class ThemeManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Theme { Light, Dark, Military };
|
||||
|
||||
static ThemeManager* getInstance();
|
||||
void setTheme(Theme theme);
|
||||
Theme currentTheme() const;
|
||||
QString getStyleSheet(const QString& component) const;
|
||||
|
||||
signals:
|
||||
void themeChanged(Theme theme);
|
||||
|
||||
private:
|
||||
void loadTheme(Theme theme);
|
||||
QMap<QString, QString> m_styleSheets;
|
||||
Theme m_currentTheme;
|
||||
};
|
||||
```
|
||||
|
||||
#### 2. 样式配置文件结构
|
||||
```
|
||||
src/resources/styles/
|
||||
├── themes/
|
||||
│ ├── dark.qss # 深色主题
|
||||
│ ├── light.qss # 浅色主题
|
||||
│ └── military.qss # 军事主题
|
||||
├── components/
|
||||
│ ├── device_card.qss # 设备卡片样式
|
||||
│ ├── status_panel.qss # 状态面板样式
|
||||
│ ├── main_window.qss # 主窗口样式
|
||||
│ └── buttons.qss # 按钮样式
|
||||
└── common/
|
||||
├── colors.qss # 颜色定义
|
||||
├── fonts.qss # 字体定义
|
||||
└── animations.qss # 动画效果
|
||||
```
|
||||
|
||||
## 配置文件管理
|
||||
|
||||
### 1. 应用配置 (AppConfig)
|
||||
```json
|
||||
// config/app.json
|
||||
{
|
||||
"application": {
|
||||
"name": "CasualtySightPlus",
|
||||
"version": "2.0.0",
|
||||
"theme": "military",
|
||||
"language": "zh_CN"
|
||||
},
|
||||
"database": {
|
||||
"host": "localhost",
|
||||
"port": 3306,
|
||||
"name": "fly_land_database",
|
||||
"username": "root",
|
||||
"pool_size": 10,
|
||||
"connection_timeout": 30000
|
||||
},
|
||||
"ui": {
|
||||
"window_size": [1400, 900],
|
||||
"device_card_style": "modern",
|
||||
"auto_refresh_interval": 5000,
|
||||
"animation_enabled": true
|
||||
},
|
||||
"map": {
|
||||
"default_center": [39.9, 116.4],
|
||||
"default_zoom": 12,
|
||||
"tile_server": "amap"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 设备模板配置
|
||||
```json
|
||||
// config/device_templates.json
|
||||
{
|
||||
"uav_templates": [
|
||||
{
|
||||
"name": "侦察机模板",
|
||||
"type": "reconnaissance",
|
||||
"default_settings": {
|
||||
"max_altitude": 500,
|
||||
"max_speed": 50,
|
||||
"camera_resolution": "1080p"
|
||||
}
|
||||
}
|
||||
],
|
||||
"robot_templates": [
|
||||
{
|
||||
"name": "巡逻机器人模板",
|
||||
"type": "patrol",
|
||||
"default_settings": {
|
||||
"max_speed": 5,
|
||||
"sensor_range": 50,
|
||||
"battery_capacity": 8000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 构建系统改进
|
||||
|
||||
### 1. 更新的 .pro 文件结构
|
||||
```pro
|
||||
# CasualtySightPlus.pro
|
||||
QT += core gui widgets quickwidgets positioning
|
||||
QT += multimedia multimediawidgets
|
||||
QT += webenginewidgets webchannel
|
||||
QT += sql charts network
|
||||
|
||||
CONFIG += c++17
|
||||
|
||||
# 版本信息
|
||||
VERSION = 2.0.0
|
||||
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
|
||||
|
||||
# 包含路径
|
||||
INCLUDEPATH += \
|
||||
include \
|
||||
src/core \
|
||||
src/ui \
|
||||
AudioModule
|
||||
|
||||
# 构建目录
|
||||
OBJECTS_DIR = build/obj
|
||||
MOC_DIR = build/moc
|
||||
UI_DIR = build/ui
|
||||
RCC_DIR = build/rcc
|
||||
DESTDIR = build/bin
|
||||
|
||||
# 预编译头文件
|
||||
PRECOMPILED_HEADER = src/core/pch.h
|
||||
|
||||
# 源文件组织
|
||||
include(src/core/core.pri)
|
||||
include(src/ui/ui.pri)
|
||||
include(AudioModule/audio.pri)
|
||||
|
||||
# 资源文件
|
||||
RESOURCES += \
|
||||
resources/resources.qrc \
|
||||
resources/styles/styles.qrc \
|
||||
resources/themes/themes.qrc
|
||||
|
||||
# 安装规则
|
||||
target.path = /opt/CasualtySightPlus/bin
|
||||
config.files = config/*
|
||||
config.path = /opt/CasualtySightPlus/config
|
||||
INSTALLS += target config
|
||||
```
|
||||
|
||||
### 2. 模块化 .pri 文件
|
||||
```pro
|
||||
# src/core/core.pri
|
||||
HEADERS += \
|
||||
$$PWD/database/ConnectionManager.h \
|
||||
$$PWD/database/BaseDAO.h \
|
||||
$$PWD/database/models/UAVModel.h \
|
||||
$$PWD/database/models/DogModel.h \
|
||||
$$PWD/database/models/InjuryModel.h \
|
||||
$$PWD/services/DeviceService.h \
|
||||
$$PWD/utils/Logger.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/database/ConnectionManager.cpp \
|
||||
$$PWD/database/BaseDAO.cpp \
|
||||
$$PWD/database/models/UAVModel.cpp \
|
||||
$$PWD/database/models/DogModel.cpp \
|
||||
$$PWD/database/models/InjuryModel.cpp \
|
||||
$$PWD/services/DeviceService.cpp \
|
||||
$$PWD/utils/Logger.cpp
|
||||
```
|
||||
|
||||
## 迁移策略
|
||||
|
||||
### 阶段1: 准备工作
|
||||
1. 创建新的目录结构
|
||||
2. 设置构建环境
|
||||
3. 创建基础框架类
|
||||
|
||||
### 阶段2: 数据库层迁移
|
||||
1. 实现新的数据库连接管理
|
||||
2. 迁移现有数据模型
|
||||
3. 创建改进的DAO类
|
||||
4. 测试数据库操作
|
||||
|
||||
### 阶段3: UI组件重构
|
||||
1. 创建新的设备卡片组件
|
||||
2. 重构主界面布局
|
||||
3. 实现样式主题系统
|
||||
4. 迁移现有功能
|
||||
|
||||
### 阶段4: 集成和测试
|
||||
1. 集成所有模块
|
||||
2. 全面功能测试
|
||||
3. 性能优化
|
||||
4. 文档更新
|
||||
|
||||
## 风险评估
|
||||
|
||||
### 技术风险
|
||||
- **数据库迁移风险**: 中等 - 现有数据库结构已经使用MySQL
|
||||
- **UI兼容性风险**: 低 - 使用标准Qt组件
|
||||
- **性能风险**: 低 - 改进的架构应该提升性能
|
||||
|
||||
### 时间风险
|
||||
- **开发周期**: 预计4-5周
|
||||
- **测试时间**: 额外1周
|
||||
- **文档编写**: 额外几天
|
||||
|
||||
### 缓解策略
|
||||
1. 分阶段实施,确保每个阶段都有可工作的版本
|
||||
2. 保持现有数据库结构兼容性
|
||||
3. 充分的单元测试和集成测试
|
||||
4. 详细的代码审查和文档
|
@ -1,682 +0,0 @@
|
||||
// RightFunctionPanel.h
|
||||
#ifndef RIGHTFUNCTIONPANEL_H
|
||||
#define RIGHTFUNCTIONPANEL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QFrame>
|
||||
#include <QProgressBar>
|
||||
#include <QSlider>
|
||||
|
||||
class ModuleCard : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ModuleCard(const QString &title, const QString &icon, QWidget *parent = nullptr);
|
||||
void addContent(QWidget *content);
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_contentLayout;
|
||||
QLabel *m_titleLabel;
|
||||
};
|
||||
|
||||
class DeviceCard : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeviceCard(const QString &name, const QString &iconPath, QWidget *parent = nullptr);
|
||||
void setStatus(const QString &status, const QColor &color);
|
||||
void setActive(bool active);
|
||||
|
||||
signals:
|
||||
void deviceSelected(const QString &deviceName);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
QString m_deviceName;
|
||||
QLabel *m_iconLabel;
|
||||
QLabel *m_nameLabel;
|
||||
QLabel *m_statusLabel;
|
||||
bool m_isActive = false;
|
||||
};
|
||||
|
||||
class RightFunctionPanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RightFunctionPanel(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
// 战场探索信号
|
||||
void startMapping();
|
||||
void stopMapping();
|
||||
void startNavigation();
|
||||
void stopNavigation();
|
||||
void startPhotoTransmission();
|
||||
void stopPhotoTransmission();
|
||||
void startPersonRecognition();
|
||||
void stopPersonRecognition();
|
||||
|
||||
// 情报传输信号
|
||||
void startVoiceCall();
|
||||
void endVoiceCall();
|
||||
void muteCall(bool muted);
|
||||
void setCallVolume(int volume);
|
||||
|
||||
// 敌情统计信号
|
||||
void refreshEnemyStats();
|
||||
void exportReport();
|
||||
void requestAIAnalysis();
|
||||
|
||||
public slots:
|
||||
void updateEnemyStats(int totalEnemies, const QString &threatLevel);
|
||||
void updateDeviceStatus(const QString &deviceName, bool online, int battery);
|
||||
|
||||
private slots:
|
||||
void onDeviceSelected(const QString &deviceName);
|
||||
void onMappingToggle();
|
||||
void onNavigationToggle();
|
||||
void onPhotoTransmissionToggle();
|
||||
void onPersonRecognitionToggle();
|
||||
void onVoiceCallToggle();
|
||||
void onRefreshStats();
|
||||
void onAIAnalysis();
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
void setupBattlefieldExplorationModule();
|
||||
void setupIntelligenceModule();
|
||||
void setupEnemyStatsModule();
|
||||
void applyStyles();
|
||||
|
||||
// UI组件
|
||||
QVBoxLayout *m_mainLayout;
|
||||
|
||||
// 战场探索模块
|
||||
ModuleCard *m_explorationCard;
|
||||
DeviceCard *m_robotDogCard;
|
||||
DeviceCard *m_droneCard;
|
||||
QPushButton *m_mappingBtn;
|
||||
QPushButton *m_navigationBtn;
|
||||
QPushButton *m_photoBtn;
|
||||
QPushButton *m_recognitionBtn;
|
||||
QString m_selectedDevice;
|
||||
|
||||
// 情报传输模块
|
||||
ModuleCard *m_intelligenceCard;
|
||||
QPushButton *m_voiceCallBtn;
|
||||
QPushButton *m_muteBtn;
|
||||
QSlider *m_volumeSlider;
|
||||
QLabel *m_callStatusLabel;
|
||||
bool m_isInCall = false;
|
||||
|
||||
// 敌情统计模块
|
||||
ModuleCard *m_statsCard;
|
||||
QLabel *m_totalEnemiesLabel;
|
||||
QLabel *m_threatLevelLabel;
|
||||
QPushButton *m_refreshBtn;
|
||||
QPushButton *m_aiAnalysisBtn;
|
||||
QPushButton *m_exportBtn;
|
||||
};
|
||||
|
||||
#endif // RIGHTFUNCTIONPANEL_H
|
||||
|
||||
// RightFunctionPanel.cpp
|
||||
#include "RightFunctionPanel.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QTimer>
|
||||
|
||||
// ModuleCard实现
|
||||
ModuleCard::ModuleCard(const QString &title, const QString &icon, QWidget *parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setObjectName("ModuleCard");
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(12);
|
||||
layout->setContentsMargins(12, 12, 12, 12);
|
||||
|
||||
// 标题栏
|
||||
QHBoxLayout *headerLayout = new QHBoxLayout();
|
||||
QLabel *iconLabel = new QLabel();
|
||||
iconLabel->setObjectName("ModuleIcon");
|
||||
iconLabel->setText(icon); // 使用Unicode图标或设置图片
|
||||
iconLabel->setFixedSize(20, 20);
|
||||
|
||||
m_titleLabel = new QLabel(title);
|
||||
m_titleLabel->setObjectName("ModuleTitle");
|
||||
|
||||
headerLayout->addWidget(iconLabel);
|
||||
headerLayout->addWidget(m_titleLabel);
|
||||
headerLayout->addStretch();
|
||||
|
||||
layout->addLayout(headerLayout);
|
||||
|
||||
// 内容区域
|
||||
m_contentLayout = new QVBoxLayout();
|
||||
m_contentLayout->setSpacing(8);
|
||||
layout->addLayout(m_contentLayout);
|
||||
}
|
||||
|
||||
void ModuleCard::addContent(QWidget *content)
|
||||
{
|
||||
m_contentLayout->addWidget(content);
|
||||
}
|
||||
|
||||
// DeviceCard实现
|
||||
DeviceCard::DeviceCard(const QString &name, const QString &iconPath, QWidget *parent)
|
||||
: QFrame(parent), m_deviceName(name)
|
||||
{
|
||||
setObjectName("DeviceCard");
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setFixedHeight(80);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setAlignment(Qt::AlignCenter);
|
||||
layout->setSpacing(4);
|
||||
|
||||
m_iconLabel = new QLabel();
|
||||
m_iconLabel->setObjectName("DeviceIcon");
|
||||
m_iconLabel->setFixedSize(32, 32);
|
||||
m_iconLabel->setAlignment(Qt::AlignCenter);
|
||||
// 设置图标,这里用文字代替
|
||||
m_iconLabel->setText(name.contains("机器狗") ? "🐕" : "🚁");
|
||||
|
||||
m_nameLabel = new QLabel(name);
|
||||
m_nameLabel->setObjectName("DeviceName");
|
||||
m_nameLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
m_statusLabel = new QLabel("离线");
|
||||
m_statusLabel->setObjectName("DeviceStatus");
|
||||
m_statusLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
layout->addWidget(m_iconLabel);
|
||||
layout->addWidget(m_nameLabel);
|
||||
layout->addWidget(m_statusLabel);
|
||||
}
|
||||
|
||||
void DeviceCard::setStatus(const QString &status, const QColor &color)
|
||||
{
|
||||
m_statusLabel->setText(status);
|
||||
m_statusLabel->setStyleSheet(QString("color: %1;").arg(color.name()));
|
||||
}
|
||||
|
||||
void DeviceCard::setActive(bool active)
|
||||
{
|
||||
m_isActive = active;
|
||||
update();
|
||||
}
|
||||
|
||||
void DeviceCard::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
emit deviceSelected(m_deviceName);
|
||||
}
|
||||
QFrame::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void DeviceCard::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QFrame::paintEvent(event);
|
||||
|
||||
if (m_isActive) {
|
||||
QPainter painter(this);
|
||||
painter.setPen(QPen(QColor("#2E5D31"), 2));
|
||||
painter.drawRect(rect().adjusted(1, 1, -1, -1));
|
||||
}
|
||||
}
|
||||
|
||||
// RightFunctionPanel实现
|
||||
RightFunctionPanel::RightFunctionPanel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUI();
|
||||
applyStyles();
|
||||
}
|
||||
|
||||
void RightFunctionPanel::setupUI()
|
||||
{
|
||||
m_mainLayout = new QVBoxLayout(this);
|
||||
m_mainLayout->setSpacing(12);
|
||||
m_mainLayout->setContentsMargins(16, 16, 16, 16);
|
||||
|
||||
// 面板标题
|
||||
QLabel *titleLabel = new QLabel("功能面板");
|
||||
titleLabel->setObjectName("PanelTitle");
|
||||
titleLabel->setAlignment(Qt::AlignCenter);
|
||||
m_mainLayout->addWidget(titleLabel);
|
||||
|
||||
setupBattlefieldExplorationModule();
|
||||
setupIntelligenceModule();
|
||||
setupEnemyStatsModule();
|
||||
|
||||
m_mainLayout->addStretch();
|
||||
}
|
||||
|
||||
void RightFunctionPanel::setupBattlefieldExplorationModule()
|
||||
{
|
||||
m_explorationCard = new ModuleCard("战场探索", "🔍", this);
|
||||
|
||||
// 设备选择
|
||||
QHBoxLayout *deviceLayout = new QHBoxLayout();
|
||||
m_robotDogCard = new DeviceCard("机器狗", "robot_dog.png", this);
|
||||
m_droneCard = new DeviceCard("无人机", "drone.png", this);
|
||||
|
||||
connect(m_robotDogCard, &DeviceCard::deviceSelected, this, &RightFunctionPanel::onDeviceSelected);
|
||||
connect(m_droneCard, &DeviceCard::deviceSelected, this, &RightFunctionPanel::onDeviceSelected);
|
||||
|
||||
deviceLayout->addWidget(m_robotDogCard);
|
||||
deviceLayout->addWidget(m_droneCard);
|
||||
|
||||
QWidget *deviceWidget = new QWidget();
|
||||
deviceWidget->setLayout(deviceLayout);
|
||||
m_explorationCard->addContent(deviceWidget);
|
||||
|
||||
// 功能按钮
|
||||
QGridLayout *buttonLayout = new QGridLayout();
|
||||
m_mappingBtn = new QPushButton("自主建图");
|
||||
m_navigationBtn = new QPushButton("导航避障");
|
||||
m_photoBtn = new QPushButton("照片传输");
|
||||
m_recognitionBtn = new QPushButton("人物识别");
|
||||
|
||||
// 设置按钮样式类名
|
||||
m_mappingBtn->setObjectName("FunctionBtn");
|
||||
m_navigationBtn->setObjectName("FunctionBtn");
|
||||
m_photoBtn->setObjectName("FunctionBtn");
|
||||
m_recognitionBtn->setObjectName("FunctionBtn");
|
||||
|
||||
buttonLayout->addWidget(m_mappingBtn, 0, 0);
|
||||
buttonLayout->addWidget(m_navigationBtn, 0, 1);
|
||||
buttonLayout->addWidget(m_photoBtn, 1, 0);
|
||||
buttonLayout->addWidget(m_recognitionBtn, 1, 1);
|
||||
|
||||
connect(m_mappingBtn, &QPushButton::clicked, this, &RightFunctionPanel::onMappingToggle);
|
||||
connect(m_navigationBtn, &QPushButton::clicked, this, &RightFunctionPanel::onNavigationToggle);
|
||||
connect(m_photoBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPhotoTransmissionToggle);
|
||||
connect(m_recognitionBtn, &QPushButton::clicked, this, &RightFunctionPanel::onPersonRecognitionToggle);
|
||||
|
||||
QWidget *buttonWidget = new QWidget();
|
||||
buttonWidget->setLayout(buttonLayout);
|
||||
m_explorationCard->addContent(buttonWidget);
|
||||
|
||||
m_mainLayout->addWidget(m_explorationCard);
|
||||
}
|
||||
|
||||
void RightFunctionPanel::setupIntelligenceModule()
|
||||
{
|
||||
m_intelligenceCard = new ModuleCard("情报传输", "📡", this);
|
||||
|
||||
// 通话控制
|
||||
QHBoxLayout *callLayout = new QHBoxLayout();
|
||||
m_voiceCallBtn = new QPushButton("开始通话");
|
||||
m_muteBtn = new QPushButton("静音");
|
||||
m_voiceCallBtn->setObjectName("FunctionBtn");
|
||||
m_muteBtn->setObjectName("FunctionBtn");
|
||||
m_muteBtn->setEnabled(false);
|
||||
|
||||
callLayout->addWidget(m_voiceCallBtn);
|
||||
callLayout->addWidget(m_muteBtn);
|
||||
|
||||
connect(m_voiceCallBtn, &QPushButton::clicked, this, &RightFunctionPanel::onVoiceCallToggle);
|
||||
|
||||
QWidget *callWidget = new QWidget();
|
||||
callWidget->setLayout(callLayout);
|
||||
m_intelligenceCard->addContent(callWidget);
|
||||
|
||||
// 音量控制
|
||||
QHBoxLayout *volumeLayout = new QHBoxLayout();
|
||||
QLabel *volumeLabel = new QLabel("音量:");
|
||||
m_volumeSlider = new QSlider(Qt::Horizontal);
|
||||
m_volumeSlider->setRange(0, 100);
|
||||
m_volumeSlider->setValue(70);
|
||||
|
||||
volumeLayout->addWidget(volumeLabel);
|
||||
volumeLayout->addWidget(m_volumeSlider);
|
||||
|
||||
QWidget *volumeWidget = new QWidget();
|
||||
volumeWidget->setLayout(volumeLayout);
|
||||
m_intelligenceCard->addContent(volumeWidget);
|
||||
|
||||
// 通话状态
|
||||
m_callStatusLabel = new QLabel("未连接");
|
||||
m_callStatusLabel->setObjectName("CallStatus");
|
||||
m_intelligenceCard->addContent(m_callStatusLabel);
|
||||
|
||||
m_mainLayout->addWidget(m_intelligenceCard);
|
||||
}
|
||||
|
||||
void RightFunctionPanel::setupEnemyStatsModule()
|
||||
{
|
||||
m_statsCard = new ModuleCard("敌情统计", "📊", this);
|
||||
|
||||
// 统计信息
|
||||
QVBoxLayout *statsLayout = new QVBoxLayout();
|
||||
|
||||
m_totalEnemiesLabel = new QLabel("已发现目标: 0");
|
||||
m_threatLevelLabel = new QLabel("威胁等级: 无");
|
||||
m_totalEnemiesLabel->setObjectName("StatLabel");
|
||||
m_threatLevelLabel->setObjectName("StatLabel");
|
||||
|
||||
statsLayout->addWidget(m_totalEnemiesLabel);
|
||||
statsLayout->addWidget(m_threatLevelLabel);
|
||||
|
||||
QWidget *statsWidget = new QWidget();
|
||||
statsWidget->setLayout(statsLayout);
|
||||
m_statsCard->addContent(statsWidget);
|
||||
|
||||
// 操作按钮
|
||||
QHBoxLayout *statsButtonLayout = new QHBoxLayout();
|
||||
m_refreshBtn = new QPushButton("刷新");
|
||||
m_aiAnalysisBtn = new QPushButton("AI分析");
|
||||
m_exportBtn = new QPushButton("导出报告");
|
||||
|
||||
m_refreshBtn->setObjectName("FunctionBtn");
|
||||
m_aiAnalysisBtn->setObjectName("FunctionBtn");
|
||||
m_exportBtn->setObjectName("FunctionBtn");
|
||||
|
||||
statsButtonLayout->addWidget(m_refreshBtn);
|
||||
statsButtonLayout->addWidget(m_aiAnalysisBtn);
|
||||
|
||||
connect(m_refreshBtn, &QPushButton::clicked, this, &RightFunctionPanel::onRefreshStats);
|
||||
connect(m_aiAnalysisBtn, &QPushButton::clicked, this, &RightFunctionPanel::onAIAnalysis);
|
||||
|
||||
QWidget *statsButtonWidget = new QWidget();
|
||||
statsButtonWidget->setLayout(statsButtonLayout);
|
||||
m_statsCard->addContent(statsButtonWidget);
|
||||
|
||||
// 导出按钮单独一行
|
||||
m_statsCard->addContent(m_exportBtn);
|
||||
|
||||
m_mainLayout->addWidget(m_statsCard);
|
||||
}
|
||||
|
||||
void RightFunctionPanel::applyStyles()
|
||||
{
|
||||
QString styles = R"(
|
||||
QWidget {
|
||||
font-family: "Microsoft YaHei", "SimHei", sans-serif;
|
||||
}
|
||||
|
||||
RightFunctionPanel {
|
||||
background-color: #2A3F47;
|
||||
border-left: 2px solid #546E7A;
|
||||
}
|
||||
|
||||
#PanelTitle {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
border-bottom: 1px solid #546E7A;
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
#ModuleCard {
|
||||
background-color: #354A54;
|
||||
border: 1px solid #546E7A;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
#ModuleCard:hover {
|
||||
border-color: #2E5D31;
|
||||
background-color: #4A6572;
|
||||
}
|
||||
|
||||
#ModuleTitle {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
#ModuleIcon {
|
||||
font-size: 16px;
|
||||
color: #2E5D31;
|
||||
}
|
||||
|
||||
#DeviceCard {
|
||||
background-color: #3D525E;
|
||||
border: 1px solid #546E7A;
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#DeviceCard:hover {
|
||||
background-color: #4A6572;
|
||||
border-color: #2E5D31;
|
||||
}
|
||||
|
||||
#DeviceName {
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#DeviceStatus {
|
||||
font-size: 10px;
|
||||
color: #78909C;
|
||||
}
|
||||
|
||||
#FunctionBtn {
|
||||
background-color: #2E5D31;
|
||||
color: #FFFFFF;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
#FunctionBtn:hover {
|
||||
background-color: #245429;
|
||||
}
|
||||
|
||||
#FunctionBtn:pressed {
|
||||
background-color: #1a3d1d;
|
||||
}
|
||||
|
||||
#FunctionBtn:disabled {
|
||||
background-color: #78909C;
|
||||
}
|
||||
|
||||
#StatLabel {
|
||||
font-size: 12px;
|
||||
color: #B0BEC5;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
#CallStatus {
|
||||
font-size: 11px;
|
||||
color: #78909C;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
border: 1px solid #546E7A;
|
||||
height: 4px;
|
||||
background: #3D525E;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #2E5D31;
|
||||
border: 1px solid #546E7A;
|
||||
width: 12px;
|
||||
margin: -4px 0;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
background: #245429;
|
||||
}
|
||||
)";
|
||||
|
||||
setStyleSheet(styles);
|
||||
}
|
||||
|
||||
// 槽函数实现
|
||||
void RightFunctionPanel::onDeviceSelected(const QString &deviceName)
|
||||
{
|
||||
m_selectedDevice = deviceName;
|
||||
|
||||
// 更新设备选择状态
|
||||
m_robotDogCard->setActive(deviceName.contains("机器狗"));
|
||||
m_droneCard->setActive(deviceName.contains("无人机"));
|
||||
|
||||
// 根据设备类型启用/禁用相应按钮
|
||||
bool isRobotDog = deviceName.contains("机器狗");
|
||||
m_mappingBtn->setEnabled(isRobotDog);
|
||||
m_navigationBtn->setEnabled(isRobotDog);
|
||||
m_photoBtn->setEnabled(!isRobotDog);
|
||||
m_recognitionBtn->setEnabled(!isRobotDog);
|
||||
}
|
||||
|
||||
void RightFunctionPanel::onMappingToggle()
|
||||
{
|
||||
static bool isMappingActive = false;
|
||||
isMappingActive = !isMappingActive;
|
||||
|
||||
m_mappingBtn->setText(isMappingActive ? "停止建图" : "自主建图");
|
||||
|
||||
if (isMappingActive) {
|
||||
emit startMapping();
|
||||
} else {
|
||||
emit stopMapping();
|
||||
}
|
||||
}
|
||||
|
||||
void RightFunctionPanel::onNavigationToggle()
|
||||
{
|
||||
static bool isNavigationActive = false;
|
||||
isNavigationActive = !isNavigationActive;
|
||||
|
||||
m_navigationBtn->setText(isNavigationActive ? "停止导航" : "导航避障");
|
||||
|
||||
if (isNavigationActive) {
|
||||
emit startNavigation();
|
||||
} else {
|
||||
emit stopNavigation();
|
||||
}
|
||||
}
|
||||
|
||||
void RightFunctionPanel::onPhotoTransmissionToggle()
|
||||
{
|
||||
static bool isTransmissionActive = false;
|
||||
isTransmissionActive = !isTransmissionActive;
|
||||
|
||||
m_photoBtn->setText(isTransmissionActive ? "停止传输" : "照片传输");
|
||||
|
||||
if (isTransmissionActive) {
|
||||
emit startPhotoTransmission();
|
||||
} else {
|
||||
emit stopPhotoTransmission();
|
||||
}
|
||||
}
|
||||
|
||||
void RightFunctionPanel::onPersonRecognitionToggle()
|
||||
{
|
||||
static bool isRecognitionActive = false;
|
||||
isRecognitionActive = !isRecognitionActive;
|
||||
|
||||
m_recognitionBtn->setText(isRecognitionActive ? "停止识别" : "人物识别");
|
||||
|
||||
if (isRecognitionActive) {
|
||||
emit startPersonRecognition();
|
||||
} else {
|
||||
emit stopPersonRecognition();
|
||||
}
|
||||
}
|
||||
|
||||
void RightFunctionPanel::onVoiceCallToggle()
|
||||
{
|
||||
m_isInCall = !m_isInCall;
|
||||
|
||||
m_voiceCallBtn->setText(m_isInCall ? "结束通话" : "开始通话");
|
||||
m_muteBtn->setEnabled(m_isInCall);
|
||||
m_callStatusLabel->setText(m_isInCall ? "通话中..." : "未连接");
|
||||
|
||||
if (m_isInCall) {
|
||||
emit startVoiceCall();
|
||||
} else {
|
||||
emit endVoiceCall();
|
||||
}
|
||||
}
|
||||
|
||||
void RightFunctionPanel::onRefreshStats()
|
||||
{
|
||||
emit refreshEnemyStats();
|
||||
|
||||
// 模拟刷新效果
|
||||
m_refreshBtn->setText("刷新中...");
|
||||
m_refreshBtn->setEnabled(false);
|
||||
|
||||
QTimer::singleShot(2000, [this]() {
|
||||
m_refreshBtn->setText("刷新");
|
||||
m_refreshBtn->setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
void RightFunctionPanel::onAIAnalysis()
|
||||
{
|
||||
emit requestAIAnalysis();
|
||||
|
||||
// 显示分析状态
|
||||
m_aiAnalysisBtn->setText("分析中...");
|
||||
m_aiAnalysisBtn->setEnabled(false);
|
||||
|
||||
QTimer::singleShot(3000, [this]() {
|
||||
m_aiAnalysisBtn->setText("AI分析");
|
||||
m_aiAnalysisBtn->setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
void RightFunctionPanel::updateEnemyStats(int totalEnemies, const QString &threatLevel)
|
||||
{
|
||||
m_totalEnemiesLabel->setText(QString("已发现目标: %1").arg(totalEnemies));
|
||||
m_threatLevelLabel->setText(QString("威胁等级: %1").arg(threatLevel));
|
||||
|
||||
// 根据威胁等级设置颜色
|
||||
if (threatLevel == "高") {
|
||||
m_threatLevelLabel->setStyleSheet("color: #DC143C;");
|
||||
} else if (threatLevel == "中") {
|
||||
m_threatLevelLabel->setStyleSheet("color: #FF8C00;");
|
||||
} else {
|
||||
m_threatLevelLabel->setStyleSheet("color: #4CAF50;");
|
||||
}
|
||||
}
|
||||
|
||||
void RightFunctionPanel::updateDeviceStatus(const QString &deviceName, bool online, int battery)
|
||||
{
|
||||
DeviceCard *deviceCard = nullptr;
|
||||
if (deviceName.contains("机器狗")) {
|
||||
deviceCard = m_robotDogCard;
|
||||
} else if (deviceName.contains("无人机")) {
|
||||
deviceCard = m_droneCard;
|
||||
}
|
||||
|
||||
if (deviceCard) {
|
||||
if (online) {
|
||||
deviceCard->setStatus(QString("在线 %1%").arg(battery), QColor("#4CAF50"));
|
||||
} else {
|
||||
deviceCard->setStatus("离线", QColor("#78909C"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "RightFunctionPanel.moc"
|
@ -1,55 +0,0 @@
|
||||
-- BattlefieldExplorationSystem 数据库设置脚本
|
||||
|
||||
-- 创建数据库
|
||||
CREATE DATABASE IF NOT EXISTS fly_land_database;
|
||||
USE fly_land_database;
|
||||
|
||||
-- 创建无人机表
|
||||
CREATE TABLE IF NOT EXISTS uavdatabase (
|
||||
id VARCHAR(50) PRIMARY KEY,
|
||||
state INT DEFAULT 0,
|
||||
ip VARCHAR(15) NOT NULL,
|
||||
port INT DEFAULT 8080,
|
||||
lon DOUBLE DEFAULT 0.0,
|
||||
lat DOUBLE DEFAULT 0.0
|
||||
);
|
||||
|
||||
-- 创建机器狗表
|
||||
CREATE TABLE IF NOT EXISTS dogdatabase (
|
||||
id VARCHAR(50) PRIMARY KEY,
|
||||
state INT DEFAULT 0,
|
||||
ip VARCHAR(15) NOT NULL,
|
||||
port INT DEFAULT 9090,
|
||||
lon DOUBLE DEFAULT 0.0,
|
||||
lat DOUBLE DEFAULT 0.0
|
||||
);
|
||||
|
||||
-- 插入测试数据 - 无人机
|
||||
INSERT INTO uavdatabase (id, state, ip, port, lon, lat) VALUES
|
||||
('UAV001', 1, '192.168.1.101', 8080, 116.40, 39.90),
|
||||
('UAV002', 2, '192.168.1.102', 8080, 116.42, 39.92),
|
||||
('UAV003', 0, '192.168.1.103', 8080, 116.44, 39.94)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
state = VALUES(state),
|
||||
ip = VALUES(ip),
|
||||
port = VALUES(port),
|
||||
lon = VALUES(lon),
|
||||
lat = VALUES(lat);
|
||||
|
||||
-- 插入测试数据 - 机器狗
|
||||
INSERT INTO dogdatabase (id, state, ip, port, lon, lat) VALUES
|
||||
('DOG001', 1, '192.168.1.201', 9090, 116.38, 39.88),
|
||||
('DOG002', 0, '192.168.1.202', 9090, 116.46, 39.86)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
state = VALUES(state),
|
||||
ip = VALUES(ip),
|
||||
port = VALUES(port),
|
||||
lon = VALUES(lon),
|
||||
lat = VALUES(lat);
|
||||
|
||||
-- 验证数据
|
||||
SELECT 'UAV Devices:' AS info;
|
||||
SELECT * FROM uavdatabase;
|
||||
|
||||
SELECT 'Dog Devices:' AS info;
|
||||
SELECT * FROM dogdatabase;
|
Loading…
Reference in new issue