🎨 更新了对数据库的表、字段判断

This commit is contained in:
Art_Sakura 2025-04-08 19:00:17 +08:00
parent 6b3137e015
commit d17c1b8ed7
6 changed files with 179 additions and 106 deletions

View File

@ -1,11 +1,11 @@
from nonebot import get_driver
from nonebot.plugin import PluginMetadata
from zhenxun.configs.utils import Command, PluginExtraData
from zhenxun.configs.utils import Command, PluginExtraData, RegisterConfig
from zhenxun.services.log import logger
from zhenxun.utils.message import MessageUtils
from .command import diuse_farm, diuse_register
from .command import diuse_farm, diuse_register, reclamation
from .config import g_pJsonManager
from .database import g_pSqlManager
from .farm.farm import g_pFarmManager
@ -30,13 +30,33 @@ __plugin_meta__ = PluginMetadata(
出售作物 [作物/种子名称] [数量]
偷菜 at
开垦
购买农场币 [数量] 金币转换农场币比率是 1 : 2
购买农场币 [数量] 数量为消耗金币的数量
""".strip(),
extra=PluginExtraData(
author="Art_Sakura",
version="1.0",
commands=[Command(command="我的农场")],
menu_type="群内小游戏"
menu_type="群内小游戏",
configs=[
RegisterConfig(
key="兑换倍数",
value="2",
help="金币兑换农场币的倍数 默认值为: 2倍",
default_value="2",
),
RegisterConfig(
key="手续费",
value="0.2",
help="金币兑换农场币的手续费 默认值为: 0.2 实际意义为20%手续费",
default_value="0.2",
),
RegisterConfig(
key="服务地址",
value="http://diuse.work",
help="签到、交易行、活动等服务器地址",
default_value="http://diuse.work",
)
]
).to_dict(),
)
driver = get_driver()
@ -51,9 +71,6 @@ async def start():
# 初始化读取Json
await g_pJsonManager.init()
# await g_pFarmManager.reclamation("1754798088")
# await g_pSqlManager.initUserInfoByUid("1754798088", "Art_Sakura", 0, 100)
# 析构函数
@driver.on_shutdown
async def shutdown():

View File

@ -258,33 +258,6 @@ async def _(session: Uninfo):
res = await g_pFarmManager.reclamation(uid)
await MessageUtils.build_message(res).send(reply_to=True)
diuse_farm.shortcut(
"开垦",
command="我的农场",
arguments=["reclamation"],
prefix=True,
)
@diuse_farm.assign("reclamation")
async def _(session: Uninfo):
uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0:
await MessageUtils.build_message("尚未开通农场快at我发送 开通农场 开通吧").send()
return None
result = await g_pFarmManager.getUserPlantByUid(uid)
await MessageUtils.build_message(result).send(reply_to=True)
diuse_farm.set_path_arg("reclamation", "result")
@diuse_farm.got_path("test", "测试一下")
async def _(name: str):
await MessageUtils.build_message(name).send(reply_to=True)
diuse_farm.shortcut(
"出售作物(?P<name>.*?)",
command="我的农场",

View File

@ -1,32 +1,7 @@
{
<<<<<<< HEAD
"soil":[1, 1, 1, 2, 3, 5, 7, 9, 11, 13,
15, 17, 19, 21, 23, 25, 27, 29, 31, 33,
36, 39, 42, 45, 48, 51, 54, 57, 60, 70
=======
"level":
{
"0": 0,
"1": 50,
"2": 75,
"3": 125,
"4": 185,
"5": 200,
"6": 250,
"7": 275,
"8": 350,
"9": 500,
"10": 850,
"11": 1250,
"12": 2250,
"13": 3500,
"14": 4500,
"15": 5800
},
"soil":[1, 1, 1, 2, 3, 5, 7, 9, 12, 15,
18, 21, 25, 29, 33, 38, 43, 48, 54, 60,
66, 72, 78, 85, 92, 99, 106, 114, 120, 130
>>>>>>> f85ab9758c44ce45c6aae9e792f7a5d9e2f7459a
],
"reclamation":
{

View File

@ -1,5 +1,6 @@
import math
import os
import re
from datetime import date, datetime, timedelta
from io import StringIO
from math import e
@ -20,7 +21,6 @@ class CSqlManager:
async def cleanup(cls):
if cls.m_pDB:
await cls.m_pDB.close()
cls.m_pDB = None
@classmethod
async def init(cls) -> bool:
@ -28,62 +28,125 @@ class CSqlManager:
cls.m_pDB = await aiosqlite.connect(g_sDBFilePath)
if bIsExist == False:
# TODO 缺少判断创建失败事件
await cls.createDB()
#if bIsExist == False:
#TODO 缺少判断创建失败事件
#await cls.createDB()
await cls.checkDB()
return True
@classmethod
async def createDB(cls) -> bool:
"""初始化数据库用户信息表
async def getColumns(cls, tableName):
""" 由AI生成
获取表的列信息
"""
try:
cursor = await cls.m_pDB.execute(f'PRAGMA table_info("{tableName}")')
columns = [row[1] for row in await cursor.fetchall()]
return columns
except aiosqlite.Error as e:
logger.error(f"获取表结构失败: {str(e)}")
raise
@classmethod
async def ensure_table_exists(cls, tableName, columns) -> bool:
"""智能创建并分析数据库表、字段是否存在 由AI生成
Args:
tableName (_type_): 表名
columns (_type_): 字典
Returns:
bool: 是否创建成功
_type_: _description_
"""
try:
current_columns = await cls.getColumns(tableName)
#用户信息
userInfo = """
CREATE TABLE user (
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
);
"""
#检查表是否存在
table_exists = bool(current_columns)
#用户仓库
userStorehouse = """
CREATE TABLE storehouse (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
item TEXT DEFAULT '',
plant TEXT DEFAULT '',
seed TEXT DEFAULT ''
);
"""
#如果表不存在,直接创建
if not table_exists:
create_sql = f'''
CREATE TABLE "{tableName}" (
{", ".join(f'"{k}" {v}' for k, v in columns.items())}
);
'''
await cls.m_pDB.execute(create_sql)
await cls.m_pDB.commit() #显式提交新建表操作
return True
#用户土地信息
with StringIO() as buffer:
buffer.write("CREATE TABLE soil (")
buffer.write("uid INTEGER PRIMARY KEY AUTOINCREMENT,")
#表存在时的处理
columns_to_add = []
columns_to_remove = []
fields = [f"soil{i} TEXT DEFAULT ''" for i in range(1, 31)]
buffer.write(",\n".join(fields))
#检查需要添加的列
for k, v in columns.items():
if k not in current_columns:
columns_to_add.append(f'"{k}" {v}')
buffer.write(");")
#检查需要移除的列
for col in current_columns:
if col not in columns.keys():
columns_to_remove.append(col)
userSoilInfo = buffer.getvalue()
#执行修改
if columns_to_add or columns_to_remove:
try:
#开启事务使用connection级别的事务控制
await cls.m_pDB.execute('BEGIN TRANSACTION')
#添加新列
for col_def in columns_to_add:
await cls.m_pDB.execute(f'ALTER TABLE "{tableName}" ADD COLUMN {col_def}')
#删除旧列
for col in columns_to_remove:
await cls.m_pDB.execute(f'ALTER TABLE "{tableName}" DROP COLUMN "{col}"')
#显式提交事务
await cls.m_pDB.commit()
return True
except Exception as e:
#回滚事务
await cls.m_pDB.rollback()
logger.error(f"表结构迁移失败: {str(e)}")
if not await cls.executeDB(userInfo):
return False
except aiosqlite.Error as e:
logger.error(f"表结构迁移失败: {str(e)}")
if not await cls.executeDB(userStorehouse):
return False
return True
if not await cls.executeDB(userSoilInfo):
return False
@classmethod
async def checkDB(cls) -> bool:
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"
}
userStorehouse = {
"uid": "INTEGER PRIMARY KEY AUTOINCREMENT",
"item": "TEXT DEFAULT ''",
"plant": "TEXT DEFAULT ''",
"seed": "TEXT DEFAULT ''"
}
userSoilInfo = {
"uid": "INTEGER PRIMARY KEY AUTOINCREMENT",
**{f"soil{i}": "TEXT DEFAULT ''" for i in range(1, 31)}
}
await cls.ensure_table_exists("user", userInfo)
await cls.ensure_table_exists("storehouse", userStorehouse)
await cls.ensure_table_exists("soil", userSoilInfo)
return True
@ -373,7 +436,7 @@ class CSqlManager:
s = ""
else:
#获取种子信息 这里能崩我吃
plantInfo = g_pJsonManager.m_pPlant['plant'][plant] # type: ignore
plantInfo = g_pJsonManager.m_pPlant['plant'][plant] #type: ignore
currentTime = datetime.now()
newTime = currentTime + timedelta(hours=int(plantInfo['time']))

