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())