更新数据库逻辑

This commit is contained in:
Art_Sakura 2025-04-27 10:52:28 +08:00
parent 4cd0302426
commit 719494e4e5
19 changed files with 407 additions and 199 deletions

View File

@ -28,7 +28,7 @@ __plugin_meta__ = PluginMetadata(
收获 收获
铲除 铲除
我的作物 我的作物
出售作物 [作物/种子名称] [数量] 出售作物 [作物/种子名称] [数量] (不填写作物
偷菜 at 偷菜 at
开垦 开垦
购买农场币 [数量] 数量为消耗金币的数量 购买农场币 [数量] 数量为消耗金币的数量

View File

@ -8,80 +8,164 @@
{ {
"4": "4":
{ {
"level": 2, "level": 2,
"point": 800, "point": 800,
"item": [] "item": []
}, },
"5": "5":
{ {
"level": 3, "level": 3,
"point": 1300, "point": 1300,
"item": [] "item": []
}, },
"6": "6":
{ {
"level": 5, "level": 5,
"point": 3200, "point": 3200,
"item": [] "item": []
}, },
"7": "7":
{ {
"level": 7, "level": 7,
"point": 5500, "point": 5500,
"item": [] "item": []
}, },
"8": "8":
{ {
"level": 9, "level": 9,
"point": 12000, "point": 12000,
"item": [] "item": []
}, },
"9": "9":
{ {
"level": 15, "level": 11,
"point": 19800, "point": 19800,
"item": [] "item": []
}, },
"10": "10":
{ {
"level":3, "level": 13,
"point": 3000, "point": 30000,
"item": [] "item": []
}, },
"11": "11":
{ {
"level":3, "level": 15,
"point": 3000, "point": 50000,
"item": [] "item": []
}, },
"12": "12":
{ {
"level":3, "level": 17,
"point": 3000, "point": 70000,
"item": [] "item": []
}, },
"13": "13":
{ {
"level":3, "level": 19,
"point": 3000, "point": 90000,
"item": [] "item": []
}, },
"14": "14":
{ {
"level":3, "level": 21,
"point": 3000, "point": 130000,
"item": [] "item": []
}, },
"15": "15":
{ {
"level":3, "level": 23,
"point": 3000, "point": 150000,
"item": [] "item": []
}, },
"16": "16":
{ {
"level":3, "level": 25,
"point": 3000, "point": 180000,
"item": []
},
"17":
{
"level": 27,
"point": 230000,
"item": []
},
"18":
{
"level": 29,
"point": 300000,
"item": []
},
"19":
{
"level": 31,
"point": 500000,
"item": []
},
"20":
{
"level": 33,
"point": 850000,
"item": []
},
"21":
{
"level": 36,
"point": 1100000,
"item": []
},
"22":
{
"level": 39,
"point": 1300000,
"item": []
},
"23":
{
"level": 42,
"point": 1500000,
"item": []
},
"24":
{
"level": 45,
"point": 1700000,
"item": []
},
"25":
{
"level": 48,
"point": 2000000,
"item": []
},
"26":
{
"level": 51,
"point": 2200000,
"item": []
},
"27":
{
"level": 54,
"point": 2800000,
"item": []
},
"28":
{
"level": 57,
"point": 3500000,
"item": []
},
"29":
{
"level": 60,
"point": 4300000,
"item": []
},
"30":
{
"level": 70,
"point": 5200000,
"item": [] "item": []
} }
} }

View File

@ -3,10 +3,11 @@
"zhuShi": "zhuShi":
[ [
"level: 解锁等级", "level: 解锁等级",
"buy: 购买价格",
"limit: 限制等级 0普通土地 1红土地 2黄土地 3黑土地", "limit: 限制等级 0普通土地 1红土地 2黄土地 3黑土地",
"experience: 收获经验", "experience: 收获经验",
"harvest: 收获数量", "harvest: 收获数量",
"price: 价", "price: 果实售价",
"time: 成熟时间 小时", "time: 成熟时间 小时",
"crop: 作物可以收几次", "crop: 作物可以收几次",
"again: 再次成熟时间 单位:小时", "again: 再次成熟时间 单位:小时",
@ -19,6 +20,7 @@
"胡萝卜": "胡萝卜":
{ {
"level": 0, "level": 0,
"buy": 163,
"limit": 0, "limit": 0,
"experience": 18, "experience": 18,
"harvest": 17, "harvest": 17,
@ -33,6 +35,7 @@
"白萝卜": "白萝卜":
{ {
"level": 0, "level": 0,
"buy": 125,
"limit": 0, "limit": 0,
"experience": 15, "experience": 15,
"harvest": 16, "harvest": 16,
@ -47,6 +50,7 @@
"牧草": "牧草":
{ {
"level": 0, "level": 0,
"buy": 80,
"limit": 0, "limit": 0,
"experience": 10, "experience": 10,
"harvest": 25, "harvest": 25,
@ -61,6 +65,7 @@
"大白菜": "大白菜":
{ {
"level": 1, "level": 1,
"buy": 168,
"limit": 0, "limit": 0,
"experience": 19, "experience": 19,
"harvest": 17, "harvest": 17,
@ -75,6 +80,7 @@
"大蒜": "大蒜":
{ {
"level": 1, "level": 1,
"buy": 169,
"limit": 0, "limit": 0,
"experience": 19, "experience": 19,
"harvest": 17, "harvest": 17,
@ -89,6 +95,7 @@
"水稻": "水稻":
{ {
"level": 2, "level": 2,
"buy": 168,
"limit": 0, "limit": 0,
"experience": 19, "experience": 19,
"harvest": 18, "harvest": 18,
@ -96,13 +103,14 @@
"time": 14, "time": 14,
"crop": 1, "crop": 1,
"again": 0, "again": 0,
"phase": 6, "phase": 5,
"general": true, "general": false,
"sell": false "sell": false
}, },
"小麦": "小麦":
{ {
"level": 2, "level": 2,
"buy": 168,
"limit": 0, "limit": 0,
"experience": 19, "experience": 19,
"harvest": 18, "harvest": 18,
@ -117,6 +125,7 @@
"玉米": "玉米":
{ {
"level": 3, "level": 3,
"buy": 175,
"limit": 0, "limit": 0,
"experience": 19, "experience": 19,
"harvest": 17, "harvest": 17,
@ -131,6 +140,7 @@
"油菜": "油菜":
{ {
"level": 4, "level": 4,
"buy": 194,
"limit": 0, "limit": 0,
"experience": 29, "experience": 29,
"harvest": 23, "harvest": 23,
@ -145,6 +155,7 @@
"生菜": "生菜":
{ {
"level": 4, "level": 4,
"buy": 195,
"limit": 0, "limit": 0,
"experience": 25, "experience": 25,
"harvest": 21, "harvest": 21,
@ -155,6 +166,96 @@
"phase": 6, "phase": 6,
"general": true, "general": true,
"sell": false "sell": false
},
"小白菜":
{
"level": 4,
"buy": 195,
"limit": 0,
"experience": 15,
"harvest": 18,
"price": 21,
"time": 11,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"红枣":
{
"level": 5,
"buy": 237,
"limit": 0,
"experience": 21,
"harvest": 20,
"price": 25,
"time": 16,
"crop": 1,
"again": 0,
"phase": 6,
"general": true,
"sell": false
},
"茄子":
{
"level": 5,
"buy": 237,
"limit": 0,
"experience": 21,
"harvest": 20,
"price": 25,
"time": 16,
"crop": 1,
"again": 0,
"phase": 6,
"general": true,
"sell": false
},
"番茄":
{
"level": 6,
"buy": 99999,
"limit": 0,
"experience": 22,
"harvest": 21,
"price": 7000,
"time": 17,
"crop": 1,
"again": 0,
"phase": 6,
"general": true,
"sell": false
},
"红玫瑰":
{
"level": 7,
"buy": 251,
"limit": 0,
"experience": 23,
"harvest": 22,
"price": 27,
"time": 18,
"crop": 1,
"again": 0,
"phase": 6,
"general": true,
"sell": false
},
"豌豆":
{
"level": 7,
"buy": 266,
"limit": 0,
"experience": 23,
"harvest": 22,
"price": 27,
"time": 18,
"crop": 1,
"again": 0,
"phase": 6,
"general": true,
"sell": false
} }
} }
} }

View File

@ -28,10 +28,7 @@ class CSqlManager:
bIsExist = os.path.exists(g_sDBFilePath) bIsExist = os.path.exists(g_sDBFilePath)
cls.m_pDB = await aiosqlite.connect(g_sDBFilePath) cls.m_pDB = await aiosqlite.connect(g_sDBFilePath)
cls.m_pDB.row_factory = aiosqlite.Row
#if bIsExist == False:
#TODO 缺少判断创建失败事件
#await cls.createDB()
await cls.checkDB() await cls.checkDB()
@ -50,11 +47,11 @@ class CSqlManager:
await cls.m_pDB.execute("COMMIT;") await cls.m_pDB.execute("COMMIT;")
@classmethod @classmethod
async def getTableInfo(cls, table_name: str) -> list: async def getTableInfo(cls, tableName: str) -> list:
if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', table_name): if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', tableName):
raise ValueError(f"Illegal table name: {table_name}") raise ValueError(f"Illegal table name: {tableName}")
try: try:
cursor = await cls.m_pDB.execute(f'PRAGMA table_info("{table_name}")') cursor = await cls.m_pDB.execute(f'PRAGMA table_info("{tableName}")')
rows = await cursor.fetchall() rows = await cursor.fetchall()
return [{"name": row[1], "type": row[2]} for row in rows] return [{"name": row[1], "type": row[2]} for row in rows]
except aiosqlite.Error: except aiosqlite.Error:
@ -62,7 +59,7 @@ class CSqlManager:
@classmethod @classmethod
async def ensureTableSchema(cls, table_name: str, columns: dict) -> bool: async def ensureTableSchema(cls, tableName: str, columns: dict) -> bool:
"""由AI生成 """由AI生成
创建表或为已存在表添加缺失字段 创建表或为已存在表添加缺失字段
返回 True 表示有变更创建或新增列False 则无操作 返回 True 表示有变更创建或新增列False 则无操作
@ -75,34 +72,44 @@ class CSqlManager:
_type_: _description_ _type_: _description_
""" """
info = await cls.getTableInfo(table_name) info = await cls.getTableInfo(tableName)
existing = {col['name']: col['type'].upper() for col in info} existing = {col['name']: col['type'].upper() for col in info}
desired = {k: v.upper() for k, v in columns.items()} desired = {k: v.upper() for k, v in columns.items() if k != "PRIMARY KEY"}
primaryKey = columns.get("PRIMARY KEY", "")
if not existing: if not existing:
cols_def = ", ".join(f'"{k}" {v}' for k, v in columns.items()) colsDef = ", ".join(f'"{k}" {v}' for k, v in desired.items())
await cls.m_pDB.execute(f'CREATE TABLE "{table_name}" ({cols_def});') if primaryKey:
colsDef += f", PRIMARY KEY {primaryKey}"
await cls.m_pDB.execute(f'CREATE TABLE "{tableName}" ({colsDef});')
return True return True
to_add = [k for k in desired if k not in existing]
to_remove = [k for k in existing if k not in desired] toAdd = [k for k in desired if k not in existing]
type_mismatch = [k for k in desired if k in existing and existing[k] != desired[k]] toRemove = [k for k in existing if k not in desired]
if to_add and not to_remove and not type_mismatch: typeMismatch = [k for k in desired if k in existing and existing[k] != desired[k]]
for col in to_add:
if toAdd and not toRemove and not typeMismatch:
for col in toAdd:
await cls.m_pDB.execute( await cls.m_pDB.execute(
f'ALTER TABLE "{table_name}" ADD COLUMN "{col}" {columns[col]}' f'ALTER TABLE "{tableName}" ADD COLUMN "{col}" {columns[col]}'
) )
return True return True
async with cls._transaction(): async with cls._transaction():
tmp_table = f"{table_name}_new" tmpTable = f"{tableName}_new"
cols_def = ", ".join(f'"{k}" {v}' for k, v in columns.items()) colsDef = ", ".join(f'"{k}" {v}' for k, v in desired.items())
await cls.m_pDB.execute(f'CREATE TABLE "{tmp_table}" ({cols_def});') if primaryKey:
common_cols = [k for k in desired if k in existing] colsDef += f", PRIMARY KEY {primaryKey}"
if common_cols: await cls.m_pDB.execute(f'CREATE TABLE "{tmpTable}" ({colsDef});')
cols_str = ", ".join(f'"{c}"' for c in common_cols)
commonCols = [k for k in desired if k in existing]
if commonCols:
colsStr = ", ".join(f'"{c}"' for c in commonCols)
await cls.m_pDB.execute( await cls.m_pDB.execute(
f'INSERT INTO "{tmp_table}" ({cols_str}) SELECT {cols_str} FROM "{table_name}";' f'INSERT INTO "{tmpTable}" ({colsStr}) SELECT {colsStr} FROM "{tableName}";'
) )
await cls.m_pDB.execute(f'DROP TABLE "{table_name}";') await cls.m_pDB.execute(f'DROP TABLE "{tableName}";')
await cls.m_pDB.execute(f'ALTER TABLE "{tmp_table}" RENAME TO "{table_name}";') await cls.m_pDB.execute(f'ALTER TABLE "{tmpTable}" RENAME TO "{tableName}";')
return True return True
@classmethod @classmethod
@ -155,17 +162,16 @@ class CSqlManager:
Returns: Returns:
bool: 是否执行成功 bool: 是否执行成功
""" """
if len(command) <= 0: if len(command) <= 0:
logger.warning("数据库语句长度不能") logger.warning("数据库语句长度为空")
return False return False
try: try:
await cls.m_pDB.execute(command) async with cls._transaction():
await cls.m_pDB.commit() await cls.m_pDB.execute(command)
return True return True
except Exception as e: except Exception as e:
logger.warning("数据库语句执行出错" + command) logger.warning("数据库语句执行出错:" + command)
return False return False
@classmethod @classmethod
@ -483,8 +489,6 @@ class CSqlManager:
"DELETE FROM userSeed WHERE uid = ? AND seed = ?", "DELETE FROM userSeed WHERE uid = ? AND seed = ?",
(uid, seed) (uid, seed)
) )
await cls.m_pDB.commit()
return True return True
except Exception as e: except Exception as e:
logger.warning(f"真寻农场addUserSeedByUid 失败: {e}") logger.warning(f"真寻农场addUserSeedByUid 失败: {e}")
@ -543,17 +547,18 @@ class CSqlManager:
Returns: Returns:
bool: 是否成功 bool: 是否成功
""" """
try: try:
if count <= 0:
return await cls.deleteUserSeedByName(uid, seed)
async with cls._transaction(): async with cls._transaction():
await cls.m_pDB.execute( await cls.m_pDB.execute(
"UPDATE userSeed SET count = ? WHERE uid = ? AND seed = ?", "UPDATE userSeed SET count = ? WHERE uid = ? AND seed = ?",
(count, uid, seed) (count, uid, seed)
) )
await cls.m_pDB.commit()
return True return True
except Exception as e: except Exception as e:
logger.warning(f"真寻农场updateUserSeedByName 更新失败: {e}") logger.warning(f"真寻农场updateUserSeedByName失败:{e}")
return False return False
@classmethod @classmethod
@ -573,7 +578,6 @@ class CSqlManager:
"DELETE FROM userSeed WHERE uid = ? AND seed = ?", "DELETE FROM userSeed WHERE uid = ? AND seed = ?",
(uid, seed) (uid, seed)
) )
await cls.m_pDB.commit()
return True return True
except Exception as e: except Exception as e:
logger.warning(f"真寻农场deleteUserSeedByName 删除失败: {e}") logger.warning(f"真寻农场deleteUserSeedByName 删除失败: {e}")
@ -613,12 +617,28 @@ class CSqlManager:
"INSERT INTO userPlant (uid, plant, count) VALUES (?, ?, ?)", "INSERT INTO userPlant (uid, plant, count) VALUES (?, ?, ?)",
(uid, plant, count) (uid, plant, count)
) )
await cls.m_pDB.commit()
return True return True
except Exception as e: except Exception as e:
logger.warning(f"真寻农场addUserPlantByUid 失败: {e}") logger.warning(f"真寻农场addUserPlantByUid 失败: {e}")
return False return False
@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}
@classmethod @classmethod
async def getUserPlantByName(cls, uid: str, plant: str) -> Optional[int]: async def getUserPlantByName(cls, uid: str, plant: str) -> Optional[int]:
"""根据作物名称获取用户的作物数量 """根据作物名称获取用户的作物数量
@ -642,7 +662,7 @@ class CSqlManager:
return None return None
@classmethod @classmethod
async def updateUserPlantByUid(cls, uid: str, plant: str, count: int) -> bool: async def updateUserPlantByName(cls, uid: str, plant: str, count: int) -> bool:
"""更新 userPlant 表中某个作物的数量 """更新 userPlant 表中某个作物的数量
Args: Args:
@ -654,28 +674,21 @@ class CSqlManager:
bool: 是否更新成功 bool: 是否更新成功
""" """
try: try:
if count <= 0:
return await cls.deleteUserPlantByName(uid, plant)
async with cls._transaction(): async with cls._transaction():
#更新作物数量
await cls.m_pDB.execute( await cls.m_pDB.execute(
"UPDATE userPlant SET count = ? WHERE uid = ? AND plant = ?", "UPDATE userPlant SET count = ? WHERE uid = ? AND plant = ?",
(count, uid, plant) (count, uid, plant)
) )
#如果作物数量为 0删除记录
if count <= 0:
await cls.m_pDB.execute(
"DELETE FROM userPlant WHERE uid = ? AND plant = ?",
(uid, plant)
)
await cls.m_pDB.commit()
return True return True
except Exception as e: except Exception as e:
logger.warning(f"真寻农场updateUserPlantByUid 更新失败: {e}") logger.warning(f"真寻农场updateUserPlantByName失败:{e}")
return False return False
@classmethod @classmethod
async def deleteUserPlantByUid(cls, uid: str, plant: str) -> bool: async def deleteUserPlantByName(cls, uid: str, plant: str) -> bool:
"""从 userPlant 表中删除某个作物记录 """从 userPlant 表中删除某个作物记录
Args: Args:
@ -691,10 +704,9 @@ class CSqlManager:
"DELETE FROM userPlant WHERE uid = ? AND plant = ?", "DELETE FROM userPlant WHERE uid = ? AND plant = ?",
(uid, plant) (uid, plant)
) )
await cls.m_pDB.commit()
return True return True
except Exception as e: except Exception as e:
logger.warning(f"真寻农场deleteUserPlantByUid 删除失败: {e}") logger.warning(f"真寻农场deleteUserPlantByName 失败: {e}")
return False return False
g_pSqlManager = CSqlManager() g_pSqlManager = CSqlManager()

View File

@ -213,9 +213,12 @@ class CFarmManager:
currentStage = int(elapsedHour / (plantInfo['time'] / (plantInfo['phase'] - 1))) currentStage = int(elapsedHour / (plantInfo['time'] / (plantInfo['phase'] - 1)))
#TODO 缺少判断部分种子是否是通用0阶段图片
if currentStage <= 0: if currentStage <= 0:
plant = BuildImage(background = g_sResourcePath / f"plant/basic/0.png") if plantInfo['general'] == False:
plant = BuildImage(background = g_sResourcePath / f"plant/{soilInfo[0]}/0.png")
else:
plant = BuildImage(background = g_sResourcePath / f"plant/basic/0.png")
await plant.resize(0, 35, 58) await plant.resize(0, 35, 58)
else: else:
plant = BuildImage(background = g_sResourcePath / f"plant/{soilInfo[0]}/{currentStage}.png") plant = BuildImage(background = g_sResourcePath / f"plant/{soilInfo[0]}/{currentStage}.png")
@ -395,7 +398,7 @@ class CFarmManager:
harvestRecords.append(f"收获作物:{plantId},数量为:{number},经验为:{plantInfo['experience']}") harvestRecords.append(f"收获作物:{plantId},数量为:{number},经验为:{plantInfo['experience']}")
#更新数据库操作 #更新数据库操作
await g_pSqlManager.addUserPlantByPlant(uid, plantId, number) await g_pSqlManager.addUserPlantByUid(uid, plantId, number)
await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 4) await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 4)
if experience > 0: if experience > 0:
@ -455,7 +458,6 @@ class CFarmManager:
Returns: Returns:
bytes: 返回图片 bytes: 返回图片
""" """
data_list = [] data_list = []
column_name = [ column_name = [
"-", "-",
@ -468,48 +470,40 @@ class CFarmManager:
plant = await g_pSqlManager.getUserPlantByUid(uid) plant = await g_pSqlManager.getUserPlantByUid(uid)
if plant == None: if plant is None:
result = await ImageTemplate.table_page( result = await ImageTemplate.table_page(
"作物仓库", "作物仓库",
"播种示例:@小真寻 出售作物 大白菜 [数量]", "播种示例:@小真寻 出售作物 大白菜 [数量]",
column_name, column_name,
data_list, data_list,
) )
return result.pic2bytes() return result.pic2bytes()
sell = "" sell = ""
for item in plant.split(','): for name, count in plant.items(): # 使用 .items() 来遍历字典
if '|' in item: plantInfo = g_pJsonManager.m_pPlant['plant'][name]
plantName, count = item.split('|', 1) #分割一次,避免多竖线问题 icon = ""
try: icon_path = g_sResourcePath / f"plant/{name}/icon.png"
plantInfo = g_pJsonManager.m_pPlant['plant'][plantName] if icon_path.exists():
icon = (icon_path, 33, 33)
icon = "" if plantInfo['again'] == True:
icon_path = g_sResourcePath / f"plant/{plantName}/icon.png" sell = "可以"
if icon_path.exists(): else:
icon = (icon_path, 33, 33) sell = "不可以"
if plantInfo['again'] == True: number = int(count) * plantInfo['price']
sell = "可以"
else:
sell = "不可以"
number = int(count) * plantInfo['price'] data_list.append(
[
data_list.append( icon,
[ name,
icon, count,
plantName, plantInfo['price'],
count, number,
plantInfo['price'], sell
number, ]
sell )
]
)
except Exception as e:
continue
result = await ImageTemplate.table_page( result = await ImageTemplate.table_page(
"作物仓库", "作物仓库",
@ -611,7 +605,7 @@ class CFarmManager:
logger.info(f"{randomNumber}") logger.info(f"{randomNumber}")
if randomNumber > 0: if randomNumber > 0:
await g_pSqlManager.addUserPlantByPlant(uid, plantId, randomNumber) await g_pSqlManager.addUserPlantByUid(uid, plantId, randomNumber)
harvestRecords.append(f"成功偷到作物:{plantId},数量为:{randomNumber}") harvestRecords.append(f"成功偷到作物:{plantId},数量为:{randomNumber}")
stealingStatus.append(f"{uid}-{randomNumber}") stealingStatus.append(f"{uid}-{randomNumber}")

View File

@ -1,4 +1,5 @@
import math import math
from re import I
from zhenxun.services.log import logger from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage from zhenxun.utils._build_image import BuildImage
@ -22,8 +23,9 @@ class CShopManager:
column_name = [ column_name = [
"-", "-",
"种子名称", "种子名称",
"种子单价"
"解锁等级", "解锁等级",
"种子单价", "果实单价",
"收获经验", "收获经验",
"收获数量", "收获数量",
"成熟时间(小时)", "成熟时间(小时)",
@ -53,6 +55,7 @@ class CShopManager:
[ [
icon, icon,
key, key,
plant['buy'],
plant['level'], plant['level'],
plant['price'], plant['price'],
plant['experience'], plant['experience'],
@ -105,7 +108,7 @@ class CShopManager:
return "你的等级不够哦,努努力吧" return "你的等级不够哦,努努力吧"
point = await g_pSqlManager.getUserPointByUid(uid) point = await g_pSqlManager.getUserPointByUid(uid)
total = int(plantInfo['price']) * num total = int(plantInfo['buy']) * num
logger.debug(f"用户:{uid}购买{name},数量为{num}。用户农场币为{point},购买需要{total}") logger.debug(f"用户:{uid}购买{name},数量为{num}。用户农场币为{point},购买需要{total}")
@ -114,7 +117,7 @@ class CShopManager:
else: else:
await g_pSqlManager.updateUserPointByUid(uid, point - total) await g_pSqlManager.updateUserPointByUid(uid, point - total)
if await g_pSqlManager.addUserSeedByPlant(uid, name, num) == False: if await g_pSqlManager.addUserSeedByUid(uid, name, num) == False:
return "购买失败,执行数据库错误!" return "购买失败,执行数据库错误!"
return f"成功购买{name},花费{total}农场币, 剩余{point - total}农场币" return f"成功购买{name},花费{total}农场币, 剩余{point - total}农场币"
@ -129,81 +132,39 @@ class CShopManager:
Returns: Returns:
str: str:
""" """
plantDict = await g_pSqlManager.getUserPlantByUid(uid)
plant = await g_pSqlManager.getUserPlantByUid(uid) if not plantDict:
if plant == None:
return "你仓库没有可以出售的作物" return "你仓库没有可以出售的作物"
point = 0 totalPoint = 0
totalSold = 0
remainingItems = []
isAll = False if not name:
if num == -1: for plantName, count in plantDict.items():
isAll = True plantInfo = g_pJsonManager.m_pPlant['plant'][plantName]
totalPoint += plantInfo['price'] * count
items = plant.split(',') await g_pSqlManager.deleteUserPlantByName(uid, plantName)
if len(name) <= 0:
#出售全部
for item in items:
if '|' in item:
plant_name, count_str = item.split('|', 1)
try:
count = int(count_str)
plant_info = g_pJsonManager.m_pPlant['plant'][plant_name]
point += plant_info['price'] * count
except Exception:
continue
await g_pSqlManager.updateUserPlantByUid(uid, "") # 清空仓库
else: else:
for item in items: currentCount = plantDict.get(name)
if '|' in item: if currentCount is None:
plantName, countStr = item.split('|', 1) return f"出售作物{name}出错:你没有这种作物"
try:
count = int(countStr)
if plantName == name:
if isAll: if num == -1:
sellAmount = count sellCount = currentCount
else: else:
sellAmount = min(num, count) if num > currentCount:
return f"出售作物{name}出错:数量不足"
sellCount = num
totalSold += sellAmount
remaining = count - sellAmount
if remaining > 0:
remainingItems.append(f"{plantName}|{remaining}")
if isAll == False:
num -= sellAmount
break
except (ValueError, TypeError):
continue
if num > 0 and isAll == False:
return f"出售作物{name}出错:数量不足"
#计算收益
try:
plantInfo = g_pJsonManager.m_pPlant['plant'][name] plantInfo = g_pJsonManager.m_pPlant['plant'][name]
totalPoint = plantInfo['price'] * totalSold totalPoint = plantInfo['price'] * sellCount
except KeyError: await g_pSqlManager.addUserPlantByUid(uid, name, -sellCount)
return f"出售作物{name}出错:作物不存在"
#更新剩余作物 point = await g_pSqlManager.getUserPointByUid(uid)
remainingPlant = ','.join(remainingItems) if remainingItems else "" await g_pSqlManager.updateUserPointByUid(uid, point + totalPoint)
await g_pSqlManager.updateUserPlantByUid(uid, remainingPlant)
#更新农场币 if not name:
p = await g_pSqlManager.getUserPointByUid(uid) return f"成功出售所有作物,获得农场币:{totalPoint},当前农场币:{point + totalPoint}"
await g_pSqlManager.updateUserPointByUid(uid, p + totalPoint)
if name:
return f"成功出售{name},获得农场币:{totalPoint}"
else: else:
return f"成功出售所有作物,获得农场币:{totalPoint}" return f"成功出售{name},获得农场币:{totalPoint},当前农场币:{point + totalPoint}"
g_pShopManager = CShopManager() g_pShopManager = CShopManager()

View File

@ -1,31 +1,87 @@
from email.mime import base
from unittest import result from unittest import result
import requests import httpx
from zhenxun.configs.config import Config
from zhenxun.services.log import logger
class CRequestManager: class CRequestManager:
@classmethod @classmethod
async def post(cls, url, json_data=None, form_data=None): async def download(cls, url: str, savePath: str, fileName: str) -> bool:
"""发送 POST 请求(支持 JSON/Form-Data 格式)""" """下载文件到指定路径
Args:
url (str): 文件的下载链接
savePath (str): 保存文件的文件夹路径
fileName (str): 保存后的文件名
Returns:
bool: 是否下载成功
"""
try: try:
headers = {"Content-Type": "application/json"} if json_data else None async with httpx.AsyncClient(timeout=10.0) as client:
response = requests.post( response = await client.get(url)
url, if response.status_code == 200:
json=json_data, fullPath = savePath.rstrip("/") + "/" + fileName
data=form_data, with open(fullPath, "wb") as f:
headers=headers, f.write(response.content)
timeout=5 return True
) else:
response.raise_for_status() logger.warning(f"文件下载失败: HTTP {response.status_code} {response.text}")
return response.json() return False
except requests.exceptions.RequestException as e: except Exception as e:
print(f"请求失败: {e}") logger.warning(f"下载文件异常: {e}")
return False
@classmethod
async def post(cls, endpoint: str, name: str = "", jsonData: dict = None, formData: dict = None) -> dict:
"""发送POST请求到指定接口供其他方法统一调用
Args:
endpoint (str): 请求的接口路径
name (str, optional): 操作名称用于日志记录
jsonData (dict, optional): 以JSON格式发送的数据
formData (dict, optional): 以表单格式发送的数据
Raises:
ValueError: 当jsonData和formData都未提供时抛出
Returns:
dict: 返回请求结果的JSON数据
"""
if jsonData is None and formData is None:
raise ValueError("post请求必须提供jsonData或formData其中之一")
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
try:
async with httpx.AsyncClient(timeout=5.0) as client:
if jsonData is not None:
response = await client.post(url, json=jsonData)
else:
response = await client.post(url, data=formData)
if response.status_code == 200:
return response.json()
else:
logger.warning(f"真寻农场{name}请求失败: HTTP {response.status_code} {response.text}")
return {}
except httpx.RequestError as e:
logger.warning(f"真寻农场{name}请求异常: {e}")
return {} return {}
except Exception as e:
logger.warning(f"真寻农场{name}处理异常: {e}")
return {}
@classmethod @classmethod
async def sign(cls, uid: str) -> str: async def sign(cls, uid: str) -> str:
a = await cls.post("http://diuse.work:9099/testPost", json_data={"level":3}) a = await cls.post("http://diuse.work:9099/testPost", jsonData={"level":3})
result = "" result = ""

BIN
resource/plant/水稻/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB