"""初始数据:来自 姓名.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())