Merge pull request #11 from Mualamx/Beta
✨ 添加数据库字段(是否为点券作物,点券作物单价);实现点券购买种子;我的种子查询页面添加点券单价。
This commit is contained in:
commit
ac495ad6e9
@ -58,6 +58,12 @@ __plugin_meta__ = PluginMetadata(
|
||||
help="金币兑换农场币的倍数 默认值为: 2倍",
|
||||
default_value="2",
|
||||
),
|
||||
RegisterConfig(
|
||||
key="点券兑换倍数",
|
||||
value="2000",
|
||||
help="农场币兑换点券的倍数 比例为2000:1",
|
||||
default_value="2000",
|
||||
),
|
||||
RegisterConfig(
|
||||
key="手续费",
|
||||
value="0.2",
|
||||
|
||||
129
command.py
129
command.py
@ -85,6 +85,8 @@ diuse_farm = on_alconna(
|
||||
Subcommand("harvest", help_text="收获"),
|
||||
Subcommand("eradicate", help_text="铲除"),
|
||||
Subcommand("my-plant", help_text="我的作物"),
|
||||
Subcommand("lock-plant", Args["name?", str], help_text="作物加锁"),
|
||||
Subcommand("unlock-plant", Args["name?", str], help_text="作物解锁"),
|
||||
Subcommand("sell-plant", Args["name?", str]["num?", int], help_text="出售作物"),
|
||||
Subcommand("stealing", Args["target?", At], help_text="偷菜"),
|
||||
Subcommand("buy-point", Args["num?", int], help_text="购买农场币"),
|
||||
@ -92,6 +94,8 @@ diuse_farm = on_alconna(
|
||||
Subcommand("change-name", Args["name?", str], help_text="更改农场名"),
|
||||
Subcommand("sign-in", help_text="农场签到"),
|
||||
Subcommand("admin-up", Args["num?", int], help_text="农场下阶段"),
|
||||
Subcommand("point-to-vipPoint", Args["num?", int], help_text="点券兑换"),
|
||||
Subcommand("my-vipPoint", help_text="我的点券"),
|
||||
),
|
||||
priority=5,
|
||||
block=True,
|
||||
@ -328,6 +332,65 @@ async def _(session: Uninfo):
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
|
||||
diuse_farm.shortcut(
|
||||
"作物加锁(?P<name>)",
|
||||
command="我的农场",
|
||||
arguments=["lock-plant", "{name}"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@diuse_farm.assign("lock-plant")
|
||||
async def _(session: Uninfo, name: Match[str]):
|
||||
uid = str(session.user.id)
|
||||
|
||||
if not await g_pToolManager.isRegisteredByUid(uid):
|
||||
return
|
||||
|
||||
result = await g_pFarmManager.lockUserPlantByUid(uid, name.result, 1)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
|
||||
diuse_farm.shortcut(
|
||||
"作物解锁(?P<name>)",
|
||||
command="我的农场",
|
||||
arguments=["unlock-plant", "{name}"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@diuse_farm.assign("unlock-plant")
|
||||
async def _(session: Uninfo, name: Match[str]):
|
||||
uid = str(session.user.id)
|
||||
|
||||
if not await g_pToolManager.isRegisteredByUid(uid):
|
||||
return
|
||||
|
||||
result = await g_pFarmManager.lockUserPlantByUid(uid, name.result, 0)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
|
||||
diuse_farm.shortcut(
|
||||
"出售作物(?P<name>.*?)",
|
||||
command="我的农场",
|
||||
arguments=["sell-plant", "{name}"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@diuse_farm.assign("sell-plant")
|
||||
async def _(
|
||||
session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("num", -1)
|
||||
):
|
||||
uid = str(session.user.id)
|
||||
|
||||
if not await g_pToolManager.isRegisteredByUid(uid):
|
||||
return
|
||||
|
||||
result = await g_pShopManager.sellPlantByUid(uid, name.result, num.result)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
|
||||
reclamation = on_alconna(
|
||||
Alconna("开垦"),
|
||||
priority=5,
|
||||
@ -364,27 +427,6 @@ async def _(session: Uninfo):
|
||||
await MessageUtils.build_message(res).send(reply_to=True)
|
||||
|
||||
|
||||
diuse_farm.shortcut(
|
||||
"出售作物(?P<name>.*?)",
|
||||
command="我的农场",
|
||||
arguments=["sell-plant", "{name}"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@diuse_farm.assign("sell-plant")
|
||||
async def _(
|
||||
session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("num", -1)
|
||||
):
|
||||
uid = str(session.user.id)
|
||||
|
||||
if not await g_pToolManager.isRegisteredByUid(uid):
|
||||
return
|
||||
|
||||
result = await g_pShopManager.sellPlantByUid(uid, name.result, num.result)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
|
||||
diuse_farm.shortcut(
|
||||
"偷菜",
|
||||
command="我的农场",
|
||||
@ -606,3 +648,48 @@ async def _(session: Uninfo, num: Query[int] = AlconnaQuery("num", 0)):
|
||||
return
|
||||
|
||||
await g_pDBService.userSoil.nextPhase(uid, num.result)
|
||||
|
||||
|
||||
diuse_farm.shortcut(
|
||||
"点券兑换(.*?)",
|
||||
command="我的农场",
|
||||
arguments=["point-to-vipPoint"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@diuse_farm.assign("point-to-vipPoint")
|
||||
async def _(session: Uninfo, num: Query[int] = AlconnaQuery("num", 0)):
|
||||
if num.result <= 0:
|
||||
await MessageUtils.build_message("请在指令后跟需要购买点券的数量").finish(
|
||||
reply_to=True
|
||||
)
|
||||
|
||||
uid = str(session.user.id)
|
||||
|
||||
if not await g_pToolManager.isRegisteredByUid(uid):
|
||||
return
|
||||
|
||||
result = await g_pFarmManager.pointToVipPointByUid(uid, num.result)
|
||||
await MessageUtils.build_message(result).send(reply_to=True)
|
||||
|
||||
|
||||
diuse_farm.shortcut(
|
||||
"我的点券",
|
||||
command="我的农场",
|
||||
arguments=["my-vipPoint"],
|
||||
prefix=True,
|
||||
)
|
||||
|
||||
|
||||
@diuse_farm.assign("my-vipPoint")
|
||||
async def _(session: Uninfo):
|
||||
uid = str(session.user.id)
|
||||
vipPoint = await g_pDBService.user.getUserVipPointByUid(uid)
|
||||
|
||||
if not await g_pToolManager.isRegisteredByUid(uid):
|
||||
return
|
||||
|
||||
await MessageUtils.build_message(
|
||||
g_sTranslation["basic"]["vipPoint"].format(vipPoint=vipPoint)
|
||||
).send(reply_to=True)
|
||||
|
||||
@ -34,6 +34,7 @@ g_sTranslation = {
|
||||
"basic": {
|
||||
"notFarm": "尚未开通农场,快at我发送 开通农场 开通吧 🌱🚜",
|
||||
"point": "你的当前农场币为: {point} 🌾💰",
|
||||
"vipPoint": "你的当前点券为: {vipPoint} 🌾💰",
|
||||
},
|
||||
"register": {
|
||||
"success": "✅ 农场开通成功!\n💼 初始资金:{point}农场币 🥳🎉",
|
||||
@ -45,7 +46,9 @@ g_sTranslation = {
|
||||
"notNum": "❗️ 请输入购买数量!",
|
||||
"noLevel": "🔒 你的等级不够哦,努努力吧 💪",
|
||||
"noPoint": "💰 你的农场币不够哦~ 快速速氪金吧!💸",
|
||||
"noVipPoint": "💰 你的点券不够哦~ 快速速氪金吧!💸",
|
||||
"success": "✅ 成功购买{name},花费{total}农场币,剩余{point}农场币 🌾",
|
||||
"vipSuccess": "✅ 成功购买{name},花费{total}点券,剩余{point}点券 🌾",
|
||||
"errorSql": "❌ 购买失败,执行数据库错误!🛑",
|
||||
"error": "❌ 购买出错!请检查需购买的种子名称!🔍",
|
||||
},
|
||||
@ -121,4 +124,10 @@ g_sTranslation = {
|
||||
"aquamarine": "增产+32% 经验+32% 时间-28% 幸运+1%",
|
||||
"blackcrystal": "增产+32% 经验+40% 时间-28% 幸运+2%",
|
||||
},
|
||||
"lockPlant": {
|
||||
"noPlant": "很抱歉,你的作物仓库中没有该作物",
|
||||
"lockPlant": "加锁成功,现在{name}不会被一键售卖了",
|
||||
"unlockPlant": "解锁成功,现在{name}会被一键售卖了",
|
||||
"error": "未知错误",
|
||||
},
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ class CUserPlantDB(CSqlManager):
|
||||
"uid": "TEXT NOT NULL", # 用户Uid
|
||||
"plant": "TEXT NOT NULL", # 作物名称
|
||||
"count": "INTEGER NOT NULL DEFAULT 0", # 数量
|
||||
"isLock": "INTEGER NOT NULL DEFAULT 0", # 是否上锁 0=没有,非0=有
|
||||
"PRIMARY KEY": "(uid, plant)",
|
||||
}
|
||||
|
||||
@ -91,6 +92,27 @@ class CUserPlantDB(CSqlManager):
|
||||
logger.warning("getUserPlantByName 查询失败!", e=e)
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def checkUserPlantByName(cls, uid: str, plant: str) -> bool:
|
||||
"""根据作物名称判断用户作物仓库是否存在该作物
|
||||
|
||||
Args:
|
||||
uid (str): 用户uid
|
||||
plant (str): 作物名称
|
||||
|
||||
Returns:
|
||||
bool: 是否存在
|
||||
"""
|
||||
try:
|
||||
async with cls.m_pDB.execute(
|
||||
"SELECT * FROM userPlant WHERE uid = ? AND plant = ?", (uid, plant)
|
||||
) as cursor:
|
||||
row = await cursor.fetchone()
|
||||
return True if row else False
|
||||
except Exception as e:
|
||||
logger.warning("checkUserPlantByName 查询失败!", e=e)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def updateUserPlantByName(cls, uid: str, plant: str, count: int) -> bool:
|
||||
"""更新 userPlant 表中某个作物的数量
|
||||
@ -114,7 +136,51 @@ class CUserPlantDB(CSqlManager):
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning("updateUserPlantByName失败!", e=e)
|
||||
logger.warning("updateUserPlantByName 失败!", e=e)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def lockUserPlantByName(cls, uid: str, plant: str, lock: int) -> bool:
|
||||
"""给作物加锁,防止一键售卖
|
||||
|
||||
Args:
|
||||
uid (str): 用户uid
|
||||
plant (str): 作物名称
|
||||
lock (int): 0为解锁,非0均为加锁
|
||||
|
||||
Returns:
|
||||
bool: 是否加锁成功
|
||||
"""
|
||||
try:
|
||||
async with cls._transaction():
|
||||
await cls.m_pDB.execute(
|
||||
"UPDATE userPlant SET isLock = ? WHERE uid = ? AND plant = ?",
|
||||
(lock, uid, plant),
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning("lockUserPlantByName 失败!", e=e)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def checkPlantLockByName(cls, uid: str, plant: str) -> bool:
|
||||
"""根据作物名称判断是否加锁
|
||||
|
||||
Args:
|
||||
uid (str): 用户uid
|
||||
plant (str): 作物名称
|
||||
|
||||
Returns:
|
||||
bool: 是否加锁
|
||||
"""
|
||||
try:
|
||||
async with cls.m_pDB.execute(
|
||||
"SELECT isLock FROM userPlant WHERE uid = ? AND plant = ?", (uid, plant)
|
||||
) as cursor:
|
||||
row = await cursor.fetchone()
|
||||
return row[0] > 0 if row else False
|
||||
except Exception as e:
|
||||
logger.warning("checkUserPlantByName 查询失败!", e=e)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
|
||||
@ -165,7 +165,6 @@ class CUserSignDB(CSqlManager):
|
||||
if row["currentMonth"] == currentMonth
|
||||
else 1
|
||||
)
|
||||
totalSignDays = row["totalSignDays"]
|
||||
lastDate = row["lastSignDate"]
|
||||
prevDate = (
|
||||
g_pToolManager.dateTime().strptime(signDate, "%Y-%m-%d")
|
||||
@ -200,7 +199,7 @@ class CUserSignDB(CSqlManager):
|
||||
),
|
||||
)
|
||||
else:
|
||||
totalSignDays = 1
|
||||
monthSignDays = 1
|
||||
await cls.m_pDB.execute(
|
||||
"""
|
||||
INSERT INTO userSignSummary
|
||||
@ -211,7 +210,7 @@ class CUserSignDB(CSqlManager):
|
||||
uid,
|
||||
1,
|
||||
currentMonth,
|
||||
1,
|
||||
monthSignDays,
|
||||
signDate,
|
||||
1,
|
||||
1 if isSupplement else 0,
|
||||
@ -219,15 +218,13 @@ class CUserSignDB(CSqlManager):
|
||||
)
|
||||
|
||||
# 计算累签奖励
|
||||
reward = g_pJsonManager.m_pSign["continuou"].get(f"{totalSignDays}", None)
|
||||
|
||||
reward = g_pJsonManager.m_pSign["continuou"].get(f"{monthSignDays}", None)
|
||||
if reward:
|
||||
point += reward.get("point", 0)
|
||||
exp += reward.get("exp", 0)
|
||||
vipPoint = reward.get("vipPoint", 0)
|
||||
|
||||
plant = reward.get("plant", {})
|
||||
|
||||
if plant:
|
||||
for key, value in plant.items():
|
||||
await g_pDBService.userSeed.addUserSeedByUid(uid, key, value)
|
||||
|
||||
@ -24,7 +24,7 @@ class CUserSoilDB(CSqlManager):
|
||||
"weedStatus": "INTEGER DEFAULT 0", # 杂草状态 0=无杂草,1=有杂草
|
||||
"waterStatus": "INTEGER DEFAULT 0", # 缺水状态 0=不缺水,1=缺水
|
||||
"harvestCount": "INTEGER DEFAULT 0", # 收获次数
|
||||
"isSoilPlanted": "INTEGER DEFAULT NULL", # 是否种植作物
|
||||
"isSoilPlanted": "INTEGER DEFAULT NULL", # 是否种植作物 0=没有,1=有
|
||||
"PRIMARY KEY": "(uid, soilIndex)",
|
||||
}
|
||||
|
||||
|
||||
95
farm/farm.py
95
farm/farm.py
@ -159,6 +159,7 @@ class CFarmManager:
|
||||
if image:
|
||||
avatar = BuildImage(background=image)
|
||||
|
||||
await avatar.resize(0, 140, 150)
|
||||
await img.paste(avatar, (125, 85))
|
||||
|
||||
# 头像框
|
||||
@ -732,7 +733,15 @@ class CFarmManager:
|
||||
bytes: 返回图片
|
||||
"""
|
||||
data_list = []
|
||||
column_name = ["-", "作物名称", "数量", "单价", "总价", "是否可以上架交易行"]
|
||||
column_name = [
|
||||
"-",
|
||||
"作物名称",
|
||||
"数量",
|
||||
"单价",
|
||||
"总价",
|
||||
"是否上锁",
|
||||
"是否可以上架交易行",
|
||||
]
|
||||
|
||||
plant = await g_pDBService.userPlant.getUserPlantByUid(uid)
|
||||
|
||||
@ -763,7 +772,15 @@ class CFarmManager:
|
||||
|
||||
number = int(count) * plantInfo["price"]
|
||||
|
||||
data_list.append([icon, name, count, plantInfo["price"], number, sell])
|
||||
isLock = await g_pDBService.userPlant.checkPlantLockByName(uid, name)
|
||||
if isLock:
|
||||
lock = "上锁"
|
||||
else:
|
||||
lock = "未上锁"
|
||||
|
||||
data_list.append(
|
||||
[icon, name, count, plantInfo["price"], number, lock, sell]
|
||||
)
|
||||
|
||||
result = await ImageTemplate.table_page(
|
||||
"作物仓库",
|
||||
@ -774,6 +791,31 @@ class CFarmManager:
|
||||
|
||||
return result.pic2bytes()
|
||||
|
||||
@classmethod
|
||||
async def lockUserPlantByUid(cls, uid: str, name: str, lock: int) -> str:
|
||||
"""加/解 锁用户作物
|
||||
|
||||
Args:
|
||||
uid (str): 用户uid
|
||||
name (str): 作物名称
|
||||
lock (int): 0=解锁 非0=加锁
|
||||
|
||||
Returns:
|
||||
str: 返回
|
||||
"""
|
||||
# 先判断该用户仓库是否有该作物
|
||||
if not await g_pDBService.userPlant.checkUserPlantByName(uid, name):
|
||||
return g_sTranslation["lockPlant"]["noPlant"]
|
||||
|
||||
# 更改加锁状态
|
||||
if await g_pDBService.userPlant.lockUserPlantByName(uid, name, lock):
|
||||
if lock == 0:
|
||||
return g_sTranslation["lockPlant"]["unlockPlant"].format(name=name)
|
||||
else:
|
||||
return g_sTranslation["lockPlant"]["lockPlant"].format(name=name)
|
||||
else:
|
||||
return g_sTranslation["lockPlant"]["error"]
|
||||
|
||||
@classmethod
|
||||
async def stealing(cls, uid: str, target: str) -> str:
|
||||
"""偷菜
|
||||
@ -1106,5 +1148,54 @@ class CFarmManager:
|
||||
text=g_sTranslation["soilInfo"][soilLevelText],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def pointToVipPointByUid(cls, uid: str, num: int) -> str:
|
||||
"""点券兑换
|
||||
num:用户传参,即将兑换的点券
|
||||
pro:兑换倍数;兑换倍数乘以num即为需要消耗的农场币
|
||||
Args:
|
||||
uid (str): 用户Uid
|
||||
num (int): 兑换点券数量
|
||||
Returns:
|
||||
str: 返回结果
|
||||
兑换比例在配置文件中配置
|
||||
目前配置文件中默认是20倍
|
||||
100点券需要20000农场币
|
||||
赠送点券规则:
|
||||
小于2000点券:0
|
||||
2000-5000点券:100
|
||||
5000-50000点券:280
|
||||
大于50000点券:3000
|
||||
"""
|
||||
if num < 100:
|
||||
return "点券兑换数量必须大于等于100"
|
||||
|
||||
pro = int(Config.get_config("zhenxun_plugin_farm", "点券兑换倍数"))
|
||||
pro *= num
|
||||
|
||||
point = await g_pDBService.user.getUserPointByUid(uid)
|
||||
if point < pro:
|
||||
return f"你的农场币不足,当前农场币为{point},兑换还需要{pro - point}农场币"
|
||||
|
||||
p = await g_pDBService.user.getUserVipPointByUid(uid)
|
||||
|
||||
giftPoints: int
|
||||
if num < 2000:
|
||||
giftPoints = 0
|
||||
elif num < 5000:
|
||||
giftPoints = 100
|
||||
elif num < 50000:
|
||||
giftPoints = 280
|
||||
else:
|
||||
giftPoints = 3000
|
||||
|
||||
number = num + p + giftPoints
|
||||
await g_pDBService.user.updateUserVipPointByUid(uid, int(number))
|
||||
|
||||
point -= pro
|
||||
await g_pDBService.user.updateUserPointByUid(uid, int(point))
|
||||
|
||||
return f"兑换{num}点券成功,当前点券:{number},赠送点券:{giftPoints},当前农场币:{point}"
|
||||
|
||||
|
||||
g_pFarmManager = CFarmManager()
|
||||
|
||||
117
farm/help.py
Normal file
117
farm/help.py
Normal file
@ -0,0 +1,117 @@
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Template
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
from zhenxun.configs.path_config import DATA_PATH
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
from ..config import g_sResourcePath
|
||||
|
||||
|
||||
def rendeerHtmlToFile(path: Path | str, context: dict, output: Path | str) -> None:
|
||||
"""
|
||||
使用 Jinja2 渲染 HTML 模板并保存到指定文件,会自动创建父目录
|
||||
|
||||
Args:
|
||||
path (str): 模板 HTML 路径
|
||||
context (dict): 用于渲染的上下文字典
|
||||
output (str): 输出 HTML 文件路径
|
||||
"""
|
||||
templatePath = str(path)
|
||||
outputPath = str(output)
|
||||
|
||||
templateStr = Path(templatePath).read_text(encoding="utf-8")
|
||||
template = Template(templateStr)
|
||||
rendered = template.render(**context)
|
||||
|
||||
# 自动创建目录
|
||||
Path(outputPath).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
Path(outputPath).write_text(rendered, encoding="utf-8")
|
||||
|
||||
|
||||
async def screenshotHtmlToBytes(path: str) -> bytes:
|
||||
"""
|
||||
使用 Playwright 截图本地 HTML 文件并返回 PNG 图片字节数据
|
||||
|
||||
Args:
|
||||
path (str): 本地 HTML 文件路径
|
||||
|
||||
Returns:
|
||||
bytes: PNG 图片的原始字节内容
|
||||
"""
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch()
|
||||
page = await browser.new_page()
|
||||
file_url = Path(path).resolve().as_uri()
|
||||
await page.goto(file_url)
|
||||
image_bytes = await page.screenshot(full_page=True)
|
||||
await browser.close()
|
||||
|
||||
return image_bytes
|
||||
|
||||
|
||||
async def screenshotSave(path: str, save: str) -> None:
|
||||
"""
|
||||
使用 Playwright 渲染本地 HTML 并将截图保存到指定路径
|
||||
|
||||
Args:
|
||||
path (str): HTML 文件路径
|
||||
save (str): PNG 保存路径(如 output/image.png)
|
||||
"""
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch()
|
||||
page = await browser.new_page()
|
||||
|
||||
file_url = Path(path).resolve().as_uri()
|
||||
await page.goto(file_url)
|
||||
|
||||
# 确保保存目录存在
|
||||
Path(save).parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 截图并保存到本地文件
|
||||
await page.screenshot(path=save, full_page=True)
|
||||
await browser.close()
|
||||
|
||||
|
||||
async def createHelpImage() -> bool:
|
||||
templatePath = g_sResourcePath / "html/help.html"
|
||||
outputPath = DATA_PATH / "farm_res/html/help.html"
|
||||
|
||||
context = {
|
||||
"title": "功能指令总览",
|
||||
"data": [
|
||||
{
|
||||
"command": "开通农场",
|
||||
"description": "首次进入游戏开通农场",
|
||||
"tip": "",
|
||||
},
|
||||
{
|
||||
"command": "购买种子",
|
||||
"description": "从商店中购买可用种子",
|
||||
"tip": "",
|
||||
},
|
||||
{"command": "播种", "description": "将种子种入土地中", "tip": "先开垦土地"},
|
||||
{
|
||||
"command": "收获",
|
||||
"description": "收获成熟作物获得收益",
|
||||
"tip": "",
|
||||
},
|
||||
{
|
||||
"command": "偷菜",
|
||||
"description": "从好友农场中偷取成熟作物",
|
||||
"tip": "1",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
try:
|
||||
rendeerHtmlToFile(templatePath, context, outputPath)
|
||||
|
||||
image_bytes = await screenshot_html_to_bytes(html_output_path)
|
||||
except Exception as e:
|
||||
logger.warning("绘制农场帮助菜单失败", e=e)
|
||||
return False
|
||||
|
||||
return True
|
||||
41
farm/shop.py
41
farm/shop.py
@ -1,6 +1,5 @@
|
||||
import math
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.image_utils import ImageTemplate
|
||||
|
||||
from ..config import g_sResourcePath, g_sTranslation
|
||||
@ -33,7 +32,8 @@ class CShopManager:
|
||||
columnName = [
|
||||
"-",
|
||||
"种子名称",
|
||||
"种子单价",
|
||||
"农场币",
|
||||
"点券",
|
||||
"解锁等级",
|
||||
"果实单价",
|
||||
"收获经验",
|
||||
@ -77,7 +77,8 @@ class CShopManager:
|
||||
[
|
||||
icon,
|
||||
plant["name"], # 种子名称
|
||||
plant["buy"], # 种子单价
|
||||
plant["buy"], # 农场币种子单价
|
||||
plant["vipBuy"], # 点券种子单价
|
||||
plant["level"], # 解锁等级
|
||||
plant["price"], # 果实单价
|
||||
plant["experience"], # 收获经验
|
||||
@ -125,21 +126,32 @@ class CShopManager:
|
||||
if level[0] < int(plantInfo["level"]):
|
||||
return g_sTranslation["buySeed"]["noLevel"]
|
||||
|
||||
point = await g_pDBService.user.getUserPointByUid(uid)
|
||||
total = int(plantInfo["buy"]) * num
|
||||
|
||||
"""
|
||||
logger.debug(
|
||||
f"用户:{uid}购买{name},数量为{num}。用户农场币为{point},购买需要{total}"
|
||||
)
|
||||
|
||||
if point < total:
|
||||
return g_sTranslation["buySeed"]["noPoint"]
|
||||
"""
|
||||
if plantInfo["isVip"] == 1:
|
||||
vipPoint = await g_pDBService.user.getUserVipPointByUid(uid)
|
||||
total = int(plantInfo["vipBuy"]) * num
|
||||
if vipPoint < total:
|
||||
return g_sTranslation["buySeed"]["noVipPoint"]
|
||||
await g_pDBService.user.updateUserVipPointByUid(uid, vipPoint - total)
|
||||
else:
|
||||
point = await g_pDBService.user.getUserPointByUid(uid)
|
||||
total = int(plantInfo["buy"]) * num
|
||||
if point < total:
|
||||
return g_sTranslation["buySeed"]["noPoint"]
|
||||
await g_pDBService.user.updateUserPointByUid(uid, point - total)
|
||||
|
||||
if not await g_pDBService.userSeed.addUserSeedByUid(uid, name, num):
|
||||
return g_sTranslation["buySeed"]["errorSql"]
|
||||
if not await g_pDBService.userSeed.addUserSeedByUid(uid, name, num):
|
||||
return g_sTranslation["buySeed"]["errorSql"]
|
||||
|
||||
if plantInfo["isVip"] == 1:
|
||||
return g_sTranslation["buySeed"]["vipSuccess"].format(
|
||||
name=name, total=total, point=vipPoint - total
|
||||
)
|
||||
else:
|
||||
return g_sTranslation["buySeed"]["success"].format(
|
||||
name=name, total=total, point=point - total
|
||||
)
|
||||
@ -167,6 +179,13 @@ class CShopManager:
|
||||
|
||||
if name == "":
|
||||
for plantName, count in plant.items():
|
||||
isLock = await g_pDBService.userPlant.checkPlantLockByName(
|
||||
uid, plantName
|
||||
)
|
||||
|
||||
if isLock:
|
||||
continue
|
||||
|
||||
plantInfo = await g_pDBService.plant.getPlantByName(plantName)
|
||||
if not plantInfo:
|
||||
continue
|
||||
|
||||
Binary file not shown.
75
resource/html/help.html
Normal file
75
resource/html/help.html
Normal file
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ title }}</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #ffe4e9;
|
||||
font-family: "Microsoft YaHei", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
.content-box {
|
||||
background-color: #fff0f5;
|
||||
border-radius: 24px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
|
||||
width: 900px;
|
||||
}
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
th {
|
||||
background-color: #ffb6c1;
|
||||
font-weight: bold;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
td {
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
tr:not(:last-child) {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="content-box">
|
||||
<div class="title">{{ title }}</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>指令</th>
|
||||
<th>描述</th>
|
||||
<th>Tip</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entry in data %}
|
||||
<tr>
|
||||
<td>{{ entry.command }}</td>
|
||||
<td>{{ entry.description }}</td>
|
||||
<td>{{ entry.tip }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue
Block a user