diff --git a/app.py b/app.py index f7f9c30..a5ec92c 100644 --- a/app.py +++ b/app.py @@ -259,28 +259,81 @@ def move_config(config_id): @app.route('/api/entities', methods=['GET']) def get_entities(): - """获取企业、用户或场站列表""" + """获取企业、用户或场站列表(支持分页和搜索)""" try: entity_type = request.args.get('type', 'company') + page = int(request.args.get('page', 1)) + page_size = int(request.args.get('page_size', 100)) + search = request.args.get('search', '') + + offset = (page - 1) * page_size if entity_type == 'company': # 获取企业列表 - companies = execute_query( - 'SELECT id AS company_id, company_name FROM t_company WHERE company_state = "1" ORDER BY company_name' - ) - return jsonify({'success': True, 'data': companies}) + if search: + companies = execute_query( + 'SELECT id AS company_id, company_name FROM t_company WHERE company_state = "1" AND company_name LIKE %s ORDER BY company_name LIMIT %s OFFSET %s', + (f'%{search}%', page_size, offset) + ) + total_result = execute_query( + 'SELECT COUNT(*) as total FROM t_company WHERE company_state = "1" AND company_name LIKE %s', + (f'%{search}%',) + ) + else: + companies = execute_query( + 'SELECT id AS company_id, company_name FROM t_company WHERE company_state = "1" ORDER BY company_name LIMIT %s OFFSET %s', + (page_size, offset) + ) + total_result = execute_query( + 'SELECT COUNT(*) as total FROM t_company WHERE company_state = "1"' + ) + total = total_result[0]['total'] if total_result else 0 + return jsonify({'success': True, 'data': companies, 'total': total, 'page': page, 'page_size': page_size}) + elif entity_type == 'station': # 获取场站列表 - stations = execute_query( - 'SELECT id AS station_id, station_name FROM t_station ORDER BY station_name' - ) - return jsonify({'success': True, 'data': stations}) + if search: + stations = execute_query( + 'SELECT id AS station_id, station_name FROM t_station WHERE station_name LIKE %s ORDER BY station_name LIMIT %s OFFSET %s', + (f'%{search}%', page_size, offset) + ) + total_result = execute_query( + 'SELECT COUNT(*) as total FROM t_station WHERE station_name LIKE %s', + (f'%{search}%',) + ) + else: + stations = execute_query( + 'SELECT id AS station_id, station_name FROM t_station ORDER BY station_name LIMIT %s OFFSET %s', + (page_size, offset) + ) + total_result = execute_query( + 'SELECT COUNT(*) as total FROM t_station' + ) + total = total_result[0]['total'] if total_result else 0 + return jsonify({'success': True, 'data': stations, 'total': total, 'page': page, 'page_size': page_size}) + else: - # 获取用户列表 - users = execute_query( - 'SELECT id AS user_id, user_name FROM t_user ORDER BY user_name' - ) - return jsonify({'success': True, 'data': users}) + # 获取用户列表(支持分页和搜索) + if search: + users = execute_query( + 'SELECT id AS user_id, user_name FROM t_user WHERE user_name LIKE %s ORDER BY user_name LIMIT %s OFFSET %s', + (f'%{search}%', page_size, offset) + ) + total_result = execute_query( + 'SELECT COUNT(*) as total FROM t_user WHERE user_name LIKE %s', + (f'%{search}%',) + ) + else: + users = execute_query( + 'SELECT id AS user_id, user_name FROM t_user ORDER BY user_name LIMIT %s OFFSET %s', + (page_size, offset) + ) + total_result = execute_query( + 'SELECT COUNT(*) as total FROM t_user' + ) + total = total_result[0]['total'] if total_result else 0 + return jsonify({'success': True, 'data': users, 'total': total, 'page': page, 'page_size': page_size}) + except Exception as e: return jsonify({'success': False, 'message': str(e)}), 500 diff --git a/assets/image_20260710125630640.png b/assets/image_20260710125630640.png new file mode 100644 index 0000000..df3b7ce Binary files /dev/null and b/assets/image_20260710125630640.png differ diff --git a/templates/index.html b/templates/index.html index e1aa914..323bf7f 100644 --- a/templates/index.html +++ b/templates/index.html @@ -472,10 +472,17 @@
- + +
+ - 按住 Ctrl 或 Shift 键可多选 +
+ 按住 Ctrl 或 Shift 键可多选 +
+
@@ -631,8 +638,14 @@ `).join(''); } - // 加载企业/用户列表 - async function loadEntities() { + // 当前实体加载状态 + let currentEntityType = ''; + let currentPage = 1; + let currentSearch = ''; + const pageSize = 100; + + // 加载企业/用户列表(支持分页和搜索) + async function loadEntities(page = 1, search = '') { const splitType = document.getElementById('split-type').value; const select = document.getElementById('split-value'); @@ -641,50 +654,91 @@ return; } + // 保存当前状态 + currentEntityType = splitType === 'company_id' ? 'company' : + splitType === 'user_id' ? 'user' : + splitType === 'station_id' ? 'station' : ''; + currentPage = page; + currentSearch = search; + select.innerHTML = ''; - // 根据拆分方式确定实体类型 - let entityType = ''; - if (splitType === 'company_id') { - entityType = 'company'; - } else if (splitType === 'user_id') { - entityType = 'user'; - } else if (splitType === 'station_id') { - entityType = 'station'; - } - try { - const response = await fetch(`/api/entities?type=${entityType}`); + const response = await fetch(`/api/entities?type=${currentEntityType}&page=${page}&page_size=${pageSize}&search=${encodeURIComponent(search)}`); const result = await response.json(); if (result.success) { const entities = result.data; - select.innerHTML = '' + - entities.map(e => { + const total = result.total || 0; + const totalPages = Math.ceil(total / pageSize); + + if (entities.length === 0) { + select.innerHTML = ''; + } else { + select.innerHTML = entities.map(e => { let value = ''; let name = ''; let typeLabel = ''; if (splitType === 'company_id') { - value = e.id; - name = e.name; + value = e.company_id; + name = e.company_name; } else if (splitType === 'user_id') { - value = e.id; - name = e.name; + value = e.user_id; + name = e.user_name; typeLabel = e.order_type === 3 ? '(企业用户)' : '(普通用户)'; } else if (splitType === 'station_id') { - value = e.id; - name = e.name; + value = e.station_id; + name = e.station_name; } return ``; }).join(''); + } + + // 更新分页UI + updatePagination(totalPages, total); } } catch (error) { console.error('加载列表失败:', error); + select.innerHTML = ''; } } + // 更新分页UI + function updatePagination(totalPages, total) { + const paginationDiv = document.getElementById('entity-pagination'); + if (totalPages <= 1) { + paginationDiv.innerHTML = `共 ${total} 条`; + return; + } + + let html = `共 ${total} 条`; + html += ``; + html += `${currentPage}/${totalPages}`; + html += ``; + + paginationDiv.innerHTML = html; + } + + // 搜索实体 + function searchEntities() { + const search = document.getElementById('entity-search').value.trim(); + loadEntities(1, search); + } + + // 回车搜索 + document.addEventListener('DOMContentLoaded', function() { + const searchInput = document.getElementById('entity-search'); + if (searchInput) { + searchInput.addEventListener('keypress', function(e) { + if (e.key === 'Enter') { + searchEntities(); + } + }); + } + }); + // 保存配置 async function saveConfig() { const configName = document.getElementById('config-name').value; @@ -762,16 +816,11 @@ document.getElementById('config-name').value = config.config_name; document.getElementById('split-type').value = config.split_type; - await loadEntities(); - - // 处理多选值回显:split_value 可能是逗号分隔的多个值 - const splitValueSelect = document.getElementById('split-value'); + // 获取已选择的值 const splitValues = config.split_value.split(','); - // 清除所有选中状态 - Array.from(splitValueSelect.options).forEach(opt => { - opt.selected = splitValues.includes(opt.value); - }); + // 加载实体并回显 + await loadEntitiesForEdit(config.split_type, splitValues); await loadFields(); renderFields(config.selected_fields, config.sum_fields); @@ -784,6 +833,63 @@ } } + // 加载实体用于编辑回显 + async function loadEntitiesForEdit(splitType, selectedValues) { + const select = document.getElementById('split-value'); + + if (!splitType) { + select.innerHTML = ''; + return; + } + + const entityType = splitType === 'company_id' ? 'company' : + splitType === 'user_id' ? 'user' : + splitType === 'station_id' ? 'station' : ''; + + select.innerHTML = ''; + + try { + // 先加载第一页数据 + const response = await fetch(`/api/entities?type=${entityType}&page=1&page_size=${pageSize}`); + const result = await response.json(); + + if (result.success) { + const entities = result.data; + const total = result.total || 0; + const totalPages = Math.ceil(total / pageSize); + + select.innerHTML = entities.map(e => { + let value = ''; + let name = ''; + let typeLabel = ''; + + if (splitType === 'company_id') { + value = e.company_id; + name = e.company_name; + } else if (splitType === 'user_id') { + value = e.user_id; + name = e.user_name; + typeLabel = e.order_type === 3 ? '(企业用户)' : '(普通用户)'; + } else if (splitType === 'station_id') { + value = e.station_id; + name = e.station_name; + } + + const isSelected = selectedValues.includes(String(value)); + return ``; + }).join(''); + + // 更新分页UI + currentEntityType = entityType; + currentPage = 1; + updatePagination(totalPages, total); + } + } catch (error) { + console.error('加载列表失败:', error); + select.innerHTML = ''; + } + } + // 复制配置 async function copyConfig(configId) { try {