fxdyz
This commit is contained in:
+176
-25
@@ -4,17 +4,137 @@
|
||||
# pyright: reportOptionalMemberAccess=false
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, Optional, List, Union
|
||||
from typing import Any, Dict
|
||||
|
||||
from astrbot.api import logger
|
||||
from astrbot.api import AstrBotConfig
|
||||
|
||||
from .sqlite import AsyncSQLiteDB
|
||||
from .fun_basic import load_template
|
||||
|
||||
|
||||
class BiLeidata:
|
||||
"""按 AstrBot 会话隔离存储本地避雷记录。"""
|
||||
|
||||
LEGACY_SESSION_ID = "__legacy_public__"
|
||||
|
||||
def __init__(self, sqlite:AsyncSQLiteDB):
|
||||
# 引用sqlite
|
||||
self._sql_db = sqlite
|
||||
|
||||
async def initialize(self):
|
||||
"""创建避雷表,并把升级前的数据迁移到历史公共数据区。"""
|
||||
table = await self._sql_db.fetch_one(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name=?",
|
||||
("bilei",),
|
||||
)
|
||||
if not table:
|
||||
await self._sql_db.execute(
|
||||
"""
|
||||
CREATE TABLE bilei (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
name TEXT,
|
||||
text TEXT,
|
||||
time TEXT,
|
||||
user TEXT
|
||||
)
|
||||
"""
|
||||
)
|
||||
else:
|
||||
columns = await self._sql_db.fetch_all("PRAGMA table_info(bilei)")
|
||||
if "session_id" not in {str(column["name"]) for column in columns}:
|
||||
legacy_count_row = await self._sql_db.fetch_one(
|
||||
"SELECT COUNT(*) AS count FROM bilei"
|
||||
)
|
||||
legacy_count = int((legacy_count_row or {}).get("count", 0))
|
||||
await self._sql_db.execute_transaction(
|
||||
[
|
||||
(
|
||||
"""
|
||||
CREATE TABLE bilei_session_migration (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
name TEXT,
|
||||
text TEXT,
|
||||
time TEXT,
|
||||
user TEXT
|
||||
)
|
||||
""",
|
||||
(),
|
||||
),
|
||||
(
|
||||
"""
|
||||
INSERT INTO bilei_session_migration (
|
||||
id, session_id, name, text, time, user
|
||||
)
|
||||
SELECT id, ?, name, text, time, user FROM bilei
|
||||
""",
|
||||
(self.LEGACY_SESSION_ID,),
|
||||
),
|
||||
("DROP TABLE bilei", ()),
|
||||
("ALTER TABLE bilei_session_migration RENAME TO bilei", ()),
|
||||
]
|
||||
)
|
||||
logger.info(
|
||||
f"已将 {legacy_count} 条旧避雷记录迁移到历史公共数据区"
|
||||
)
|
||||
|
||||
await self._sql_db.execute(
|
||||
"""
|
||||
CREATE INDEX IF NOT EXISTS idx_bilei_session_id_id
|
||||
ON bilei(session_id, id)
|
||||
"""
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _normalize_session_id(cls, session_id: Any) -> str:
|
||||
value = str(session_id or "").strip()
|
||||
if not value:
|
||||
raise ValueError("会话 ID 不能为空")
|
||||
if len(value) > 512:
|
||||
raise ValueError("会话 ID 不能超过 512 个字符")
|
||||
if value == cls.LEGACY_SESSION_ID:
|
||||
raise ValueError("历史公共数据区不能作为普通会话访问")
|
||||
return value
|
||||
|
||||
async def list_legacy_records(self) -> list[Dict[str, Any]]:
|
||||
"""列出等待从历史公共数据区迁出的旧版记录。"""
|
||||
return await self._sql_db.fetch_all(
|
||||
"""
|
||||
SELECT id, name, text, time, user
|
||||
FROM bilei
|
||||
WHERE session_id=?
|
||||
ORDER BY id
|
||||
""",
|
||||
(self.LEGACY_SESSION_ID,),
|
||||
)
|
||||
|
||||
async def migrate_legacy_record(
|
||||
self,
|
||||
record_id: Any,
|
||||
target_session_id: Any,
|
||||
) -> None:
|
||||
"""把一条历史记录原子地分配给指定的普通会话。"""
|
||||
if isinstance(record_id, bool):
|
||||
raise ValueError("避雷记录 ID 无效")
|
||||
try:
|
||||
normalized_record_id = int(str(record_id).strip())
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError("避雷记录 ID 无效") from None
|
||||
if normalized_record_id <= 0:
|
||||
raise ValueError("避雷记录 ID 无效")
|
||||
|
||||
session_id = self._normalize_session_id(target_session_id)
|
||||
affected = await self._sql_db.execute_affected(
|
||||
"""
|
||||
UPDATE bilei
|
||||
SET session_id=?
|
||||
WHERE id=? AND session_id=?
|
||||
""",
|
||||
(session_id, normalized_record_id, self.LEGACY_SESSION_ID),
|
||||
)
|
||||
if affected != 1:
|
||||
raise ValueError("该历史避雷记录不存在或已完成迁移")
|
||||
|
||||
def _init_return_data(self) -> Dict[str, Any]:
|
||||
"""初始化标准的返回数据结构"""
|
||||
@@ -26,9 +146,16 @@ class BiLeidata:
|
||||
|
||||
|
||||
# --- 业务功能函数 ---
|
||||
async def add(self,name: str, text: str ,user: str) -> Dict[str, Any]:
|
||||
async def add(
|
||||
self,
|
||||
session_id: Any,
|
||||
name: str,
|
||||
text: str,
|
||||
user: str,
|
||||
) -> Dict[str, Any]:
|
||||
"""避雷添加"""
|
||||
return_data = self._init_return_data()
|
||||
session_id = self._normalize_session_id(session_id)
|
||||
|
||||
# 获取系统时间
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
@@ -38,6 +165,7 @@ class BiLeidata:
|
||||
await self._sql_db.insert(
|
||||
"bilei",
|
||||
{
|
||||
"session_id": session_id,
|
||||
"name": name,
|
||||
"text": text,
|
||||
"time": now,
|
||||
@@ -63,21 +191,30 @@ class BiLeidata:
|
||||
return return_data
|
||||
|
||||
|
||||
async def all(self) -> Dict[str, Any]:
|
||||
async def all(self, session_id: Any) -> Dict[str, Any]:
|
||||
"""避雷查看"""
|
||||
return_data = self._init_return_data()
|
||||
session_id = self._normalize_session_id(session_id)
|
||||
|
||||
|
||||
# 查询数据
|
||||
try:
|
||||
data = await self._sql_db.select_all("bilei")
|
||||
data = await self._sql_db.fetch_all(
|
||||
"""
|
||||
SELECT id, name, text, time, user
|
||||
FROM bilei
|
||||
WHERE session_id=?
|
||||
ORDER BY id
|
||||
""",
|
||||
(session_id,),
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
logger.error(f"查看避雷失败: {e}")
|
||||
return_data["msg"] = "查看避雷失败"
|
||||
return return_data
|
||||
|
||||
if not data:
|
||||
return_data["msg"] = "未找到避雷数据"
|
||||
return_data["msg"] = "当前会话暂无避雷数据"
|
||||
return return_data
|
||||
|
||||
|
||||
@@ -97,18 +234,23 @@ class BiLeidata:
|
||||
return return_data
|
||||
|
||||
|
||||
async def select(self, name:str) -> Dict[str, Any]:
|
||||
async def select(self, session_id: Any, name: str) -> Dict[str, Any]:
|
||||
"""避雷查询 名称"""
|
||||
return_data = self._init_return_data()
|
||||
session_id = self._normalize_session_id(session_id)
|
||||
|
||||
# 模糊拼接
|
||||
like_name = f"%{name}%"
|
||||
# 查询数据
|
||||
try:
|
||||
data = await self._sql_db.select_all(
|
||||
"bilei",
|
||||
"name LIKE ?",
|
||||
(like_name,)
|
||||
data = await self._sql_db.fetch_all(
|
||||
"""
|
||||
SELECT id, name, text, time, user
|
||||
FROM bilei
|
||||
WHERE session_id=? AND name LIKE ?
|
||||
ORDER BY id
|
||||
""",
|
||||
(session_id, like_name),
|
||||
)
|
||||
except FileNotFoundError as e:
|
||||
logger.error(f"查询避雷失败: {e}")
|
||||
@@ -116,7 +258,7 @@ class BiLeidata:
|
||||
return return_data
|
||||
|
||||
if not data:
|
||||
return_data["msg"] = "未查询到避雷数据"
|
||||
return_data["msg"] = "当前会话未查询到避雷数据"
|
||||
return return_data
|
||||
|
||||
|
||||
@@ -136,18 +278,26 @@ class BiLeidata:
|
||||
return return_data
|
||||
|
||||
|
||||
async def update(self, id:int, name: str, text: str ,user: str) -> Dict[str, Any]:
|
||||
async def update(
|
||||
self,
|
||||
session_id: Any,
|
||||
id: int,
|
||||
name: str,
|
||||
text: str,
|
||||
user: str,
|
||||
) -> Dict[str, Any]:
|
||||
"""避雷修改 ID 名称 备注"""
|
||||
return_data = self._init_return_data()
|
||||
session_id = self._normalize_session_id(session_id)
|
||||
|
||||
data = await self._sql_db.select_one(
|
||||
"bilei",
|
||||
"id=?",
|
||||
(id,)
|
||||
"session_id=? AND id=?",
|
||||
(session_id, id),
|
||||
)
|
||||
|
||||
if not data:
|
||||
return_data["msg"] = "没有当前ID"
|
||||
return_data["msg"] = "当前会话中不存在该避雷记录"
|
||||
return return_data
|
||||
|
||||
# 获取系统时间
|
||||
@@ -163,8 +313,8 @@ class BiLeidata:
|
||||
"time": now,
|
||||
"user": user,
|
||||
},
|
||||
"id=?",
|
||||
(id,)
|
||||
"session_id=? AND id=?",
|
||||
(session_id, id),
|
||||
)
|
||||
|
||||
except FileNotFoundError as e:
|
||||
@@ -186,26 +336,27 @@ class BiLeidata:
|
||||
return return_data
|
||||
|
||||
|
||||
async def delete(self, id:int) -> Dict[str, Any]:
|
||||
async def delete(self, session_id: Any, id: int) -> Dict[str, Any]:
|
||||
"""避雷删除 ID"""
|
||||
return_data = self._init_return_data()
|
||||
session_id = self._normalize_session_id(session_id)
|
||||
|
||||
data = await self._sql_db.select_one(
|
||||
"bilei",
|
||||
"id=?",
|
||||
(id,)
|
||||
"session_id=? AND id=?",
|
||||
(session_id, id),
|
||||
)
|
||||
|
||||
if not data:
|
||||
return_data["msg"] = "没有当前ID"
|
||||
return_data["msg"] = "当前会话中不存在该避雷记录"
|
||||
return return_data
|
||||
|
||||
# 删除
|
||||
try:
|
||||
await self._sql_db.delete(
|
||||
"bilei",
|
||||
"id=?",
|
||||
(id,)
|
||||
"session_id=? AND id=?",
|
||||
(session_id, id),
|
||||
)
|
||||
|
||||
except FileNotFoundError as e:
|
||||
@@ -217,4 +368,4 @@ class BiLeidata:
|
||||
|
||||
return_data["code"] = 200
|
||||
|
||||
return return_data
|
||||
return return_data
|
||||
|
||||
Reference in New Issue
Block a user