|
|
"""
|
|
|
无人机决策系统 - 数据库管理模块
|
|
|
作者:刘宇杰
|
|
|
日期:2025-07-13
|
|
|
功能说明:
|
|
|
本模块提供数据库的初始化、分析记录和打击计划的增删查改等操作。
|
|
|
"""
|
|
|
import sqlite3
|
|
|
import json
|
|
|
from sqlite3 import Error
|
|
|
from datetime import datetime
|
|
|
from config.settings import settings
|
|
|
from typing import List, Dict, Any, Optional
|
|
|
|
|
|
class DatabaseManager:
|
|
|
"""
|
|
|
数据库管理类,负责数据库的初始化和数据操作。
|
|
|
"""
|
|
|
|
|
|
def __init__(self):
|
|
|
"""
|
|
|
初始化数据库管理器,自动创建数据库和表结构。
|
|
|
"""
|
|
|
self.db_path = settings.DATABASE_PATH
|
|
|
self._init_db()
|
|
|
|
|
|
def _init_db(self):
|
|
|
"""
|
|
|
初始化数据库表结构。
|
|
|
"""
|
|
|
conn = None
|
|
|
try:
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
# 简化后的分析记录表(不再关联用户)
|
|
|
cursor.execute("""
|
|
|
CREATE TABLE IF NOT EXISTS analysis_records (
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
record_type TEXT NOT NULL, -- 'text' or 'image'
|
|
|
file_path TEXT NOT NULL,
|
|
|
analysis_result TEXT NOT NULL,
|
|
|
created_at TEXT NOT NULL
|
|
|
)
|
|
|
""")
|
|
|
|
|
|
# 简化后的打击计划表(不再关联用户)
|
|
|
cursor.execute("""
|
|
|
CREATE TABLE IF NOT EXISTS strike_plans (
|
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
|
plan_details TEXT NOT NULL,
|
|
|
created_at TEXT NOT NULL,
|
|
|
executed BOOLEAN DEFAULT 0,
|
|
|
execution_result TEXT
|
|
|
)
|
|
|
""")
|
|
|
|
|
|
conn.commit()
|
|
|
except Error as e:
|
|
|
print(f"数据库初始化失败: {str(e)}")
|
|
|
finally:
|
|
|
if conn:
|
|
|
conn.close()
|
|
|
|
|
|
def add_analysis_record(self, record_type: str, file_path: str, analysis_result: dict) -> Optional[int]:
|
|
|
"""
|
|
|
添加分析记录。
|
|
|
:param record_type: 记录类型(text/image)
|
|
|
:param file_path: 文件路径
|
|
|
:param analysis_result: 分析结果字典
|
|
|
:return: 新记录ID或-1
|
|
|
"""
|
|
|
try:
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
cursor.execute(
|
|
|
"INSERT INTO analysis_records (record_type, file_path, analysis_result, created_at) VALUES (?, ?, ?, ?)",
|
|
|
(record_type, file_path, json.dumps(analysis_result), datetime.now().isoformat())
|
|
|
)
|
|
|
|
|
|
record_id = cursor.lastrowid
|
|
|
conn.commit()
|
|
|
return record_id
|
|
|
except Error as e:
|
|
|
print(f"添加分析记录失败: {str(e)}")
|
|
|
return -1
|
|
|
finally:
|
|
|
if conn:
|
|
|
conn.close()
|
|
|
|
|
|
def get_records(self, limit: int = 10) -> list:
|
|
|
"""
|
|
|
获取分析记录。
|
|
|
:param limit: 返回记录数
|
|
|
:return: 记录列表
|
|
|
"""
|
|
|
try:
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
conn.row_factory = sqlite3.Row
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
cursor.execute(
|
|
|
"SELECT * FROM analysis_records ORDER BY created_at DESC LIMIT ?",
|
|
|
(limit,)
|
|
|
)
|
|
|
|
|
|
records = cursor.fetchall()
|
|
|
return [dict(record) for record in records]
|
|
|
except Error as e:
|
|
|
print(f"获取分析记录失败: {str(e)}")
|
|
|
return []
|
|
|
finally:
|
|
|
if conn:
|
|
|
conn.close()
|
|
|
|
|
|
def get_user_records(self, user_id: int, limit: int = 10) -> list:
|
|
|
"""
|
|
|
获取用户的分析记录(兼容旧接口)。
|
|
|
:param user_id: 用户ID
|
|
|
:param limit: 返回记录数
|
|
|
:return: 记录列表
|
|
|
"""
|
|
|
return self.get_records(limit)
|
|
|
|
|
|
def add_strike_plan(self, user_id: int, plan_details: dict) -> Optional[int]:
|
|
|
"""
|
|
|
添加打击计划。
|
|
|
:param user_id: 用户ID
|
|
|
:param plan_details: 计划详情字典
|
|
|
:return: 新计划ID或-1
|
|
|
"""
|
|
|
try:
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
cursor.execute(
|
|
|
"INSERT INTO strike_plans (plan_details, created_at) VALUES (?, ?)",
|
|
|
(json.dumps(plan_details), datetime.now().isoformat())
|
|
|
)
|
|
|
|
|
|
plan_id = cursor.lastrowid
|
|
|
conn.commit()
|
|
|
return plan_id
|
|
|
except Error as e:
|
|
|
print(f"添加打击计划失败: {str(e)}")
|
|
|
return -1
|
|
|
finally:
|
|
|
if conn:
|
|
|
conn.close()
|
|
|
|
|
|
def get_user_plans(self, user_id: int, limit: int = 5) -> list:
|
|
|
"""
|
|
|
获取用户的打击计划。
|
|
|
:param user_id: 用户ID
|
|
|
:param limit: 返回计划数
|
|
|
:return: 计划列表
|
|
|
"""
|
|
|
try:
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
conn.row_factory = sqlite3.Row
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
cursor.execute(
|
|
|
"SELECT * FROM strike_plans ORDER BY created_at DESC LIMIT ?",
|
|
|
(limit,)
|
|
|
)
|
|
|
|
|
|
plans = cursor.fetchall()
|
|
|
return [dict(plan) for plan in plans]
|
|
|
except Error as e:
|
|
|
print(f"获取打击计划失败: {str(e)}")
|
|
|
return []
|
|
|
finally:
|
|
|
if conn:
|
|
|
conn.close()
|
|
|
|
|
|
def mark_plan_executed(self, plan_id: int, execution_result: dict):
|
|
|
"""
|
|
|
标记计划为已执行。
|
|
|
:param plan_id: 计划ID
|
|
|
:param execution_result: 执行结果字典
|
|
|
"""
|
|
|
try:
|
|
|
conn = sqlite3.connect(self.db_path)
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
cursor.execute(
|
|
|
"UPDATE strike_plans SET executed = 1, execution_result = ? WHERE id = ?",
|
|
|
(json.dumps(execution_result), plan_id)
|
|
|
)
|
|
|
|
|
|
conn.commit()
|
|
|
except Error as e:
|
|
|
print(f"更新计划状态失败: {str(e)}")
|
|
|
finally:
|
|
|
if conn:
|
|
|
conn.close()
|
|
|
|
|
|
def get_user(self, username: str) -> dict:
|
|
|
"""
|
|
|
获取用户信息(模拟用户)。
|
|
|
:param username: 用户名
|
|
|
:return: 用户信息字典
|
|
|
"""
|
|
|
# 简化版:返回模拟用户数据
|
|
|
return {
|
|
|
'id': 1,
|
|
|
'username': username,
|
|
|
'password_hash': '', # 简化版不验证密码
|
|
|
'created_at': datetime.now().isoformat(),
|
|
|
'last_login': None
|
|
|
}
|
|
|
|
|
|
def add_user(self, username: str, password_hash: str) -> bool:
|
|
|
"""
|
|
|
添加新用户(模拟)。
|
|
|
:param username: 用户名
|
|
|
:param password_hash: 密码哈希
|
|
|
:return: 是否成功
|
|
|
"""
|
|
|
# 简化版:总是返回成功
|
|
|
print(f"添加用户: {username}")
|
|
|
return True
|
|
|
|
|
|
def update_user_login_time(self, user_id: int):
|
|
|
"""
|
|
|
更新用户最后登录时间(模拟)。
|
|
|
:param user_id: 用户ID
|
|
|
"""
|
|
|
# 简化版:不实际更新数据库
|
|
|
print(f"更新用户 {user_id} 登录时间")
|
|
|
|
|
|
def unused_function_3():
|
|
|
temp = [x * 2 for x in range(7)]
|
|
|
return temp
|
|
|
|
|
|
class UnusedClassC:
|
|
|
def __init__(self):
|
|
|
self.data = []
|
|
|
def add(self, item):
|
|
|
self.data.append(item)
|
|
|
def clear(self):
|
|
|
self.data = []
|
|
|
|
|
|
unused_var_3 = 3.14159
|
|
|
unused_set_3 = set(range(4))
|
|
|
|
|
|
def unused_function_11():
|
|
|
s = 0
|
|
|
for i in range(50):
|
|
|
s += i
|
|
|
return s
|
|
|
|
|
|
def unused_function_12():
|
|
|
return [chr(97+i) for i in range(26)]
|
|
|
|
|
|
class UnusedClassK:
|
|
|
def __init__(self):
|
|
|
self.items = set()
|
|
|
def add_item(self, item):
|
|
|
self.items.add(item)
|
|
|
def clear_items(self):
|
|
|
self.items.clear()
|
|
|
|
|
|
class UnusedClassL:
|
|
|
def __init__(self):
|
|
|
self.counter = 0
|
|
|
def inc(self):
|
|
|
self.counter += 1
|
|
|
def reset(self):
|
|
|
self.counter = 0
|
|
|
|
|
|
unused_var_14 = [i for i in range(100)]
|
|
|
unused_var_15 = 'database_unused'
|
|
|
unused_var_16 = {i: i*i for i in range(10)}
|
|
|
|
|
|
def unused_function_23():
|
|
|
s = 0
|
|
|
for i in range(200):
|
|
|
s += i
|
|
|
return s
|
|
|
|
|
|
def unused_function_24():
|
|
|
return [chr(65+i) for i in range(52)]
|
|
|
|
|
|
class UnusedClassW:
|
|
|
def __init__(self):
|
|
|
self.items = set(range(100))
|
|
|
def add_item(self, item):
|
|
|
self.items.add(item)
|
|
|
def clear_items(self):
|
|
|
self.items.clear()
|
|
|
|
|
|
class UnusedClassX:
|
|
|
def __init__(self):
|
|
|
self.counter = 100
|
|
|
def dec(self):
|
|
|
self.counter -= 1
|
|
|
def reset(self):
|
|
|
self.counter = 100
|
|
|
|
|
|
unused_var_33 = [i for i in range(200)]
|
|
|
unused_var_34 = 'database_more_unused'
|
|
|
unused_var_35 = {i: i*i for i in range(20)} |