223 lines
7.6 KiB
Python
223 lines
7.6 KiB
Python
from zhenxun.services.log import logger
|
||
|
||
from .database import CSqlManager
|
||
|
||
|
||
class CUserStealDB(CSqlManager):
|
||
@classmethod
|
||
async def initDB(cls):
|
||
userSteal = {
|
||
"uid": "TEXT NOT NULL", # 被偷用户Uid
|
||
"soilIndex": "INTEGER NOT NULL", # 被偷的地块索引 从1开始
|
||
"stealerUid": "TEXT NOT NULL", # 偷菜用户Uid
|
||
"stealCount": "INTEGER NOT NULL", # 被偷数量
|
||
"stealTime": "INTEGER NOT NULL", # 被偷时间
|
||
"PRIMARY KEY": "(uid, soilIndex, stealerUid)",
|
||
}
|
||
await cls.ensureTableSchema("userSteal", userSteal)
|
||
|
||
@classmethod
|
||
async def addStealRecord(
|
||
cls, uid: str, soilIndex: int, stealerUid: str, stealCount: int, stealTime: int
|
||
) -> bool:
|
||
"""添加偷菜记录
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
soilIndex (int): 被偷地块索引
|
||
stealerUid (str): 偷菜用户Uid
|
||
stealCount (int): 被偷数量
|
||
stealTime (int): 被偷时间(时间戳)
|
||
|
||
Returns:
|
||
bool: 操作是否成功
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
await cls.m_pDB.execute(
|
||
'INSERT INTO "userSteal"(uid, soilIndex, stealerUid, stealCount, stealTime) VALUES(?, ?, ?, ?, ?);',
|
||
(uid, soilIndex, stealerUid, stealCount, stealTime),
|
||
)
|
||
return True
|
||
except Exception as e:
|
||
logger.warning("添加偷菜记录失败", e=e)
|
||
return False
|
||
|
||
@classmethod
|
||
async def getStealRecordsByUid(cls, uid: str) -> dict:
|
||
"""根据用户Uid获取所有偷菜记录
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
|
||
Returns:
|
||
list: 偷菜记录字典列表,每条包含 soilIndex, stealerUid, stealCount, stealTime
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
cursor = await cls.m_pDB.execute(
|
||
'SELECT soilIndex, stealerUid, stealCount, stealTime FROM "userSteal" WHERE uid=?;',
|
||
(uid,),
|
||
)
|
||
row = await cursor.fetchone()
|
||
|
||
if not row:
|
||
return {}
|
||
|
||
result = dict(row)
|
||
return result
|
||
except Exception as e:
|
||
logger.warning("获取偷菜记录失败", e=e)
|
||
return {}
|
||
|
||
@classmethod
|
||
async def getStealRecord(cls, uid: str, soilIndex: int) -> list:
|
||
"""获取指定地块的所有偷菜记录
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
soilIndex (int): 被偷地块索引
|
||
|
||
Returns:
|
||
list: 偷菜记录字典列表,每条包含 stealerUid, stealCount, stealTime
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
cursor = await cls.m_pDB.execute(
|
||
'SELECT stealerUid, stealCount, stealTime FROM "userSteal" WHERE uid=? AND soilIndex=?;',
|
||
(uid, soilIndex),
|
||
)
|
||
rows = await cursor.fetchall()
|
||
return [
|
||
{
|
||
"uid": uid,
|
||
"soilIndex": soilIndex,
|
||
"stealerUid": row[0],
|
||
"stealCount": row[1],
|
||
"stealTime": row[2],
|
||
}
|
||
for row in rows
|
||
]
|
||
except Exception as e:
|
||
logger.warning("获取单地块偷菜记录失败", e=e)
|
||
return []
|
||
|
||
@classmethod
|
||
async def getTotalStolenCount(cls, uid: str, soilIndex: int) -> int:
|
||
"""计算指定地块被偷的总数量(所有用户偷取数量之和)
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
soilIndex (int): 被偷地块索引
|
||
|
||
Returns:
|
||
int: 被偷的总数量,如果无记录则返回 0
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
cursor = await cls.m_pDB.execute(
|
||
'SELECT SUM(stealCount) FROM "userSteal" WHERE uid=? AND soilIndex=?;',
|
||
(uid, soilIndex),
|
||
)
|
||
row = await cursor.fetchone()
|
||
return row[0] or 0 # type: ignore
|
||
except Exception as e:
|
||
logger.warning("计算总偷菜数量失败", e=e)
|
||
return 0
|
||
|
||
@classmethod
|
||
async def getStealerCount(cls, uid: str, soilIndex: int) -> int:
|
||
"""计算指定地块被多少人偷过(不同偷菜用户数量)
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
soilIndex (int): 被偷地块索引
|
||
|
||
Returns:
|
||
int: 偷菜者总数,如果无记录则返回 0
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
cursor = await cls.m_pDB.execute(
|
||
'SELECT COUNT(DISTINCT stealerUid) FROM "userSteal" WHERE uid=? AND soilIndex=?;',
|
||
(uid, soilIndex),
|
||
)
|
||
row = await cursor.fetchone()
|
||
return row[0] or 0 # type: ignore
|
||
except Exception as e:
|
||
logger.warning("计算偷菜者数量失败", e=e)
|
||
return 0
|
||
|
||
@classmethod
|
||
async def hasStealed(cls, uid: str, soilIndex: int, stealerUid: str) -> bool:
|
||
"""判断指定用户是否曾偷取过该地块
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
soilIndex (int): 被偷地块索引
|
||
stealerUid (str): 偷菜用户Uid
|
||
|
||
Returns:
|
||
bool: 若存在记录返回 True,否则返回 False
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
cursor = await cls.m_pDB.execute(
|
||
'SELECT 1 FROM "userSteal" WHERE uid=? AND soilIndex=? AND stealerUid=? LIMIT 1;',
|
||
(uid, soilIndex, stealerUid),
|
||
)
|
||
row = await cursor.fetchone()
|
||
return bool(row)
|
||
except Exception as e:
|
||
logger.warning("检查偷菜记录失败", e=e)
|
||
return False
|
||
|
||
@classmethod
|
||
async def updateStealRecord(
|
||
cls, uid: str, soilIndex: int, stealerUid: str, stealCount: int, stealTime: int
|
||
) -> bool:
|
||
"""更新偷菜记录的数量和时间
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
soilIndex (int): 被偷地块索引
|
||
stealerUid (str): 偷菜用户Uid
|
||
stealCount (int): 新的偷菜数量
|
||
stealTime (int): 新的偷菜时间(时间戳)
|
||
|
||
Returns:
|
||
bool: 操作是否成功
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
await cls.m_pDB.execute(
|
||
'UPDATE "userSteal" SET stealCount=?, stealTime=? WHERE uid=? AND soilIndex=? AND stealerUid=?;',
|
||
(stealCount, stealTime, uid, soilIndex, stealerUid),
|
||
)
|
||
return True
|
||
except Exception as e:
|
||
logger.warning("更新偷菜记录失败", e=e)
|
||
return False
|
||
|
||
@classmethod
|
||
async def deleteStealRecord(cls, uid: str, soilIndex: int) -> bool:
|
||
"""删除指定偷菜记录(只需被偷用户Uid和地块索引)
|
||
|
||
Args:
|
||
uid (str): 被偷用户Uid
|
||
soilIndex (int): 被偷地块索引
|
||
|
||
Returns:
|
||
bool: 删除是否成功
|
||
"""
|
||
try:
|
||
async with cls._transaction():
|
||
await cls.m_pDB.execute(
|
||
'DELETE FROM "userSteal" WHERE uid=? AND soilIndex=?;',
|
||
(uid, soilIndex),
|
||
)
|
||
return True
|
||
except Exception as e:
|
||
logger.warning("删除偷菜记录失败", e=e)
|
||
return False
|