201 lines
8.8 KiB
HTML
201 lines
8.8 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{% if batch %}批量消课{% else %}单个消课{% endif %}{% endblock %}
|
|
{% block content %}
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h4><i class="bi bi-journal-check"></i> {% if batch %}批量消课{% else %}单个消课{% endif %}</h4>
|
|
<a href="{{ url_for('consumption_list') }}" class="btn btn-outline-secondary"><i class="bi bi-arrow-left"></i> 返回</a>
|
|
</div>
|
|
<div class="card shadow-sm">
|
|
<div class="card-body">
|
|
<form method="POST">
|
|
<div class="row g-3">
|
|
{% if batch %}
|
|
<div class="col-md-6">
|
|
<label class="form-label">选择班级 <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="class_id" required>
|
|
<option value="">请选择班级</option>
|
|
{% for c in classes %}
|
|
<option value="{{ c.id }}">{{ c.name }} - {{ c.course.name }}({{ c.current_students }}人)</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
{% else %}
|
|
<div class="col-md-4">
|
|
<label class="form-label">选择学员 <span class="text-danger">*</span></label>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" id="student_search" placeholder="输入学员姓名搜索" autocomplete="off">
|
|
<select class="form-select" name="student_id" id="student_id" required style="display:none;">
|
|
<option value="">请选择学员</option>
|
|
</select>
|
|
<button class="btn btn-outline-secondary" type="button" id="clear_student">清除</button>
|
|
</div>
|
|
<div id="student_suggestions" class="list-group position-absolute w-100" style="z-index:1000; max-height:200px; overflow-y:auto;"></div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">选择班级</label>
|
|
<select class="form-select" name="class_id">
|
|
<option value="">不限</option>
|
|
{% for c in classes %}
|
|
<option value="{{ c.id }}">{{ c.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="col-md-4">
|
|
<label class="form-label">选择课程 <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="course_id" id="course_id" required>
|
|
<option value="">请选择课程</option>
|
|
{% for c in courses %}
|
|
<option value="{{ c.id }}">{{ c.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">消课课时 <span class="text-danger">*</span></label>
|
|
<input type="number" step="1" class="form-control" name="hours_consumed" value="1" min="1" required>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">上课日期</label>
|
|
<input type="date" class="form-control" name="consume_date" value="{{ today }}">
|
|
</div>
|
|
|
|
{% if not batch %}
|
|
<div class="col-md-3">
|
|
<label class="form-label">是否补录</label>
|
|
<select class="form-select" name="is_makeup">
|
|
<option value="0">否</option>
|
|
<option value="1">是</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">试听课(不扣课)</label>
|
|
<select class="form-select" name="is_trial">
|
|
<option value="0">否</option>
|
|
<option value="1">是(试听)</option>
|
|
</select>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="col-md-6">
|
|
<label class="form-label">备注</label>
|
|
<input type="text" class="form-control" name="remark" placeholder="可选">
|
|
</div>
|
|
</div>
|
|
|
|
{% if not batch %}
|
|
<div class="mt-3">
|
|
<div id="accountInfo" class="alert alert-light" style="display:none;"></div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="mt-3">
|
|
<button type="submit" class="btn btn-primary"><i class="bi bi-check-lg"></i> 确认消课</button>
|
|
<a href="{{ url_for('consumption_list') }}" class="btn btn-outline-secondary">取消</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
{% if not batch %}
|
|
<script>
|
|
document.getElementById('student_id').addEventListener('change', loadAccount);
|
|
document.getElementById('course_id').addEventListener('change', loadAccount);
|
|
|
|
// 学员搜索功能
|
|
var searchTimeout = null;
|
|
document.getElementById('student_search').addEventListener('input', function(e) {
|
|
var keyword = e.target.value.trim();
|
|
var suggestions = document.getElementById('student_suggestions');
|
|
var studentSelect = document.getElementById('student_id');
|
|
|
|
if (keyword.length < 1) {
|
|
suggestions.innerHTML = '';
|
|
return;
|
|
}
|
|
|
|
clearTimeout(searchTimeout);
|
|
searchTimeout = setTimeout(function() {
|
|
fetch('/api/students/search?q=' + encodeURIComponent(keyword))
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
suggestions.innerHTML = '';
|
|
if (data.data.length === 0) {
|
|
suggestions.innerHTML = '<div class="list-group-item text-muted">未找到学员</div>';
|
|
return;
|
|
}
|
|
data.data.forEach(function(s) {
|
|
var item = document.createElement('a');
|
|
item.href = '#';
|
|
item.className = 'list-group-item list-group-item-action';
|
|
item.textContent = s.name;
|
|
item.dataset.id = s.id;
|
|
item.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
selectStudent(s.id, s.name);
|
|
});
|
|
suggestions.appendChild(item);
|
|
});
|
|
});
|
|
}, 200);
|
|
});
|
|
|
|
function selectStudent(id, name) {
|
|
var studentSelect = document.getElementById('student_id');
|
|
var searchInput = document.getElementById('student_search');
|
|
var suggestions = document.getElementById('student_suggestions');
|
|
|
|
// 设置select的值
|
|
studentSelect.innerHTML = '<option value="' + id + '" selected>' + name + '</option>';
|
|
studentSelect.style.display = 'block';
|
|
searchInput.value = name;
|
|
suggestions.innerHTML = '';
|
|
|
|
// 触发账户信息加载
|
|
loadAccount();
|
|
}
|
|
|
|
document.getElementById('clear_student').addEventListener('click', function() {
|
|
var studentSelect = document.getElementById('student_id');
|
|
var searchInput = document.getElementById('student_search');
|
|
var suggestions = document.getElementById('student_suggestions');
|
|
|
|
studentSelect.innerHTML = '<option value="">请选择学员</option>';
|
|
studentSelect.style.display = 'block';
|
|
searchInput.value = '';
|
|
suggestions.innerHTML = '';
|
|
document.getElementById('accountInfo').style.display = 'none';
|
|
});
|
|
|
|
// 点击其他地方关闭建议列表
|
|
document.addEventListener('click', function(e) {
|
|
if (!e.target.closest('#student_search') && !e.target.closest('#student_suggestions')) {
|
|
document.getElementById('student_suggestions').innerHTML = '';
|
|
}
|
|
});
|
|
|
|
function loadAccount() {
|
|
var sid = document.getElementById('student_id').value;
|
|
var cid = document.getElementById('course_id').value;
|
|
if (!sid || !cid) return;
|
|
fetch('/api/student_account/' + sid + '/' + cid)
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
var el = document.getElementById('accountInfo');
|
|
if (data.success) {
|
|
var d = data.data;
|
|
el.style.display = 'block';
|
|
el.innerHTML = '<strong>课时余额:</strong>正课 ' + d.normal_hours + ' 课时,赠课 ' + d.gifted_hours + ' 课时,合计 ' + d.total_hours + ' 课时';
|
|
if (d.is_stopped) el.innerHTML += ' <span class="text-danger">(停课中)</span>';
|
|
} else {
|
|
el.style.display = 'block';
|
|
el.innerHTML = '<span class="text-danger">未找到课时账户</span>';
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
{% endif %}
|
|
{% endblock %}
|