2025-04-07 18:52:27 +08:00
|
|
|
|
import math
|
2025-03-16 19:11:05 +08:00
|
|
|
|
import os
|
2025-04-08 19:00:17 +08:00
|
|
|
|
import re
|
2025-04-22 19:42:09 +08:00
|
|
|
|
from contextlib import asynccontextmanager
|
2025-03-21 18:14:50 +08:00
|
|
|
|
from datetime import date, datetime, timedelta
|
2025-03-19 01:16:08 +08:00
|
|
|
|
from io import StringIO
|
2025-03-20 18:06:38 +08:00
|
|
|
|
from math import e
|
2025-04-10 18:25:20 +08:00
|
|
|
|
from typing import Any, Dict, List, Optional
|
2025-03-17 18:07:25 +08:00
|
|
|
|
|
2025-03-16 19:11:05 +08:00
|
|
|
|
import aiosqlite
|
|
|
|
|
|
|
|
|
|
|
|
from zhenxun.services.log import logger
|
|
|
|
|
|
|
2025-03-19 01:16:08 +08:00
|
|
|
|
from .config import g_pJsonManager, g_sDBFilePath, g_sDBPath
|
2025-03-17 18:07:25 +08:00
|
|
|
|
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
|
|
|
|
|
class CSqlManager:
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
g_sDBPath.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
2025-03-17 18:07:25 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def cleanup(cls):
|
|
|
|
|
|
if cls.m_pDB:
|
|
|
|
|
|
await cls.m_pDB.close()
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def init(cls) -> bool:
|
|
|
|
|
|
bIsExist = os.path.exists(g_sDBFilePath)
|
|
|
|
|
|
|
|
|
|
|
|
cls.m_pDB = await aiosqlite.connect(g_sDBFilePath)
|
2025-04-27 10:52:28 +08:00
|
|
|
|
cls.m_pDB.row_factory = aiosqlite.Row
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
|
|
|
|
|
await cls.checkDB()
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-04-22 19:42:09 +08:00
|
|
|
|
@asynccontextmanager
|
|
|
|
|
|
async def _transaction(cls):
|
|
|
|
|
|
await cls.m_pDB.execute("BEGIN;")
|
2025-04-08 19:00:17 +08:00
|
|
|
|
try:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
yield
|
|
|
|
|
|
except:
|
|
|
|
|
|
await cls.m_pDB.execute("ROLLBACK;")
|
2025-04-08 19:00:17 +08:00
|
|
|
|
raise
|
2025-04-22 19:42:09 +08:00
|
|
|
|
else:
|
|
|
|
|
|
await cls.m_pDB.execute("COMMIT;")
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
2025-04-08 19:00:17 +08:00
|
|
|
|
@classmethod
|
2025-04-27 10:52:28 +08:00
|
|
|
|
async def getTableInfo(cls, tableName: str) -> list:
|
|
|
|
|
|
if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', tableName):
|
|
|
|
|
|
raise ValueError(f"Illegal table name: {tableName}")
|
2025-04-22 19:42:09 +08:00
|
|
|
|
try:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
cursor = await cls.m_pDB.execute(f'PRAGMA table_info("{tableName}")')
|
2025-04-22 19:42:09 +08:00
|
|
|
|
rows = await cursor.fetchall()
|
|
|
|
|
|
return [{"name": row[1], "type": row[2]} for row in rows]
|
|
|
|
|
|
except aiosqlite.Error:
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-04-27 10:52:28 +08:00
|
|
|
|
async def ensureTableSchema(cls, tableName: str, columns: dict) -> bool:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
"""由AI生成
|
|
|
|
|
|
创建表或为已存在表添加缺失字段。
|
|
|
|
|
|
返回 True 表示有变更(创建或新增列),False 则无操作
|
2025-03-19 01:16:08 +08:00
|
|
|
|
|
2025-04-08 19:00:17 +08:00
|
|
|
|
Args:
|
|
|
|
|
|
tableName (_type_): 表名
|
|
|
|
|
|
columns (_type_): 字典
|
2025-03-19 01:16:08 +08:00
|
|
|
|
|
2025-04-08 19:00:17 +08:00
|
|
|
|
Returns:
|
|
|
|
|
|
_type_: _description_
|
|
|
|
|
|
"""
|
2025-03-19 01:16:08 +08:00
|
|
|
|
|
2025-04-27 10:52:28 +08:00
|
|
|
|
info = await cls.getTableInfo(tableName)
|
2025-04-22 19:42:09 +08:00
|
|
|
|
existing = {col['name']: col['type'].upper() for col in info}
|
2025-04-27 10:52:28 +08:00
|
|
|
|
desired = {k: v.upper() for k, v in columns.items() if k != "PRIMARY KEY"}
|
|
|
|
|
|
primaryKey = columns.get("PRIMARY KEY", "")
|
|
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
if not existing:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
colsDef = ", ".join(f'"{k}" {v}' for k, v in desired.items())
|
|
|
|
|
|
if primaryKey:
|
|
|
|
|
|
colsDef += f", PRIMARY KEY {primaryKey}"
|
|
|
|
|
|
await cls.m_pDB.execute(f'CREATE TABLE "{tableName}" ({colsDef});')
|
2025-04-22 19:42:09 +08:00
|
|
|
|
return True
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
|
|
|
|
|
toAdd = [k for k in desired if k not in existing]
|
|
|
|
|
|
toRemove = [k for k in existing if k not in desired]
|
|
|
|
|
|
typeMismatch = [k for k in desired if k in existing and existing[k] != desired[k]]
|
|
|
|
|
|
|
|
|
|
|
|
if toAdd and not toRemove and not typeMismatch:
|
|
|
|
|
|
for col in toAdd:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
await cls.m_pDB.execute(
|
2025-04-27 10:52:28 +08:00
|
|
|
|
f'ALTER TABLE "{tableName}" ADD COLUMN "{col}" {columns[col]}'
|
2025-04-22 19:42:09 +08:00
|
|
|
|
)
|
|
|
|
|
|
return True
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async with cls._transaction():
|
2025-04-27 10:52:28 +08:00
|
|
|
|
tmpTable = f"{tableName}_new"
|
|
|
|
|
|
colsDef = ", ".join(f'"{k}" {v}' for k, v in desired.items())
|
|
|
|
|
|
if primaryKey:
|
|
|
|
|
|
colsDef += f", PRIMARY KEY {primaryKey}"
|
|
|
|
|
|
await cls.m_pDB.execute(f'CREATE TABLE "{tmpTable}" ({colsDef});')
|
|
|
|
|
|
|
|
|
|
|
|
commonCols = [k for k in desired if k in existing]
|
|
|
|
|
|
if commonCols:
|
|
|
|
|
|
colsStr = ", ".join(f'"{c}"' for c in commonCols)
|
2025-04-22 19:42:09 +08:00
|
|
|
|
await cls.m_pDB.execute(
|
2025-04-27 10:52:28 +08:00
|
|
|
|
f'INSERT INTO "{tmpTable}" ({colsStr}) SELECT {colsStr} FROM "{tableName}";'
|
2025-04-22 19:42:09 +08:00
|
|
|
|
)
|
2025-04-27 10:52:28 +08:00
|
|
|
|
await cls.m_pDB.execute(f'DROP TABLE "{tableName}";')
|
|
|
|
|
|
await cls.m_pDB.execute(f'ALTER TABLE "{tmpTable}" RENAME TO "{tableName}";')
|
2025-04-08 19:00:17 +08:00
|
|
|
|
return True
|
2025-03-19 01:16:08 +08:00
|
|
|
|
|
2025-04-08 19:00:17 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def checkDB(cls) -> bool:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
#1. 用户表
|
2025-04-08 19:00:17 +08:00
|
|
|
|
userInfo = {
|
|
|
|
|
|
"uid": "INTEGER PRIMARY KEY AUTOINCREMENT",
|
|
|
|
|
|
"name": "TEXT NOT NULL",
|
|
|
|
|
|
"exp": "INTEGER DEFAULT 0",
|
|
|
|
|
|
"point": "INTEGER DEFAULT 0",
|
|
|
|
|
|
"soil": "INTEGER DEFAULT 3",
|
|
|
|
|
|
"stealing": "TEXT DEFAULT NULL"
|
|
|
|
|
|
}
|
2025-04-22 19:42:09 +08:00
|
|
|
|
#2. 土地表
|
2025-04-08 19:00:17 +08:00
|
|
|
|
userSoilInfo = {
|
|
|
|
|
|
"uid": "INTEGER PRIMARY KEY AUTOINCREMENT",
|
|
|
|
|
|
**{f"soil{i}": "TEXT DEFAULT ''" for i in range(1, 31)}
|
|
|
|
|
|
}
|
2025-04-22 19:42:09 +08:00
|
|
|
|
#3. 用户作物明细表
|
|
|
|
|
|
userPlant = {
|
|
|
|
|
|
"uid": "INTEGER NOT NULL",
|
|
|
|
|
|
"plant": "TEXT NOT NULL",
|
|
|
|
|
|
"count": "INTEGER NOT NULL DEFAULT 0",
|
|
|
|
|
|
#建联合主键保证每个品种一行
|
|
|
|
|
|
"PRIMARY KEY": "(uid, plant)"
|
|
|
|
|
|
}
|
|
|
|
|
|
#4. 用户种子明细表
|
|
|
|
|
|
userSeed = {
|
|
|
|
|
|
"uid": "INTEGER NOT NULL",
|
|
|
|
|
|
"seed": "TEXT NOT NULL",
|
|
|
|
|
|
"count": "INTEGER NOT NULL DEFAULT 0",
|
|
|
|
|
|
"PRIMARY KEY": "(uid, seed)"
|
|
|
|
|
|
}
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
#建表(或增列)
|
|
|
|
|
|
await cls.ensureTableSchema("user", userInfo)
|
|
|
|
|
|
await cls.ensureTableSchema("soil", userSoilInfo)
|
|
|
|
|
|
await cls.ensureTableSchema("userPlant", userPlant)
|
|
|
|
|
|
await cls.ensureTableSchema("userSeed", userSeed)
|
2025-03-19 01:16:08 +08:00
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def executeDB(cls, command: str) -> bool:
|
|
|
|
|
|
"""执行自定义SQL
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
command (str): SQL语句
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 是否执行成功
|
|
|
|
|
|
"""
|
|
|
|
|
|
if len(command) <= 0:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
logger.warning("数据库语句长度为空!")
|
2025-03-19 01:16:08 +08:00
|
|
|
|
return False
|
|
|
|
|
|
|
2025-03-16 19:11:05 +08:00
|
|
|
|
try:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(command)
|
2025-03-16 19:11:05 +08:00
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
logger.warning("数据库语句执行出错:" + command)
|
2025-03-16 19:11:05 +08:00
|
|
|
|
return False
|
|
|
|
|
|
|
2025-03-19 01:16:08 +08:00
|
|
|
|
@classmethod
|
2025-03-20 18:06:38 +08:00
|
|
|
|
async def initUserInfoByUid(cls, uid: str, name: str = "", exp: int = 0, point: int = 100):
|
|
|
|
|
|
"""初始化用户信息
|
2025-03-19 01:16:08 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-03-20 18:06:38 +08:00
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
name (str): 农场名称
|
|
|
|
|
|
exp (int): 农场经验
|
|
|
|
|
|
point (int): 农场币
|
2025-03-19 01:16:08 +08:00
|
|
|
|
"""
|
|
|
|
|
|
|
2025-03-19 18:00:50 +08:00
|
|
|
|
#用户信息
|
|
|
|
|
|
userInfo = f"""
|
2025-03-21 18:14:50 +08:00
|
|
|
|
INSERT INTO user (uid, name, exp, point, soil, stealing) VALUES ({uid}, '{name}', {exp}, {point}, 3, '{date.today()}|5')
|
2025-03-19 18:00:50 +08:00
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
#用户仓库
|
|
|
|
|
|
userStorehouse = f"""
|
|
|
|
|
|
INSERT INTO storehouse (uid) VALUES ({uid});
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
2025-03-20 18:06:38 +08:00
|
|
|
|
#用户土地
|
2025-03-19 18:00:50 +08:00
|
|
|
|
userSoilInfo = f"""
|
|
|
|
|
|
INSERT INTO soil (uid) VALUES ({uid});
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
if not await cls.executeDB(userInfo):
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
if not await cls.executeDB(userStorehouse):
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
if not await cls.executeDB(userSoilInfo):
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
2025-04-07 18:52:27 +08:00
|
|
|
|
return "开通农场成功"
|
2025-03-19 18:00:50 +08:00
|
|
|
|
|
2025-03-16 19:11:05 +08:00
|
|
|
|
@classmethod
|
2025-03-21 18:14:50 +08:00
|
|
|
|
async def getUserInfoByUid(cls, uid: str) -> dict:
|
2025-03-16 19:11:05 +08:00
|
|
|
|
"""根据用户Uid获取用户信息
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
list[dict]: 用户信息
|
|
|
|
|
|
"""
|
|
|
|
|
|
if len(uid) <= 0:
|
2025-03-21 18:14:50 +08:00
|
|
|
|
return {}
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
|
|
|
|
|
try:
|
2025-03-17 18:07:25 +08:00
|
|
|
|
async with cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT * FROM user WHERE uid = ?", (uid,)
|
|
|
|
|
|
) as cursor:
|
2025-03-16 19:11:05 +08:00
|
|
|
|
async for row in cursor:
|
2025-03-21 18:14:50 +08:00
|
|
|
|
userDict = {
|
2025-03-17 18:07:25 +08:00
|
|
|
|
"uid": row[0],
|
|
|
|
|
|
"name": row[1],
|
2025-03-18 18:39:02 +08:00
|
|
|
|
"exp": row[2],
|
2025-03-17 18:07:25 +08:00
|
|
|
|
"point": row[3],
|
2025-03-21 18:14:50 +08:00
|
|
|
|
"soil": row[4],
|
|
|
|
|
|
"stealing": row[5]
|
2025-03-16 19:11:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-21 18:14:50 +08:00
|
|
|
|
return userDict
|
|
|
|
|
|
return {}
|
2025-03-16 19:11:05 +08:00
|
|
|
|
except Exception as e:
|
2025-03-19 18:00:50 +08:00
|
|
|
|
logger.warning(f"getUserInfoByUid查询失败: {e}")
|
2025-03-21 18:14:50 +08:00
|
|
|
|
return {}
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-03-17 18:07:25 +08:00
|
|
|
|
async def getUserPointByUid(cls, uid: str) -> int:
|
2025-03-18 18:39:02 +08:00
|
|
|
|
"""根据用户Uid获取用户农场币
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int: 用户农场币
|
|
|
|
|
|
"""
|
2025-03-17 18:07:25 +08:00
|
|
|
|
if len(uid) <= 0:
|
|
|
|
|
|
return -1
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
2025-04-07 18:52:27 +08:00
|
|
|
|
async with cls.m_pDB.execute(f"SELECT point FROM user WHERE uid = {uid}") as cursor:
|
2025-03-17 18:07:25 +08:00
|
|
|
|
async for row in cursor:
|
|
|
|
|
|
return int(row[0])
|
2025-03-19 18:00:50 +08:00
|
|
|
|
|
|
|
|
|
|
return -1
|
2025-03-17 18:07:25 +08:00
|
|
|
|
except Exception as e:
|
2025-03-19 18:00:50 +08:00
|
|
|
|
logger.warning(f"getUserPointByUid查询失败: {e}")
|
2025-03-17 18:07:25 +08:00
|
|
|
|
return -1
|
|
|
|
|
|
|
2025-03-19 01:16:08 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def updateUserPointByUid(cls, uid: str, point: int) -> int:
|
|
|
|
|
|
"""根据用户Uid修改用户农场币
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
point (int): 要更新的新农场币数量(需 ≥ 0)
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int: 更新后的农场币数量(成功时),-1(失败时)
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
if len(uid) <= 0:
|
|
|
|
|
|
logger.warning("参数校验失败: uid为空或农场币值无效")
|
|
|
|
|
|
return -1
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
2025-04-10 18:25:20 +08:00
|
|
|
|
return await cls.executeDB(f"UPDATE user SET point = {point} WHERE uid = {uid}")
|
2025-03-19 01:16:08 +08:00
|
|
|
|
except Exception as e:
|
2025-04-07 18:52:27 +08:00
|
|
|
|
logger.error(f"金币更新失败: {e}")
|
2025-03-19 01:16:08 +08:00
|
|
|
|
return -1
|
|
|
|
|
|
|
2025-03-21 00:25:20 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getUserExpByUid(cls, uid: str) -> int:
|
|
|
|
|
|
"""根据用户Uid获取用户经验
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int: 用户经验值
|
|
|
|
|
|
"""
|
|
|
|
|
|
if len(uid) <= 0:
|
|
|
|
|
|
return -1
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
2025-04-07 18:52:27 +08:00
|
|
|
|
async with cls.m_pDB.execute(f"SELECT exp FROM user WHERE uid = {uid}") as cursor:
|
2025-03-21 00:25:20 +08:00
|
|
|
|
async for row in cursor:
|
|
|
|
|
|
return int(row[0])
|
|
|
|
|
|
|
|
|
|
|
|
return -1
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.warning(f"getUserLevelByUid查询失败: {e}")
|
|
|
|
|
|
return -1
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def UpdateUserExpByUid(cls, uid: str, exp: int) -> bool:
|
|
|
|
|
|
"""根据用户Uid刷新用户经验
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 是否成功
|
|
|
|
|
|
"""
|
|
|
|
|
|
if len(uid) <= 0:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
2025-04-07 18:52:27 +08:00
|
|
|
|
sql = f"UPDATE user SET exp = '{exp}' WHERE uid = {uid}"
|
2025-03-21 00:25:20 +08:00
|
|
|
|
|
|
|
|
|
|
return await cls.executeDB(sql)
|
|
|
|
|
|
|
2025-03-18 18:39:02 +08:00
|
|
|
|
@classmethod
|
2025-04-07 18:52:27 +08:00
|
|
|
|
async def getUserLevelByUid(cls, uid: str) -> tuple[int, int, int]:
|
2025-03-18 18:39:02 +08:00
|
|
|
|
"""根据用户Uid获取用户等级
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-07 18:52:27 +08:00
|
|
|
|
tuple[int, int, int]: (当前等级, 下级所需经验, 当前等级剩余经验)
|
2025-03-18 18:39:02 +08:00
|
|
|
|
"""
|
|
|
|
|
|
if len(uid) <= 0:
|
2025-04-07 18:52:27 +08:00
|
|
|
|
return -1, -1, -1
|
2025-03-18 18:39:02 +08:00
|
|
|
|
|
|
|
|
|
|
try:
|
2025-04-07 18:52:27 +08:00
|
|
|
|
async with cls.m_pDB.execute(f"SELECT exp FROM user WHERE uid = {uid}") as cursor:
|
2025-03-18 18:39:02 +08:00
|
|
|
|
async for row in cursor:
|
|
|
|
|
|
exp = int(row[0])
|
|
|
|
|
|
|
2025-04-10 18:25:20 +08:00
|
|
|
|
level = exp // 200
|
2025-04-07 18:52:27 +08:00
|
|
|
|
nextLevelExp = 200 * (level + 1)
|
2025-03-19 01:16:08 +08:00
|
|
|
|
|
2025-04-10 18:25:20 +08:00
|
|
|
|
currentLevelExp = level * 200
|
2025-04-07 18:52:27 +08:00
|
|
|
|
remainingExp = exp - currentLevelExp
|
|
|
|
|
|
|
|
|
|
|
|
return level, nextLevelExp, remainingExp
|
|
|
|
|
|
|
|
|
|
|
|
return -1, -1, -1
|
2025-03-18 18:39:02 +08:00
|
|
|
|
except Exception as e:
|
2025-03-19 18:00:50 +08:00
|
|
|
|
logger.warning(f"getUserLevelByUid查询失败: {e}")
|
2025-04-07 18:52:27 +08:00
|
|
|
|
return -1, -1, -1
|
2025-03-18 18:39:02 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getUserSoilByUid(cls, uid: str) -> int:
|
|
|
|
|
|
"""根据用户Uid获取解锁地块
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int: 解锁几块地
|
|
|
|
|
|
"""
|
|
|
|
|
|
if len(uid) <= 0:
|
2025-03-21 18:14:50 +08:00
|
|
|
|
return 0
|
2025-03-18 18:39:02 +08:00
|
|
|
|
|
2025-04-07 18:52:27 +08:00
|
|
|
|
async with cls.m_pDB.execute(f"SELECT soil FROM user WHERE uid = {uid}") as cursor:
|
2025-03-21 18:14:50 +08:00
|
|
|
|
async for row in cursor:
|
2025-04-07 18:52:27 +08:00
|
|
|
|
if not row[0]:
|
2025-03-21 18:14:50 +08:00
|
|
|
|
return 0
|
|
|
|
|
|
else:
|
|
|
|
|
|
return int(row[0])
|
2025-03-18 18:39:02 +08:00
|
|
|
|
|
2025-03-21 18:14:50 +08:00
|
|
|
|
return 0
|
2025-03-18 18:39:02 +08:00
|
|
|
|
|
2025-03-20 00:45:05 +08:00
|
|
|
|
@classmethod
|
2025-03-20 18:06:38 +08:00
|
|
|
|
async def getUserSoilStatusBySoilID(cls, uid: str, soil: str) -> tuple[bool, str]:
|
2025-03-20 00:45:05 +08:00
|
|
|
|
"""根据土地块获取用户土地状态
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
2025-03-20 18:06:38 +08:00
|
|
|
|
soil (str): 土地id
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-03-20 18:06:38 +08:00
|
|
|
|
tuple[bool, str]: [是否可以播种,土地信息]
|
2025-03-20 00:45:05 +08:00
|
|
|
|
"""
|
|
|
|
|
|
if len(uid) <= 0:
|
2025-03-20 18:06:38 +08:00
|
|
|
|
return False, ""
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
2025-04-07 18:52:27 +08:00
|
|
|
|
async with cls.m_pDB.execute(f"SELECT {soil} FROM soil WHERE uid = {uid}") as cursor:
|
2025-03-20 00:45:05 +08:00
|
|
|
|
async for row in cursor:
|
2025-03-20 18:06:38 +08:00
|
|
|
|
if row[0] == None or len(row[0]) <= 0:
|
|
|
|
|
|
return True, ""
|
|
|
|
|
|
else:
|
|
|
|
|
|
return False, row[0]
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
2025-03-20 18:06:38 +08:00
|
|
|
|
return False, ""
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-03-21 18:14:50 +08:00
|
|
|
|
async def updateUserSoilStatusByPlantName(cls, uid: str, soil: str,
|
|
|
|
|
|
plant: str = "",
|
|
|
|
|
|
status: int = 0) -> bool:
|
2025-03-20 18:06:38 +08:00
|
|
|
|
"""根据种子名称使用户播种
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户Uid
|
|
|
|
|
|
soil (str): 土地id
|
|
|
|
|
|
plant (str): 种子名称
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 是否更新成功
|
|
|
|
|
|
"""
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
|
|
|
|
|
if len(uid) <= 0:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
2025-03-21 00:25:20 +08:00
|
|
|
|
if len(plant) <= 0 and status == 4:
|
2025-03-21 18:14:50 +08:00
|
|
|
|
s = f",,,{status},"
|
2025-03-21 00:25:20 +08:00
|
|
|
|
elif len(plant) <= 0 and status != 4:
|
|
|
|
|
|
s = ""
|
2025-03-20 18:06:38 +08:00
|
|
|
|
else:
|
|
|
|
|
|
#获取种子信息 这里能崩我吃
|
2025-04-09 17:14:37 +08:00
|
|
|
|
plantInfo = g_pJsonManager.m_pPlant['plant'][plant]
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
2025-03-20 18:06:38 +08:00
|
|
|
|
currentTime = datetime.now()
|
2025-04-07 18:52:27 +08:00
|
|
|
|
newTime = currentTime + timedelta(hours=int(plantInfo['time']))
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
2025-04-09 17:14:37 +08:00
|
|
|
|
#0: 种子名称
|
|
|
|
|
|
#1: 种下时间
|
|
|
|
|
|
#2: 预计成熟时间
|
|
|
|
|
|
#3: 地状态:0:无 1:长草 2:生虫 3:缺水 4:枯萎
|
|
|
|
|
|
#4: 是否被偷 示例:QQ号-偷取数量|QQ号-偷取数量
|
|
|
|
|
|
#5: 土地等级 0:普通 1:红土地 2:黑土地 3:金土地 4:紫晶土地 5:蓝晶土地 6:黑晶土地
|
|
|
|
|
|
s = f"{plant},{int(currentTime.timestamp())},{int(newTime.timestamp())},{status},,"
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
2025-04-07 18:52:27 +08:00
|
|
|
|
sql = f"UPDATE soil SET {soil} = '{s}' WHERE uid = {uid}"
|
2025-03-20 00:45:05 +08:00
|
|
|
|
|
|
|
|
|
|
return await cls.executeDB(sql)
|
|
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
|
2025-03-17 18:07:25 +08:00
|
|
|
|
@classmethod
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async def addUserSeedByUid(cls, uid: str, seed: str, count: int = 1) -> bool:
|
|
|
|
|
|
"""根据用户uid添加种子信息
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
uid (str): 用户uid
|
|
|
|
|
|
seed (str): 种子名称
|
|
|
|
|
|
count (int): 数量
|
2025-03-16 19:11:05 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
bool: 是否添加成功
|
2025-03-16 19:11:05 +08:00
|
|
|
|
"""
|
2025-03-20 18:06:38 +08:00
|
|
|
|
try:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
#检查是否已存在该种子
|
|
|
|
|
|
async with cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT count FROM userSeed WHERE uid = ? AND seed = ?",
|
|
|
|
|
|
(uid, seed)
|
|
|
|
|
|
) as cursor:
|
|
|
|
|
|
row = await cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
if row:
|
|
|
|
|
|
#如果种子已存在,则更新数量
|
|
|
|
|
|
newCount = row[0] + count
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"UPDATE userSeed SET count = ? WHERE uid = ? AND seed = ?",
|
|
|
|
|
|
(newCount, uid, seed)
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
#如果种子不存在,则插入新记录
|
|
|
|
|
|
newCount = count
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"INSERT INTO userSeed (uid, seed, count) VALUES (?, ?, ?)",
|
|
|
|
|
|
(uid, seed, count)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
#如果种子数量为 0,删除记录
|
|
|
|
|
|
if newCount <= 0:
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"DELETE FROM userSeed WHERE uid = ? AND seed = ?",
|
|
|
|
|
|
(uid, seed)
|
|
|
|
|
|
)
|
|
|
|
|
|
return True
|
2025-03-20 18:06:38 +08:00
|
|
|
|
except Exception as e:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
logger.warning(f"真寻农场addUserSeedByUid 失败: {e}")
|
|
|
|
|
|
return False
|
2025-03-20 18:06:38 +08:00
|
|
|
|
|
2025-04-10 18:25:20 +08:00
|
|
|
|
@classmethod
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async def getUserSeedByName(cls, uid: str, seed: str) -> Optional[int]:
|
|
|
|
|
|
"""根据种子名称获取种子数量
|
2025-04-10 18:25:20 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
uid (str): 用户uid
|
|
|
|
|
|
seed (str): 种子名称
|
2025-04-10 18:25:20 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
Optional[int]: 种子数量
|
2025-04-10 18:25:20 +08:00
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async with cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT count FROM userSeed WHERE uid = ? AND seed = ?",
|
|
|
|
|
|
(uid, seed)
|
|
|
|
|
|
) as cursor:
|
|
|
|
|
|
row = await cursor.fetchone()
|
|
|
|
|
|
return row[0] if row else None
|
2025-04-10 18:25:20 +08:00
|
|
|
|
except Exception as e:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
logger.warning(f"真寻农场getUserSeedByName 查询失败: {e}")
|
|
|
|
|
|
return None
|
2025-04-10 18:25:20 +08:00
|
|
|
|
|
2025-03-20 18:06:38 +08:00
|
|
|
|
@classmethod
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async def getUserSeedByUid(cls, uid: str) -> dict:
|
|
|
|
|
|
"""根据用户Uid获取仓库全部种子信息
|
2025-03-20 18:06:38 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
uid (str): 用户uid
|
2025-03-20 18:06:38 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
dict: 种子信息
|
2025-03-20 18:06:38 +08:00
|
|
|
|
"""
|
|
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
cursor = await cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT seed, count FROM userSeed WHERE uid=?",
|
|
|
|
|
|
(uid,)
|
|
|
|
|
|
)
|
|
|
|
|
|
rows = await cursor.fetchall()
|
|
|
|
|
|
return {row["seed"]: row["count"] for row in rows}
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async def updateUserSeedByName(cls, uid: str, seed: str, count: int) -> bool:
|
|
|
|
|
|
"""根据种子名称更新种子数量
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
uid (str): 用户uid
|
2025-04-07 18:52:27 +08:00
|
|
|
|
seed (str): 种子名称
|
2025-04-22 19:42:09 +08:00
|
|
|
|
count (int): 种子数量
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
bool: 是否成功
|
2025-04-07 18:52:27 +08:00
|
|
|
|
"""
|
2025-04-22 19:42:09 +08:00
|
|
|
|
try:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
if count <= 0:
|
|
|
|
|
|
return await cls.deleteUserSeedByName(uid, seed)
|
|
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"UPDATE userSeed SET count = ? WHERE uid = ? AND seed = ?",
|
|
|
|
|
|
(count, uid, seed)
|
|
|
|
|
|
)
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
logger.warning(f"真寻农场updateUserSeedByName失败:{e}")
|
2025-04-07 18:52:27 +08:00
|
|
|
|
return False
|
|
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def deleteUserSeedByName(cls, uid: str, seed: str) -> bool:
|
|
|
|
|
|
"""根据种子名称从种子仓库中删除种子
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户uid
|
|
|
|
|
|
seed (str): 种子名称
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 是否成功
|
|
|
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"DELETE FROM userSeed WHERE uid = ? AND seed = ?",
|
|
|
|
|
|
(uid, seed)
|
|
|
|
|
|
)
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.warning(f"真寻农场deleteUserSeedByName 删除失败: {e}")
|
|
|
|
|
|
return False
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def addUserPlantByUid(cls, uid: str, plant: str, count: int = 1) -> bool:
|
|
|
|
|
|
"""根据用户uid添加作物信息
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户uid
|
|
|
|
|
|
plant (str): 作物名称
|
|
|
|
|
|
count (int): 数量
|
2025-03-20 18:06:38 +08:00
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 是否添加成功
|
|
|
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
#检查是否已存在该作物
|
|
|
|
|
|
async with cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT count FROM userPlant WHERE uid = ? AND plant = ?",
|
|
|
|
|
|
(uid, plant)
|
|
|
|
|
|
) as cursor:
|
|
|
|
|
|
row = await cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
if row:
|
|
|
|
|
|
#如果作物已存在,则更新数量
|
|
|
|
|
|
new_count = row[0] + count
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"UPDATE userPlant SET count = ? WHERE uid = ? AND plant = ?",
|
|
|
|
|
|
(new_count, uid, plant)
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
#如果作物不存在,则插入新记录
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"INSERT INTO userPlant (uid, plant, count) VALUES (?, ?, ?)",
|
|
|
|
|
|
(uid, plant, count)
|
|
|
|
|
|
)
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.warning(f"真寻农场addUserPlantByUid 失败: {e}")
|
|
|
|
|
|
return False
|
2025-03-20 18:06:38 +08:00
|
|
|
|
|
2025-04-27 10:52:28 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getUserPlantByUid(cls, uid: str) -> Dict[str, int]:
|
|
|
|
|
|
"""根据用户uid获取全部作物信息
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户uid
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Dict[str, int]: 作物名称和数量
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor = await cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT plant, count FROM userPlant WHERE uid=?",
|
|
|
|
|
|
(uid,)
|
|
|
|
|
|
)
|
|
|
|
|
|
rows = await cursor.fetchall()
|
|
|
|
|
|
return {row["plant"]: row["count"] for row in rows}
|
|
|
|
|
|
|
2025-03-20 18:06:38 +08:00
|
|
|
|
@classmethod
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async def getUserPlantByName(cls, uid: str, plant: str) -> Optional[int]:
|
|
|
|
|
|
"""根据作物名称获取用户的作物数量
|
2025-03-20 18:06:38 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
uid (str): 用户uid
|
|
|
|
|
|
plant (str): 作物名称
|
2025-03-20 18:06:38 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
Optional[int]: 作物数量
|
2025-03-20 18:06:38 +08:00
|
|
|
|
"""
|
2025-03-16 19:11:05 +08:00
|
|
|
|
try:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async with cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT count FROM userPlant WHERE uid = ? AND plant = ?",
|
|
|
|
|
|
(uid, plant)
|
|
|
|
|
|
) as cursor:
|
|
|
|
|
|
row = await cursor.fetchone()
|
|
|
|
|
|
return row[0] if row else None
|
2025-03-16 19:11:05 +08:00
|
|
|
|
except Exception as e:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
logger.warning(f"真寻农场getUserPlantByName 查询失败: {e}")
|
|
|
|
|
|
return None
|
2025-03-19 18:00:50 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-04-27 10:52:28 +08:00
|
|
|
|
async def updateUserPlantByName(cls, uid: str, plant: str, count: int) -> bool:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
"""更新 userPlant 表中某个作物的数量
|
2025-03-19 18:00:50 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
uid (str): 用户uid
|
2025-03-20 18:06:38 +08:00
|
|
|
|
plant (str): 作物名称
|
2025-04-22 19:42:09 +08:00
|
|
|
|
count (int): 新的作物数量
|
2025-03-19 18:00:50 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
bool: 是否更新成功
|
2025-03-19 18:00:50 +08:00
|
|
|
|
"""
|
2025-04-22 19:42:09 +08:00
|
|
|
|
try:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
if count <= 0:
|
|
|
|
|
|
return await cls.deleteUserPlantByName(uid, plant)
|
|
|
|
|
|
|
2025-04-22 19:42:09 +08:00
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"UPDATE userPlant SET count = ? WHERE uid = ? AND plant = ?",
|
|
|
|
|
|
(count, uid, plant)
|
|
|
|
|
|
)
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
logger.warning(f"真寻农场updateUserPlantByName失败:{e}")
|
2025-03-17 18:07:25 +08:00
|
|
|
|
return False
|
2025-03-18 18:39:02 +08:00
|
|
|
|
|
2025-04-07 18:52:27 +08:00
|
|
|
|
@classmethod
|
2025-04-27 10:52:28 +08:00
|
|
|
|
async def deleteUserPlantByName(cls, uid: str, plant: str) -> bool:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
"""从 userPlant 表中删除某个作物记录
|
2025-04-07 18:52:27 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
uid (str): 用户uid
|
2025-04-07 18:52:27 +08:00
|
|
|
|
plant (str): 作物名称
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-22 19:42:09 +08:00
|
|
|
|
bool: 是否删除成功
|
2025-04-07 18:52:27 +08:00
|
|
|
|
"""
|
2025-04-22 19:42:09 +08:00
|
|
|
|
try:
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"DELETE FROM userPlant WHERE uid = ? AND plant = ?",
|
|
|
|
|
|
(uid, plant)
|
|
|
|
|
|
)
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
logger.warning(f"真寻农场deleteUserPlantByName 失败: {e}")
|
2025-04-07 18:52:27 +08:00
|
|
|
|
return False
|
|
|
|
|
|
|
2025-03-18 18:39:02 +08:00
|
|
|
|
g_pSqlManager = CSqlManager()
|