You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
8.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
无人机决策系统 - 数据库管理模块
作者:刘宇杰
日期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)}