feat: add modal shop and lottery management
This commit is contained in:
@@ -3,7 +3,7 @@ import random
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from db.models import GameScore, LotteryEvent, LotteryParticipant, ShopItem
|
||||
from db.models import GameScore, LotteryEvent, LotteryParticipant, ShopItem, ShopTransaction
|
||||
|
||||
logger = logging.getLogger("spam_guard")
|
||||
|
||||
@@ -142,13 +142,32 @@ async def upsert_shop_item(chat_id: int, item_key: str, name: str, cost: int, de
|
||||
return item
|
||||
|
||||
|
||||
async def buy_shop_item(chat_id: int, user_id: int, item_id: str) -> dict:
|
||||
async def delete_shop_item(chat_id: int, item_key: str) -> bool:
|
||||
deleted = await ShopItem.filter(chat_id=chat_id, item_key=item_key).delete()
|
||||
return bool(deleted)
|
||||
|
||||
|
||||
async def list_shop_transactions(chat_id: int, limit: int = 100) -> list[dict]:
|
||||
rows = await ShopTransaction.filter(chat_id=chat_id).order_by("-created_at").limit(limit).all()
|
||||
return [{"id": r.id, "chat_id": r.chat_id, "user_id": r.user_id, "username": r.username, "item_key": r.item_key, "item_name": r.item_name, "cost": r.cost, "status": r.status, "note": r.note, "created_at": r.created_at} for r in rows]
|
||||
|
||||
|
||||
async def buy_shop_item(chat_id: int, user_id: int, item_id: str, username: str = "") -> dict:
|
||||
items = await list_shop_items(chat_id)
|
||||
item = next((x for x in items if str(x.get("item_key")) == str(item_id) and x.get("enabled", True)), None)
|
||||
if not item:
|
||||
return {"ok": False, "reason": "商品不存在"}
|
||||
if not await deduct_points(chat_id, user_id, int(item["cost"])):
|
||||
return {"ok": False, "reason": "积分不足", "item": item}
|
||||
await ShopTransaction.create(
|
||||
chat_id=chat_id,
|
||||
user_id=user_id,
|
||||
username=username,
|
||||
item_key=str(item.get("item_key")),
|
||||
item_name=item.get("name") or "",
|
||||
cost=int(item.get("cost") or 0),
|
||||
status="success",
|
||||
)
|
||||
summary = await get_scores_summary(user_id, chat_id)
|
||||
return {"ok": True, "item": item, "total": summary["total"]}
|
||||
|
||||
@@ -171,12 +190,16 @@ def parse_lottery_condition(raw: str) -> tuple[str, int, str]:
|
||||
|
||||
def parse_lottery_end(raw: str) -> tuple[str, int, str]:
|
||||
text = (raw or "people:3").strip().lower()
|
||||
if text in {"instant", "即开", "即开即中"}:
|
||||
return "instant", 1, "即开即中:首位参与者立即中奖"
|
||||
if text.startswith("people:") or text.startswith("人数:"):
|
||||
value = max(1, int(text.split(":", 1)[1]))
|
||||
return "people", value, f"满 {value} 人自动开奖"
|
||||
if text.startswith("minutes:") or text.startswith("分钟:"):
|
||||
value = max(1, int(text.split(":", 1)[1]))
|
||||
return "minutes", value, f"{value} 分钟后自动开奖"
|
||||
return "time", value, f"{value} 分钟后自动开奖"
|
||||
if text.startswith("time:") or text.startswith("时间:"):
|
||||
return "time_at", 0, f"指定时间开奖:{raw.split(':', 1)[1].strip()}"
|
||||
if text in {"manual", "手动"}:
|
||||
return "manual", 0, "手动开奖"
|
||||
raise ValueError(LOTTERY_END_HELP)
|
||||
@@ -207,9 +230,14 @@ async def create_lottery_event(chat_id: int, creator_id: int, creator_name: str,
|
||||
chat_id=chat_id,
|
||||
creator_id=creator_id,
|
||||
creator_name=creator_name,
|
||||
title=spec.get("title") or spec["prize"],
|
||||
description=spec.get("description") or "",
|
||||
prize=spec["prize"],
|
||||
condition_type=spec["condition_type"],
|
||||
condition_value=spec["condition_value"],
|
||||
draw_type=spec.get("draw_type") or spec["end_type"],
|
||||
draw_at=spec.get("draw_at"),
|
||||
max_participants=spec.get("max_participants") or (spec["end_value"] if spec["end_type"] == "people" else 0),
|
||||
end_type=spec["end_type"],
|
||||
end_value=spec["end_value"],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user