🎨 添加作物收获次数表及增删查改,用户可查询作物收获次数

This commit is contained in:
Mualamx
2025-10-23 02:05:04 +08:00
parent 2f0023d468
commit 15c482f41f
5 changed files with 261 additions and 0 deletions
+48
View File
@@ -98,6 +98,7 @@ diuse_farm = on_alconna(
Subcommand("my-vipPoint", help_text="我的点券"), Subcommand("my-vipPoint", help_text="我的点券"),
Subcommand("farm-help", help_text="农场帮助"), Subcommand("farm-help", help_text="农场帮助"),
Subcommand("vipSeed-shop", Args["res?", MultiVar(str)], help_text="种子商店"), Subcommand("vipSeed-shop", Args["res?", MultiVar(str)], help_text="种子商店"),
Subcommand("my-plantcount", help_text="我的作物收获次数"),
), ),
priority=5, priority=5,
block=True, block=True,
@@ -776,3 +777,50 @@ async def _(session: Uninfo, res: Match[tuple[str, ...]]):
image = await g_pShopManager.getSeedShopImage(filterKey, page, 1) image = await g_pShopManager.getSeedShopImage(filterKey, page, 1)
await MessageUtils.build_message(image).send() await MessageUtils.build_message(image).send()
diuse_farm.shortcut(
"我的收获次数",
command="我的农场",
arguments=["my-plantcount"],
prefix=True,
)
@diuse_farm.assign("my-plantcount")
async def _(session: Uninfo, res: Match[tuple[str, ...]]):
uid = str(session.user.id)
player = await g_pToolManager.getPlayerByUid(uid)
if player is None or not await player.isRegistered():
await g_pToolManager.repeat()
return
if res.result is inspect._empty:
raw = []
else:
raw = res.result
filterKey: str | int | None = None
page: int = 1
if len(raw) >= 1 and raw[0] is not None:
first = raw[0]
if isinstance(first, str) and first.isdigit():
page = int(first)
else:
filterKey = first
if (
len(raw) >= 2
and raw[1] is not None
and isinstance(raw[1], str)
and raw[1].isdigit()
):
page = int(raw[1])
if filterKey is None:
image = await g_pFarmManager.getUserPlantCountImage(uid, page, 0)
else:
image = await g_pFarmManager.getUserPlantCountImage(uid, filterKey, page)
await MessageUtils.build_message(image).send()
+124
View File
@@ -0,0 +1,124 @@
from zhenxun.services.log import logger
from .database import CSqlManager
class CUserPlantCountDB(CSqlManager):
@classmethod
async def initDB(cls):
userPlantCount = {
"uid": "TEXT NOT NULL", # 用户Uid
"plant": "TEXT NOT NULL", # 植物名称
"count": "INTEGER NOT NULL DEFAULT 0", # 数量
"PRIMARY KEY": "(uid, plant)",
}
await cls.ensureTableSchema("userPlantCount", userPlantCount)
@classmethod
async def addUserPlantCountByUid(cls, uid: str, plant: str, count: int = 1) -> bool:
"""根据用户uid添加植物的收获次数
Args:
uid (str): 用户uid
plant (str): 植物名称
count (int): 数量
Returns:
bool: 是否添加成功
"""
try:
async with cls._transaction():
async with cls.m_pDB.execute(
"SELECT count FROM userPlantCount WHERE uid = ? AND plant = ?",
(uid, plant),
) as cursor:
row = await cursor.fetchone()
if row:
newCount = row[0] + count
await cls.m_pDB.execute(
"UPDATE userPlantCount SET count = ? WHERE uid = ? AND plant = ?",
(newCount, uid, plant),
)
else:
newCount = count
await cls.m_pDB.execute(
"INSERT INTO userPlantCount (uid, plant, count) VALUES (?, ?, ?)",
(uid, plant, count),
)
if newCount <= 0:
await cls.m_pDB.execute(
"DELETE FROM userPlantCount WHERE uid = ? AND plant = ?",
(uid, plant),
)
return True
except Exception as e:
logger.warning("addUserPlantByUid 失败!", e=e)
return False
@classmethod
async def getUserPlantCountByUid(cls, uid: str) -> dict:
"""根据用户Uid获取该用户的所有植物的收获次数
Args:
uid (str): 用户uid
Returns:
dict: 植物信息
"""
cursor = await cls.m_pDB.execute(
"SELECT plant, count FROM userPlantCount WHERE uid=?", (uid,)
)
rows = await cursor.fetchall()
return {row["plant"]: row["count"] for row in rows}
@classmethod
async def updateUserPlantCountByName(cls, uid: str, plant: str, count: int) -> bool:
"""根据植物名称更新植物的收获次数
Args:
uid (str): 用户uid
plant (str): 植物名称
count (int): 收获次数
Returns:
bool: 是否成功
"""
try:
if count <= 0:
return await cls.deleteUserPlantCountByName(uid, plant)
async with cls._transaction():
await cls.m_pDB.execute(
"UPDATE userPlantCount SET count = ? WHERE uid = ? AND plant = ?",
(count, uid, plant),
)
return True
except Exception as e:
logger.warning("updateUserPlantByName失败!", e=e)
return False
@classmethod
async def deleteUserPlantCountByName(cls, uid: str, plant: str) -> bool:
"""根据植物名称从植物仓库中删除植物
Args:
uid (str): 用户uid
seed (str): 种子名称
Returns:
bool: 是否成功
"""
try:
async with cls._transaction():
await cls.m_pDB.execute(
"DELETE FROM userPlantCount WHERE uid = ? AND plant = ?",
(uid, plant),
)
return True
except Exception as e:
logger.warning("deleteUserPlantCountByName 删除失败!", e=e)
return False
+4
View File
@@ -4,6 +4,7 @@ class CDBService:
from .database.user import CUserDB from .database.user import CUserDB
from .database.userItem import CUserItemDB from .database.userItem import CUserItemDB
from .database.userPlant import CUserPlantDB from .database.userPlant import CUserPlantDB
from .database.userPlantCount import CUserPlantCountDB
from .database.userSeed import CUserSeedDB from .database.userSeed import CUserSeedDB
from .database.userSign import CUserSignDB from .database.userSign import CUserSignDB
from .database.userSoil import CUserSoilDB from .database.userSoil import CUserSoilDB
@@ -33,6 +34,9 @@ class CDBService:
self.userSign = CUserSignDB() self.userSign = CUserSignDB()
await self.userSign.initDB() await self.userSign.initDB()
self.userPlantCount = CUserPlantCountDB()
await self.userPlantCount.initDB()
async def cleanup(self): async def cleanup(self):
await self.plant.cleanup() await self.plant.cleanup()
+84
View File
@@ -629,6 +629,15 @@ class CFarmManager:
uid, soilInfo["plantName"], number uid, soilInfo["plantName"], number
) )
# 统计收获次数
try:
await g_pDBService.userPlantCount.addUserPlantCountByUid(
uid, soilInfo["plantName"]
)
except Exception:
# 忽略统计异常,避免影响主流程
pass
# 如果到达收获次数上限 # 如果到达收获次数上限
if soilInfo["harvestCount"] + 1 >= plantInfo["crop"]: if soilInfo["harvestCount"] + 1 >= plantInfo["crop"]:
await g_pDBService.userSoil.updateUserSoil( await g_pDBService.userSoil.updateUserSoil(
@@ -1221,5 +1230,80 @@ class CFarmManager:
return f"兑换{num}点券成功,当前点券:{number},赠送点券:{giftPoints},当前农场币:{point}" return f"兑换{num}点券成功,当前点券:{number},赠送点券:{giftPoints},当前农场币:{point}"
@classmethod
async def getUserPlantCountImage(
cls, uid: str, filterKey: str | int = 1, num: int = 1
) -> bytes:
"""获取用户作物收获次数图片
Args:
filterKey (str|int):
- 字符串: 根据关键字筛选种子名称
- 整数: 翻至对应页(无筛选)
num (int, optional): 当 filterKey 为字符串时,用于指定页码。Defaults to 1.
Returns:
bytes: 返回商店图片bytes
"""
# 解析参数:区分筛选关键字和页码
filterStr = None
if isinstance(filterKey, int):
page = filterKey
else:
filterStr = filterKey
page = num
# 表头定义
columnName = [
"-",
"种子名称",
"收获次数",
]
# 查询用户作物收获次数(返回 dict: {plant: count})并根据筛选关键字过滤
plants = await g_pDBService.userPlantCount.getUserPlantCountByUid(uid) or {}
filteredPlants = []
for name, cnt in plants.items():
# 字符串筛选
if filterStr and filterStr not in name:
continue
filteredPlants.append({"plant": name, "count": cnt})
# 计算分页
totalCount = len(filteredPlants)
pageCount = math.ceil(totalCount / 15) if totalCount else 1
startIndex = (page - 1) * 15
pageItems = filteredPlants[startIndex : startIndex + 15]
# 构建数据行
dataList = []
for plant in pageItems:
# 图标处理
icon = ""
iconPath = g_sResourcePath / f"plant/{plant['plant']}/icon.png"
if iconPath.exists():
icon = (iconPath, 33, 33)
dataList.append(
[
icon,
plant["plant"], # 种子名称
plant["count"], # 收获次数
]
)
# 页码标题
title = f"收获次数 页数: {page}/{pageCount}"
# 渲染表格并返回图片bytes
result = await ImageTemplate.table_page(
title,
"",
columnName,
dataList,
)
return result.pic2bytes()
g_pFarmManager = CFarmManager() g_pFarmManager = CFarmManager()
+1
View File
@@ -41,6 +41,7 @@ g_sTranslation = {
"success": "✅ 农场开通成功!\n💼 初始资金:{point}农场币 🥳🎉", "success": "✅ 农场开通成功!\n💼 初始资金:{point}农场币 🥳🎉",
"repeat": "🎉 您已经开通农场啦~ 😄", "repeat": "🎉 您已经开通农场啦~ 😄",
"error": "⚠️ 开通失败,请稍后再试 💔", "error": "⚠️ 开通失败,请稍后再试 💔",
"already": "🚜 你已经开通农场啦~ 快去种田吧 🌱",
}, },
"buySeed": { "buySeed": {
"notSeed": "🌱 请在指令后跟需要购买的种子名称", "notSeed": "🌱 请在指令后跟需要购买的种子名称",