Files
drl_2/xuexiao/templates/keshibiao_snapshots.html
user9994793890 ee860ce0ae Initial commit
2026-05-29 10:28:07 +08:00

131 lines
7.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% from 'macros/sortable.html' import sort_th %}
{% block title %}学员课时余额{% endblock %}
{% block content %}
<div class="page-toolbar">
<div>
<h4 class="page-title"><i class="bi bi-wallet2"></i> 学员课时余额</h4>
<p class="page-sub text-muted">
数据来自课时核对表 Excel 导入 · 当前查看
<strong class="text-primary">{{ year }}-{{ '%02d'|format(month) }}</strong>
{% if total %}(共 {{ total }} 条学员×课程){% endif %}
</p>
</div>
<div class="d-flex gap-2">
<a href="{{ url_for('keshibiao_index') }}" class="btn btn-neo-secondary btn-sm"><i class="bi bi-cloud-upload"></i> 导入</a>
</div>
</div>
{% if period_stats_list %}
<div class="neo-surface p-3 mb-3">
<div class="small text-muted mb-2">切换月份(数字为当月导入条数,请选 400+ 条的完整月份)</div>
<div class="d-flex flex-wrap gap-2">
{% for p in period_stats_list %}
<a href="{{ url_for('keshibiao_snapshots', year=p.year, month=p.month, keyword=keyword or '', sort=sort or none, order=order if sort else none) }}"
class="btn btn-sm {% if year == p.year and month == p.month %}btn-primary{% elif p.count < 20 %}btn-outline-warning{% else %}btn-outline-secondary{% endif %}">
{{ p.year }}-{{ '%02d'|format(p.month) }}
<span class="badge {% if year == p.year and month == p.month %}bg-light text-primary{% else %}bg-secondary{% endif %} ms-1">{{ p.count }}</span>
</a>
{% endfor %}
</div>
</div>
{% endif %}
<div class="neo-surface p-3 mb-3">
<form method="GET" class="row g-2 align-items-end">
<input type="hidden" name="year" value="{{ year }}">
<input type="hidden" name="month" value="{{ month }}">
{% if sort %}<input type="hidden" name="sort" value="{{ sort }}">{% endif %}
{% if sort %}<input type="hidden" name="order" value="{{ order }}">{% endif %}
<div class="col-md-6">
<label class="form-label">搜索学员或课程</label>
<input type="text" class="form-control" name="keyword" value="{{ keyword or '' }}" placeholder="姓名 / scratch / 大班 …">
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-neo-primary w-100"><i class="bi bi-search"></i> 搜索</button>
</div>
</form>
</div>
<div class="neo-table-wrap">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0 keshi-balance-table">
<thead class="table-light sticky-top">
<tr>
<th>{{ sort_th('keshibiao_snapshots', 'student', '学员', sort, order, list_params, '') }}</th>
<th>{{ sort_th('keshibiao_snapshots', 'course', '课程', sort, order, list_params, '') }}</th>
<th class="text-end keshi-col-key">{{ sort_th('keshibiao_snapshots', 'end_lessons', '正课剩余', sort, order, list_params) }}</th>
<th class="text-end">{{ sort_th('keshibiao_snapshots', 'end_gift', '赠课剩余', sort, order, list_params) }}</th>
<th class="text-end keshi-col-key">{{ sort_th('keshibiao_snapshots', 'end_total', '总剩余课时', sort, order, list_params) }}</th>
<th class="text-end keshi-col-money">{{ sort_th('keshibiao_snapshots', 'end_balance', '账户余额', sort, order, list_params, title='折后口径账面余额') }}</th>
<th class="text-end keshi-col-money">{{ sort_th('keshibiao_snapshots', 'unit_price', '单价/节', sort, order, list_params) }}</th>
<th class="text-end">{{ sort_th('keshibiao_snapshots', 'consumed', '本月消课', sort, order, list_params) }}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for item in rows %}
{% set s = item.snap %}
{% set d = item.disp if item.disp is mapping else {} %}
{% set acc = item.acc %}
{% set stu = acc.student if acc else none %}
{% set crs = acc.course if acc else none %}
<tr>
<td>
{% if stu %}
<a href="{{ url_for('student_detail', id=stu.id) }}" class="fw-semibold text-decoration-none">{{ stu.name }}</a>
{% else %}<span class="text-muted">—</span>{% endif %}
</td>
<td><span class="badge bg-secondary-subtle text-dark border">{{ crs.course_code or crs.name if crs else '—' }}</span></td>
<td class="text-end keshi-col-key fs-6">{{ fmt_hours(d.get('end_lessons')) }}</td>
<td class="text-end">{{ fmt_hours(d.get('end_gift_lessons')) }}</td>
<td class="text-end keshi-col-key fs-5 fw-bold text-primary">{{ fmt_hours(d.get('end_total_lessons')) }}</td>
<td class="text-end keshi-col-money fs-5 fw-bold text-success">{{ fmt_money(d.get('end_balance')) }}</td>
<td class="text-end keshi-col-money fw-semibold">{{ fmt_price(d.get('unit_price')) }}</td>
<td class="text-end text-muted">{{ fmt_hours(s.consumed_lessons) }}</td>
<td>
{% if acc %}
<a href="{{ url_for('keshibiao_account', account_id=acc.id) }}" class="btn btn-sm btn-outline-primary">明细</a>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td colspan="9" class="text-center py-5">
<p class="text-muted mb-2">当前月份没有可显示的数据</p>
{% if period_stats_list %}
<p class="small">请点上方 <strong>2026-04(492)</strong> 等条数较多的月份;勿选仅 1 条的测试月。</p>
{% else %}
<p class="small">请先在「课时核对表」页导入 Excel。</p>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% if total > per_page %}
<nav class="mt-3">
<ul class="pagination justify-content-center">
{% if page > 1 %}
<li class="page-item"><a class="page-link" href="{{ url_for('keshibiao_snapshots', page=page-1, **list_params) }}">上一页</a></li>
{% endif %}
<li class="page-item disabled"><span class="page-link">第 {{ page }} / {{ ((total-1)//per_page)+1 }} 页</span></li>
{% if page * per_page < total %}
<li class="page-item"><a class="page-link" href="{{ url_for('keshibiao_snapshots', page=page+1, **list_params) }}">下一页</a></li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endblock %}
{% block extra_css %}
<style>
.keshi-balance-table .keshi-col-key { min-width: 4.5rem; }
.keshi-balance-table .keshi-col-money { min-width: 6.5rem; }
.keshi-balance-table thead.sticky-top { top: 0; z-index: 2; }
</style>
{% endblock %}