Files
drl_2/xuexiao/scripts/global_check.py

89 lines
3.2 KiB
Python
Raw Normal View History

2026-05-29 10:28:07 +08:00
"""全局自检:路由、数据、财务展示。用法: python scripts/global_check.py"""
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
ISSUES = []
def issue(level, code, msg):
ISSUES.append((level, code, msg))
print(f'[{level}] {code}: {msg}')
def main():
from app import create_app
from models import (
db, StudentAccount, Course, MonthlySnapshot, RechargeRecord,
ConsumptionRecord, RefundRecord,
)
app = create_app()
with app.app_context():
# 数据健康
n_recharge = RechargeRecord.query.count()
n_consume = ConsumptionRecord.query.count()
n_snap = MonthlySnapshot.query.count()
n_course_price = Course.query.filter(Course.price_per_hour > 0).count()
n_orig = StudentAccount.query.filter(
StudentAccount.original_price_per_lesson > 0,
).count()
if n_snap > 100 and n_recharge == 0 and n_consume == 0:
issue(
'INFO', 'DATA-01',
'业务数据主要来自 Excel 快照(充值/消课表为空),统计页应看「课时核对表」月份',
)
if n_snap > 0 and n_orig == 0:
issue(
'WARN', 'DATA-02',
'账户未写入 original_price_per_lesson;已支持从快照单价回填,请重启 app',
)
if n_course_price == 0:
issue(
'WARN', 'DATA-03',
'课程表 price_per_hour 均为 0,建议在「课程管理」维护原价单价',
)
# 路由冒烟
client = app.test_client()
client.post('/login', data={'username': 'admin', 'password': 'admin123'})
paths = [
'/students', '/students/detail/1', '/statistics',
'/keshibiao/snapshots?year=2026&month=4',
]
for p in paths:
r = client.get(p, follow_redirects=True)
if r.status_code >= 500:
issue('FAIL', 'HTTP', f'{p} -> {r.status_code}')
# 财务计算抽样
from finance_display import account_refund_display, build_refund_preview
from keshi_display import attach_latest_snapshots, snapshot_lessons_display, get_latest_period
py, pm = get_latest_period()
acc = StudentAccount.query.first()
if acc:
snap = attach_latest_snapshots([acc], py, pm).get(acc.id)
lg = snapshot_lessons_display(snap, acc) if snap else {}
d = account_refund_display(acc, lg, snap)
if d['kind'] == 'no_price' and snap and float(snap.unit_price or 0) > 0:
issue(
'WARN', 'FIN-01',
'快照有单价但应退仍为「-」,请重启以执行单价回填',
)
print('\n=== 汇总 ===')
if not ISSUES:
print('未发现阻塞性问题。')
else:
fails = [i for i in ISSUES if i[0] == 'FAIL']
print(f'共 {len(ISSUES)} 条(失败 {len(fails)})')
return 1 if any(i[0] == 'FAIL' for i in ISSUES) else 0
if __name__ == '__main__':
sys.exit(main())