View File

@ -4,6 +4,9 @@ from datetime import date, datetime
from io import StringIO
from typing import Dict, List, Tuple
from numpy import number
from zhenxun.configs.config import Config
from zhenxun.models.user_console import UserConsole
from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage
@ -22,18 +25,23 @@ class CFarmManager:
user = await UserConsole.get_user(uid)
point = num // 2
if user.gold < point:
if user.gold < num:
return "你的金币不足"
await UserConsole.reduce_gold(uid, point, GoldHandle.BUY , 'zhenxun_plugin_farm')
await UserConsole.reduce_gold(uid, num, GoldHandle.BUY , 'zhenxun_plugin_farm')
pro = Config.get_config("zhenxun_plugin_farm", "兑换倍数")
tax = Config.get_config("zhenxun_plugin_farm", "手续费")
exc = num * pro
point = exc - (exc * tax)
p = await g_pSqlManager.getUserPointByUid(uid)
number = point + p
await g_pSqlManager.updateUserPointByUid(uid, num + p)
await g_pSqlManager.updateUserPointByUid(uid, number)
return f"充值{num}农场币成功,当前农场币:{num + p}"
return f"充值{num}农场币成功,当前农场币:{number}"
@classmethod
async def drawFarmByUid(cls, uid: str) -> bytes:

37
request.py Normal file
View File

@ -0,0 +1,37 @@
from unittest import result
import requests
class CRequestManager:
@classmethod
async def post(cls, url, json_data=None, form_data=None):
"""发送 POST 请求(支持 JSON/Form-Data 格式)"""
try:
headers = {"Content-Type": "application/json"} if json_data else None
response = requests.post(
url,
json=json_data,
data=form_data,
headers=headers,
timeout=5
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return {}
@classmethod
async def sign(cls, uid: str) -> str:
a = await cls.post("http://diuse.work:9099/testPost", json_data={"level":3})
result = ""
if int(a["type"]) == 1:
result = f"签到成功"
return result
g_pRequestManager = CRequestManager()