feat: 消课添加页面添加学员搜索功能
Coze-Commit-Type: user Coze-User-ID: 3722323274763196 Coze-Conversation-ID: 5260473
This commit is contained in:
Binary file not shown.
@@ -11,6 +11,23 @@ import business_rules as rules
|
|||||||
|
|
||||||
def register_routes(app):
|
def register_routes(app):
|
||||||
|
|
||||||
|
@app.route('/api/students/search', endpoint='api_student_search')
|
||||||
|
@login_required
|
||||||
|
def api_student_search():
|
||||||
|
"""学员搜索API"""
|
||||||
|
keyword = request.args.get('q', '')
|
||||||
|
if len(keyword) < 1:
|
||||||
|
return {'data': []}
|
||||||
|
|
||||||
|
# 直接搜索学员,不受权限限制
|
||||||
|
students = Student.query.filter(
|
||||||
|
Student.name.contains(keyword),
|
||||||
|
Student.status == 1
|
||||||
|
).limit(20).all()
|
||||||
|
|
||||||
|
results = [{'id': s.id, 'name': s.name} for s in students]
|
||||||
|
return {'data': results}
|
||||||
|
|
||||||
@app.route('/consumptions', endpoint='consumption_list')
|
@app.route('/consumptions', endpoint='consumption_list')
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('consumption_view')
|
@permission_required('consumption_view')
|
||||||
|
|||||||
@@ -22,12 +22,14 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">选择学员 <span class="text-danger">*</span></label>
|
<label class="form-label">选择学员 <span class="text-danger">*</span></label>
|
||||||
<select class="form-select" name="student_id" id="student_id" required>
|
<div class="input-group">
|
||||||
<option value="">请选择学员</option>
|
<input type="text" class="form-control" id="student_search" placeholder="输入学员姓名搜索" autocomplete="off">
|
||||||
{% for s in students %}
|
<select class="form-select" name="student_id" id="student_id" required style="display:none;">
|
||||||
<option value="{{ s.id }}">{{ s.name }}</option>
|
<option value="">请选择学员</option>
|
||||||
{% endfor %}
|
</select>
|
||||||
</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>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">选择班级</label>
|
<label class="form-label">选择班级</label>
|
||||||
@@ -101,6 +103,79 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('student_id').addEventListener('change', loadAccount);
|
document.getElementById('student_id').addEventListener('change', loadAccount);
|
||||||
document.getElementById('course_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() {
|
function loadAccount() {
|
||||||
var sid = document.getElementById('student_id').value;
|
var sid = document.getElementById('student_id').value;
|
||||||
var cid = document.getElementById('course_id').value;
|
var cid = document.getElementById('course_id').value;
|
||||||
|
|||||||
@@ -242,6 +242,9 @@ def login_required(f):
|
|||||||
@wraps(f)
|
@wraps(f)
|
||||||
def decorated(*args, **kwargs):
|
def decorated(*args, **kwargs):
|
||||||
if not session.get('user_id'):
|
if not session.get('user_id'):
|
||||||
|
from flask import request, jsonify
|
||||||
|
if request.is_xhr or request.headers.get('Content-Type') == 'application/json':
|
||||||
|
return jsonify({'error': '请先登录'}), 401
|
||||||
flash('请先登录', 'warning')
|
flash('请先登录', 'warning')
|
||||||
return redirect(url_for('login'))
|
return redirect(url_for('login'))
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
|
|||||||
Reference in New Issue
Block a user