File size: 4,331 Bytes
6e876c1 837a707 6e876c1 837a707 6e876c1 837a707 6e876c1 837a707 6e876c1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | """初始数据:来自 姓名.xlsx 的 15 名真实球员 + 1 名领队(管理员)。
另写入若干「示例比赛 + 示例进球/助攻」用于预览界面,全部可在『管理』页一键清空,
或运行 uv run python -m src.seed --reset-demo 清掉示例只保留队员。
故意留下部分「无记录」场次,演示「默认出勤」聚合。
"""
from __future__ import annotations
import datetime as dt
import logging
import sys
from .config import DEFAULT_PASSWORD
from .db import get_session, init_db
from .models import Match, User
from .repo import add_match, add_user, clear_matches_and_stats, upsert_stat
logger = logging.getLogger(__name__)
# 真实球员名单:(username, 显示名, 球衣号) —— 来自 姓名.xlsx
SEED_PLAYERS = [
("hwl", "HWL", 33),
("hoang", "Hoang", 91),
("zxt", "ZXT", 11),
("leo", "Leo", 9),
("robertlee", "robertlee", 15),
("hakimi", "HAKIMI", 12),
("mark", "MARK", 7),
("lucas", "Lucas", 8),
("xiangchen", "Xiang Chen", 10),
("meng", "Meng", 16),
("zxq", "ZXQ", 6),
("sunny", "Sunny", 30),
("ygx", "YGX", 5),
("jrchen", "JR Chen", 19),
("linjl", "Lin J.L.", 78),
]
# 示例门将(球衣 30):标记为门将后会出现在扑救榜并可录扑救
GK_USERNAMES = {"sunny"}
# 领队(管理员,不计入球员榜单)
MANAGER = ("admin", "领队", None)
# 示例比赛(可在管理页删除):(日期, 对手, 主客, 我方, 对方, 备注)
SEED_MATCHES = [
(dt.date(2024, 3, 10), "南山联队", "home", 3, 1, "示例·可删"),
(dt.date(2024, 3, 24), "福田FC", "away", 2, 2, "示例·可删"),
(dt.date(2024, 4, 7), "罗湖青年", "home", 1, 0, "示例·可删"),
(dt.date(2024, 4, 21), "宝安实业", "away", 0, 2, "示例·可删"),
]
# 示例个人数据:username -> [(场次下标, 进球, 助攻, 出勤), ...]
SEED_STATS = {
"leo": [(0, 2, 0, True), (1, 1, 0, True)],
"mark": [(0, 1, 0, True), (2, 1, 0, True)],
"hakimi": [(0, 0, 1, True), (1, 1, 0, True)],
"hwl": [(0, 0, 1, True), (2, 0, 1, True)],
"xiangchen": [(1, 0, 1, True)],
"zxt": [(3, 0, 0, False)], # 第 4 场缺勤
"meng": [(2, 0, 0, False)], # 第 3 场缺勤
}
# 示例门将扑救:username -> [(场次下标, 扑救数), ...]
SEED_SAVES = {
"sunny": [(0, 4), (1, 6), (2, 3), (3, 5)],
}
def ensure_seed() -> bool:
"""数据库为空时写入名单 + 示例数据。返回是否实际执行。"""
init_db()
with get_session() as s:
if s.query(User).count() > 0:
return False
for username, name, jersey in SEED_PLAYERS:
add_user(
username, name, DEFAULT_PASSWORD, jersey,
is_admin=False, is_player=True,
is_goalkeeper=(username in GK_USERNAMES),
)
add_user(MANAGER[0], MANAGER[1], DEFAULT_PASSWORD, MANAGER[2], is_admin=True, is_player=False)
_seed_demo_matches()
logger.info("已写入名单:%d 名球员 + 1 名领队", len(SEED_PLAYERS))
return True
def _seed_demo_matches() -> None:
for d, opp, ha, our, opp_score, note in SEED_MATCHES:
add_match(d, opp, ha, our, opp_score, note)
with get_session() as s:
uid = {u.username: u.id for u in s.query(User).all()}
match_ids = [
m.id for m in s.query(Match).order_by(Match.match_date, Match.id).all()
]
for username, records in SEED_STATS.items():
if username not in uid:
continue
for idx, goals, assists, attended in records:
upsert_stat(uid[username], match_ids[idx], goals, assists, attended)
# 门将示例扑救(场次默认出勤、0 球 0 助攻、N 次扑救)
for username, records in SEED_SAVES.items():
if username not in uid:
continue
for idx, saves in records:
upsert_stat(uid[username], match_ids[idx], 0, 0, True, saves)
def reset_demo() -> None:
"""清掉示例比赛与数据,保留队员账号。"""
init_db()
n = clear_matches_and_stats()
logger.info("已清空 %d 场示例比赛及相关数据,队员账号保留。", n)
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
if "--reset-demo" in sys.argv:
reset_demo()
else:
print("seeded:", ensure_seed())
|