diff --git a/README.md b/README.md
index d2ceed6..56b2fe7 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,16 @@
+
+
# 真寻农场(zhenxun_plugin_farm)
+
+
+
+
+
你是说可以种地对吧🤔?
+
+
---
## 如何安装
diff --git a/__init__.py b/__init__.py
index bc7238f..12193d0 100644
--- a/__init__.py
+++ b/__init__.py
@@ -82,8 +82,6 @@ async def start():
await g_pDBService.init()
- # await g_pRequestManager.initSignInFile()
-
# 析构函数
@driver.on_shutdown
async def shutdown():
diff --git a/command.py b/command.py
index 55097bb..53cded2 100644
--- a/command.py
+++ b/command.py
@@ -1,5 +1,3 @@
-from datetime import date, datetime, timedelta
-
from nonebot.adapters import Event, MessageTemplate
from nonebot.rule import to_me
from nonebot_plugin_alconna import (Alconna, AlconnaMatch, AlconnaQuery, Args,
@@ -12,9 +10,12 @@ from zhenxun.configs.config import BotConfig
from zhenxun.services.log import logger
from zhenxun.utils.message import MessageUtils
+from .config import g_bSignStatus
from .dbService import g_pDBService
from .farm.farm import g_pFarmManager
from .farm.shop import g_pShopManager
+from .json import g_pJsonManager
+from .tool import g_pToolManager
async def isRegisteredByUid(uid: str) -> bool:
@@ -136,7 +137,7 @@ diuse_farm = on_alconna(
Subcommand("buy-point", Args["num?", int], help_text="购买农场币"),
#Subcommand("sell-point", Args["num?", int], help_text="转换金币")
Subcommand("change-name", Args["name?", str], help_text="更改农场名"),
- Subcommand("sing-in", help_text="农场签到"),
+ Subcommand("sign-in", help_text="农场签到"),
),
priority=5,
block=True,
@@ -168,7 +169,7 @@ async def _(session: Uninfo):
info = await g_pFarmManager.drawDetailFarmByUid(uid)
- await MessageUtils.alc_forward_msg([info], session.self_id, BotConfig.self_nickname).send(reply_to=True)
+ await MessageUtils.alc_forward_msg([info], session.self_id, BotConfig.self_nickname).send()
diuse_farm.shortcut(
"我的农场币",
@@ -446,30 +447,55 @@ async def _(session: Uninfo, name: Match[str]):
else:
await MessageUtils.build_message("更新用户名失败!").send(reply_to=True)
-reclamation = on_alconna(
- Alconna("农场签到"),
- priority=5,
- block=True,
+diuse_farm.shortcut(
+ "农场签到",
+ command="我的农场",
+ arguments=["sign-in"],
+ prefix=True,
)
-@reclamation.handle()
+@diuse_farm.assign("sign-in")
async def _(session: Uninfo):
uid = str(session.user.id)
if await isRegisteredByUid(uid) == False:
return
- toDay = date.today()
+ #判断签到是否正常加载
+ if g_bSignStatus == False:
+ await MessageUtils.build_message("签到功能异常!").send()
+ return
+
+ toDay = g_pToolManager.dateTime().date().today()
message = ""
status = await g_pDBService.userSign.sign(uid, toDay.strftime("%Y-%m-%d"))
- if status == True:
- message = "签到成功"
+ #如果完成签到
+ if status == 1 or status == 2:
+ #获取签到总天数
+ signDay = await g_pDBService.userSign.getUserSignCountByDate(uid, toDay.strftime("%Y-%m"))
+ exp, point = await g_pDBService.userSign.getUserSignRewardByDate(uid, toDay.strftime("%Y-%m-%d"))
- img = await g_pDBService.userSign.drawSignCalendarImage(uid, toDay.year, toDay.month)
+ message += f"签到成功!累计签到天数:{signDay}\n获得经验{exp},获得金币{point}"
- await MessageUtils.build_message(img).send()
+ reward = g_pJsonManager.m_pSign['continuou'].get(f"{signDay}", None)
+
+ if reward:
+ extraPoint = reward.get('point', 0)
+ extraExp = reward.get('exp', 0)
+
+ plant = reward.get('plant', {})
+
+ message += f"\n\n成功领取累计签到奖励:\n额外获得经验{extraExp},额外获得金币{extraPoint}"
+
+ if plant:
+ for key, value in plant.items():
+ message += f"\n获得{key}种子 * {value}"
+ else:
+ message = "签到失败!未知错误"
+
+ await MessageUtils.build_message(message).send()
# await MessageUtils.alc_forward_msg([info], session.self_id, BotConfig.self_nickname).send(reply_to=True)
diff --git a/config.py b/config.py
index ffccb92..7a7a2bc 100644
--- a/config.py
+++ b/config.py
@@ -10,3 +10,5 @@ g_sPlantPath = g_sResourcePath / "db/plant.db"
g_sConfigPath = Path(__file__).resolve().parent / "config"
g_sSignInPath = g_sConfigPath / "sign_in.json"
+
+g_bSignStatus = True
diff --git a/database/user.py b/database/user.py
index fefa449..efd12a0 100644
--- a/database/user.py
+++ b/database/user.py
@@ -1,10 +1,10 @@
import math
-from datetime import date, datetime, timedelta
from typing import List, Union
from zhenxun.services.log import logger
from .database import CSqlManager
+from ..tool import g_pToolManager
class CUserDB(CSqlManager):
@@ -35,7 +35,7 @@ class CUserDB(CSqlManager):
Returns:
Union[bool, str]: False 表示失败,字符串表示成功信息
"""
- nowStr = date.today().strftime('%Y-%m-%d')
+ nowStr = g_pToolManager.dateTime().date().today().strftime('%Y-%m-%d')
sql = (
f"INSERT INTO user (uid, name, exp, point, soil, stealTime, stealCount) "
f"VALUES ({uid}, '{name}', {exp}, {point}, 3, '{nowStr}', 5)"
diff --git a/database/userSign.py b/database/userSign.py
index 2d21beb..e43b053 100644
--- a/database/userSign.py
+++ b/database/userSign.py
@@ -1,4 +1,5 @@
import calendar
+import random
from datetime import date, datetime, timedelta
from typing import Optional
@@ -8,6 +9,7 @@ from zhenxun.utils._build_image import BuildImage
from ..dbService import g_pDBService
from ..json import g_pJsonManager
from .database import CSqlManager
+from ..tool import g_pToolManager
class CUserSignDB(CSqlManager):
@@ -18,8 +20,9 @@ class CUserSignDB(CSqlManager):
"uid": "TEXT NOT NULL", #用户ID
"signDate": "DATE NOT NULL", #签到日期
"isSupplement": "TINYINT NOT NULL DEFAULT 0", #是否补签
- "rewardType": "VARCHAR(20) DEFAULT ''", #奖励类型
- "createdAt": "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP", #创建时间
+ "exp": "INT NOT NULL DEFAULT 0", #当天签到经验
+ "point": "INT NOT NULL DEFAULT 0", #当天签到金币
+ "createdAt": "DATETIME NOT NULL DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime')",#创建时间
"PRIMARY KEY": "(uid, signDate)"
}
@@ -32,22 +35,52 @@ class CUserSignDB(CSqlManager):
"lastSignDate": "DATE DEFAULT NULL", #上次签到日期
"continuousDays": "INT NOT NULL DEFAULT 0", #连续签到天数
"supplementCount": "INT NOT NULL DEFAULT 0", #补签次数
- "updatedAt": "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP", #更新时间
+ "updatedAt": "DATETIME NOT NULL DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime')"#更新时间
}
await cls.ensureTableSchema("userSignLog", userSignLog)
await cls.ensureTableSchema("userSignSummary", userSignSummary)
@classmethod
- async def getUserSignCountByDate(cls, uid: str, monthStr: str) -> int:
+ async def getUserSignRewardByDate(cls, uid: str, date: str) -> tuple[int, int]:
+ """根据指定日期获取用户签到随机奖励
+
+ Args:
+ uid (str): 用户Uid
+ date (str): 用户签到日期 示例:2025-05-27
+
+ Returns:
+ tuple[int, int]: 经验、金币
"""
+ try:
+ async with cls._transaction():
+ async with cls.m_pDB.execute(
+ "SELECT exp, point FROM userSignLog WHERE uid=? AND signDate=?",
+ (uid, date)
+ ) as cursor:
+ row = await cursor.fetchone()
+
+ if row is None:
+ return 0, 0
+
+ exp = row['exp']
+ point = row['point']
+
+ return exp, point
+ except Exception as e:
+ logger.warning("获取用户签到数据失败", e=e)
+ return 0, 0
+
+ @classmethod
+ async def getUserSignCountByDate(cls, uid: str, monthStr: str) -> int:
+ """根据日期查询用户签到总天数
Args:
uid (str): 用户Uid
monthStr (str): 需要查询的日期 示例: 2025-05
Returns:
- int: _description_
+ int: 查询月总签到天数
"""
try:
sql = "SELECT COUNT(*) FROM userSignLog WHERE uid=? AND signDate LIKE ?"
@@ -80,21 +113,43 @@ class CUserSignDB(CSqlManager):
return False
@classmethod
- async def sign(cls, uid: str, signDate: str = '') -> bool:
+ async def sign(cls, uid: str, signDate: str = '') -> int:
+ """签到
+
+ Args:
+ uid (int): 用户ID
+ signDate (str): 日期字符串 'YYYY-MM-DD' 不传默认当前系统日期
+
+ Returns:
+ bool: 0: 签到失败 1: 签到成功 2: 重复签到
+ """
try:
if not signDate:
- signDate = date.today().strftime("%Y-%m-%d")
+ signDate = g_pToolManager.dateTime().date().today().strftime("%Y-%m-%d")
if await cls.hasSigned(uid, signDate):
- return False
+ return 2
- todayStr = date.today().strftime("%Y-%m-%d")
+ todayStr = g_pToolManager.dateTime().date().today().strftime("%Y-%m-%d")
isSupplement = 0 if signDate == todayStr else 1
+ expMax, expMin, pointMax, pointMin = [
+ g_pJsonManager.m_pSign.get(key, default)
+ for key, default in (
+ ("exp_max", 50),
+ ("exp_min", 5),
+ ("point_max", 2000),
+ ("point_min", 200),
+ )
+ ]
+
+ exp = random.randint(expMin, expMax)
+ point = random.randint(pointMin, pointMax)
+
async with cls._transaction():
await cls.m_pDB.execute(
- "INSERT INTO userSignLog (uid, signDate, isSupplement, rewardType) VALUES (?, ?, ?, '')",
- (uid, signDate, isSupplement)
+ "INSERT INTO userSignLog (uid, signDate, isSupplement, exp, point) VALUES (?, ?, ?, ?, ?)",
+ (uid, signDate, isSupplement, exp, point)
)
cursor = await cls.m_pDB.execute("SELECT * FROM userSignSummary WHERE uid=?", (uid,))
@@ -103,8 +158,9 @@ class CUserSignDB(CSqlManager):
currentMonth = signDate[:7]
if row:
monthSignDays = row['monthSignDays'] + 1 if row['currentMonth'] == currentMonth else 1
+ totalSignDays = row['totalSignDays']
lastDate = row['lastSignDate']
- prevDate = (datetime.strptime(signDate, "%Y-%m-%d") - timedelta(days=1)).strftime("%Y-%m-%d")
+ prevDate = (g_pToolManager.dateTime().strptime(signDate, "%Y-%m-%d") - timedelta(days=1)).strftime("%Y-%m-%d")
continuousDays = row['continuousDays'] + 1 if lastDate == prevDate else 1
supplementCount = row['supplementCount'] + 1 if isSupplement else row['supplementCount']
await cls.m_pDB.execute(
@@ -121,6 +177,7 @@ class CUserSignDB(CSqlManager):
(currentMonth, monthSignDays, signDate, continuousDays, supplementCount, uid)
)
else:
+ totalSignDays = 1
await cls.m_pDB.execute(
"""
INSERT INTO userSignSummary
@@ -129,10 +186,31 @@ class CUserSignDB(CSqlManager):
""",
(uid, 1, currentMonth, 1, signDate, 1, 1 if isSupplement else 0)
)
- return True
+
+ #计算累签奖励
+ reward = g_pJsonManager.m_pSign['continuou'].get(f"{totalSignDays + 1}", None)
+
+ if reward:
+ point += reward.get('point', 0)
+ exp += reward.get('exp', 0)
+
+ plant = reward.get('plant', {})
+
+ if plant:
+ for key, value in plant.items():
+ await g_pDBService.userSeed.addUserSeedByUid(uid, key, value)
+
+ #向数据库更新
+ currentExp = await g_pDBService.user.getUserExpByUid(uid)
+ await g_pDBService.user.updateUserExpByUid(uid, currentExp + exp)
+
+ currentPoint = await g_pDBService.user.getUserPointByUid(uid)
+ await g_pDBService.user.updateUserPointByUid(uid, currentPoint + point)
+
+ return 1
except Exception as e:
logger.warning("执行签到失败", e=e)
- return False
+ return 0
@classmethod
async def drawSignCalendarImage(cls, uid: str, year: int, month: int):
diff --git a/database/userSoil.py b/database/userSoil.py
index a8cf066..5500637 100644
--- a/database/userSoil.py
+++ b/database/userSoil.py
@@ -1,4 +1,3 @@
-from datetime import date, datetime, timedelta
from typing import Optional
from zhenxun.services.log import logger
@@ -6,6 +5,7 @@ from zhenxun.services.log import logger
from ..dbService import g_pDBService
from ..json import g_pJsonManager
from .database import CSqlManager
+from ..tool import g_pToolManager
class CUserSoilDB(CSqlManager):
@@ -312,7 +312,7 @@ class CUserSoilDB(CSqlManager):
logger.error(f"未知植物: {plantName}")
return False
- nowTs = int(datetime.now().timestamp())
+ nowTs = int(g_pToolManager.dateTime().now().timestamp())
matureTs = nowTs + int(plantCfg.get("time", 0)) * 3600
try:
diff --git a/farm/farm.py b/farm/farm.py
index 7d318c4..6708c55 100644
--- a/farm/farm.py
+++ b/farm/farm.py
@@ -1,7 +1,6 @@
import asyncio
import math
import random
-from datetime import date, datetime
from typing import Dict, List, Tuple
from zhenxun.configs.config import Config
@@ -16,6 +15,7 @@ from ..config import g_sResourcePath
from ..dbService import g_pDBService
from ..event.event import g_pEventManager
from ..json import g_pJsonManager
+from ..tool import g_pToolManager
class CFarmManager:
@@ -211,7 +211,7 @@ class CFarmManager:
soilStatus = "-"
plantNumber = "-"
else:
- matureTime = datetime.fromtimestamp(int(soilInfo.get("matureTime", 0))).strftime("%Y-%m-%d %H:%M:%S.%f")
+ matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo.get("matureTime", 0))).strftime("%Y-%m-%d %H:%M:%S.%f")
soilStatus = await g_pDBService.userSoil.getUserSoilStatus(uid, i)
num = await g_pDBService.userSteal.getTotalStolenCount(uid, i)
@@ -286,8 +286,8 @@ class CFarmManager:
logger.error(f"绘制植物资源失败: {soilInfo['plantName']}")
return False, None, False #type: ignore
- currentTime = datetime.now()
- matureTime = datetime.fromtimestamp(int(soilInfo['matureTime']))
+ currentTime = g_pToolManager.dateTime().now()
+ matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['matureTime']))
#如果当前时间大于成熟时间 说明作物成熟
if currentTime >= matureTime:
@@ -303,7 +303,7 @@ class CFarmManager:
return True, plant, False
#如果没有成熟 则根据当前阶段进行绘制
- plantedTime = datetime.fromtimestamp(int(soilInfo['plantTime']))
+ plantedTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['plantTime']))
elapsedTime = currentTime - plantedTime
elapsedHour = elapsedTime.total_seconds() / 3600
@@ -484,8 +484,8 @@ class CFarmManager:
if not plantInfo:
continue
- currentTime = datetime.now()
- matureTime = datetime.fromtimestamp(int(soilInfo['matureTime']))
+ currentTime = g_pToolManager.dateTime().now()
+ matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['matureTime']))
if currentTime >= matureTime:
number = plantInfo['harvest']
@@ -664,10 +664,10 @@ class CFarmManager:
stealCount = int(userInfo['stealCount'])
if stealTime == '':
- stealTime = date.today().strftime('%Y-%m-%d')
+ stealTime = g_pToolManager.dateTime().date().today().strftime('%Y-%m-%d')
stealCount = 5
- elif date.fromisoformat(stealTime) != date.today():
- stealTime = date.today().strftime('%Y-%m-%d')
+ elif g_pToolManager.dateTime().date().fromisoformat(stealTime) != g_pToolManager.dateTime().date().today():
+ stealTime = g_pToolManager.dateTime().date().today().strftime('%Y-%m-%d')
stealCount = 5
if stealCount <= 0:
@@ -697,8 +697,8 @@ class CFarmManager:
if not plantInfo:
continue
- currentTime = datetime.now()
- matureTime = datetime.fromtimestamp(int(soilInfo['matureTime']))
+ currentTime = g_pToolManager.dateTime().now()
+ matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['matureTime']))
if currentTime >= matureTime:
#如果偷过,则跳过该土地
@@ -728,10 +728,10 @@ class CFarmManager:
await g_pDBService.userSoil.updateUserSoil(uid, i, "lastResetTime", int(currentTime.timestamp()))
await g_pDBService.userSoil.updateUserSoil(uid, i, "matureTime", matureTs)
- await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(datetime.now().timestamp()))
+ await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(g_pToolManager.dateTime().now().timestamp()))
else:
- await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(datetime.now().timestamp()))
+ await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(g_pToolManager.dateTime().now().timestamp()))
if isStealingPlant <= 0 and isStealingNumber <= 0:
return "目标没有作物可以被偷"
diff --git a/json.py b/json.py
index 422dcc0..15ecf7e 100644
--- a/json.py
+++ b/json.py
@@ -3,12 +3,16 @@ from pathlib import Path
from zhenxun.services.log import logger
+from . import config
+from .request import g_pRequestManager
+
class CJsonManager:
def __init__(self):
self.m_pItem = {}
self.m_pLevel = {}
self.m_pSoil = {}
+ self.m_pSign = {}
async def init(self) -> bool:
if not await self.initItem():
@@ -20,14 +24,17 @@ class CJsonManager:
if not await self.initSoil():
return False
- return True
+ if not await g_pRequestManager.initSignInFile():
+ config.g_bSignStatus = False
+
+ return False
+ else:
+ return await self.initSign()
async def initItem(self) -> bool:
- current_file_path = Path(__file__)
-
try:
with open(
- current_file_path.resolve().parent / "config/item.json",
+ config.g_sConfigPath / "item.json",
encoding="utf-8",
) as file:
self.m_pItem = json.load(file)
@@ -41,11 +48,9 @@ class CJsonManager:
return False
async def initLevel(self) -> bool:
- current_file_path = Path(__file__)
-
try:
with open(
- current_file_path.resolve().parent / "config/level.json",
+ config.g_sConfigPath / "level.json",
encoding="utf-8",
) as file:
self.m_pLevel = json.load(file)
@@ -59,11 +64,9 @@ class CJsonManager:
return False
async def initSoil(self) -> bool:
- current_file_path = Path(__file__)
-
try:
with open(
- current_file_path.resolve().parent / "config/soil.json",
+ config.g_sConfigPath / "soil.json",
encoding="utf-8",
) as file:
self.m_pSoil = json.load(file)
@@ -76,4 +79,20 @@ class CJsonManager:
logger.warning(f"soil.json JSON格式错误: {e}")
return False
+ async def initSign(self) -> bool:
+ try:
+ with open(
+ config.g_sSignInPath,
+ encoding="utf-8",
+ ) as file:
+ self.m_pSign = json.load(file)
+
+ return True
+ except FileNotFoundError:
+ logger.warning("sign_in.json 打开失败")
+ return False
+ except json.JSONDecodeError as e:
+ logger.warning(f"sign_in.json JSON格式错误: {e}")
+ return False
+
g_pJsonManager = CJsonManager()
diff --git a/request.py b/request.py
index ae53da0..91967dc 100644
--- a/request.py
+++ b/request.py
@@ -36,7 +36,6 @@ class CRequestManager:
try:
async with httpx.AsyncClient(timeout=10.0) as client:
- # 动态组装请求参数
requestArgs: dict = {"headers": headers}
if params:
requestArgs["params"] = params
@@ -60,7 +59,7 @@ class CRequestManager:
return False
@classmethod
- async def post(cls, endpoint: str, name: str = "", jsonData: dict = None) -> dict:
+ async def post(cls, endpoint: str, name: str = "", jsonData: dict = {}) -> dict:
"""发送POST请求到指定接口,统一调用,仅支持JSON格式数据
Args:
@@ -74,9 +73,6 @@ class CRequestManager:
Returns:
dict: 返回请求结果的JSON数据
"""
- if jsonData is None:
- raise ValueError("post请求必须提供jsonData")
-
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
headers = {"token": cls.m_sTokens}
@@ -129,43 +125,44 @@ class CRequestManager:
return {}
@classmethod
- async def initSignInFile(cls):
+ async def initSignInFile(cls) -> bool:
if os.path.exists(g_sSignInPath):
-
try:
with open(g_sSignInPath, "r", encoding="utf-8") as f:
content = f.read()
sign = json.loads(content)
date = sign.get("date", "")
- yearMonth = datetime.now().strftime("%Y%m")
+ yearMonth = g_pToolManager.dateTime().now().strftime("%Y%m")
if date == yearMonth:
logger.debug("真寻农场签到文件检查完毕")
+ return True
else:
logger.warning("真寻农场签到文件检查失败, 即将下载")
- await cls.downloadSignInFile()
+ return await cls.downloadSignInFile()
except json.JSONDecodeError as e:
logger.warning(f"真寻农场签到文件格式错误, 即将下载")
- await cls.downloadSignInFile()
+ return await cls.downloadSignInFile()
else:
- await cls.downloadSignInFile()
+ return await cls.downloadSignInFile()
@classmethod
- async def downloadSignInFile(cls):
- baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
+ async def downloadSignInFile(cls) -> bool:
+ try:
+ baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
- url = f"{baseUrl.rstrip('/')}/sign_in"
- url = f"http://127.0.0.1:8998/sign_in"
+ url = f"{baseUrl.rstrip('/')}:8998/sign_in"
+ path = str(g_sSignInPath.parent.resolve(strict=False))
+ yearMonth = g_pToolManager.dateTime().now().strftime("%Y%m")
- path = str(g_sSignInPath.parent.resolve(strict=False))
- yearMonth = datetime.now().strftime("%Y%m")
+ await cls.download(url, path, "signTemp.json", jsonData={'date':yearMonth})
+ g_pToolManager.renameFile(f"{path}/signTemp.json", "sign_in.json")
- logger.info(f"{yearMonth}")
- yearMonth = "202506"
-
- await cls.download(url, path, "signTemp.json", jsonData={'date':yearMonth})
- g_pToolManager.renameFile(f"{path}/signTemp.json", "sign_in.json")
+ return True
+ except Exception as e:
+ logger.error("下载签到文件失败", e=e)
+ return False
g_pRequestManager = CRequestManager()
diff --git a/tool.py b/tool.py
index 640bb95..58df77a 100644
--- a/tool.py
+++ b/tool.py
@@ -1,4 +1,6 @@
import os
+from datetime import datetime
+from zoneinfo import ZoneInfo
from zhenxun.services.log import logger
@@ -29,4 +31,9 @@ class CToolManager:
logger.warning(f"文件重命名失败: {e}")
return False
+ @classmethod
+ def dateTime(cls) -> datetime:
+ tz = ZoneInfo("Asia/Shanghai")
+ return datetime.now(tz)
+
g_pToolManager = CToolManager()