diff --git a/assets/image_20260713154657424.png b/assets/image_20260713154657424.png new file mode 100644 index 0000000..3dfca13 Binary files /dev/null and b/assets/image_20260713154657424.png differ diff --git a/public/static/js/config.js b/public/static/js/config.js index 8f84c4b..fc9e57a 100644 --- a/public/static/js/config.js +++ b/public/static/js/config.js @@ -455,123 +455,20 @@ let currentSearch = ''; const entityPageSize = 100; // 加载企业/用户列表(支持分页和搜索) -async function loadEntities(page = 1, search = '') { - const splitType = document.getElementById('split-type').value; - const select = document.getElementById('split-value'); - - // 显示/隐藏合并特来电选项(仅按企业拆分时显示) - const mergeTelecomGroup = document.getElementById('merge-telecom-group'); - if (mergeTelecomGroup) { - mergeTelecomGroup.style.display = splitType === 'company_id' ? 'block' : 'none'; - if (splitType !== 'company_id') { - document.getElementById('merge-telecom').checked = false; - toggleTelecomVehicleNo(); - } - } - - if (!splitType) { - select.innerHTML = ''; - return; - } - - // 保存当前状态 - currentEntityType = splitType === 'company_id' ? 'company' : - splitType === 'user_id' ? 'user' : - splitType === 'station_id' ? 'station' : ''; - entityPage = page; - currentSearch = search; - - select.innerHTML = ''; - - try { - const response = await fetch(`/api/entities?type=${currentEntityType}&page=${page}&page_size=${entityPageSize}&search=${encodeURIComponent(search)}`); - const result = await response.json(); - - if (result.success) { - const entities = result.data; - const total = result.total || 0; - const totalPages = Math.ceil(total / entityPageSize); - - if (entities.length === 0) { - select.innerHTML = ''; - } else { - 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 ? '(企业用户)' : '(普通用户)'; - if (e.phone) { - name = `${e.user_name} (${e.phone})`; - } - } else if (splitType === 'station_id') { - 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 += `${entityPage}/${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; const splitType = document.getElementById('split-type').value; - const splitValueSelect = document.getElementById('split-value'); + // 处理多选:从 selectedEntityIds 获取选中的实体 + const splitValue = Array.from(selectedEntityIds).join(','); - // 处理多选:获取所有选中的选项 - const selectedOptions = Array.from(splitValueSelect.selectedOptions).filter(opt => opt.value); - const splitValue = selectedOptions.map(opt => opt.value).join(','); - const splitName = selectedOptions.map(opt => opt.dataset.name || '').join(','); + // 获取选中实体的名称(需要从 DOM 中获取) + const container = document.getElementById('entity-list'); + const checkboxes = container.querySelectorAll('input[type="checkbox"]:checked'); + const splitName = Array.from(checkboxes).map(cb => { + const item = cb.closest('.checkbox-item'); + const span = item.querySelector('span'); + return span ? span.textContent.trim() : ''; + }).join(','); // 获取字段顺序(从已选字段顺序列表获取) const selectedFields = getSelectedFieldsOrder(); @@ -707,10 +604,10 @@ async function editConfig(configId) { // 加载实体用于编辑回显 async function loadEntitiesForEdit(splitType, selectedValues) { - const select = document.getElementById('split-value'); + const container = document.getElementById('entity-list'); if (!splitType) { - select.innerHTML = ''; + container.innerHTML = '
请先选择拆分方式
'; return; } @@ -718,7 +615,7 @@ async function loadEntitiesForEdit(splitType, selectedValues) { splitType === 'user_id' ? 'user' : splitType === 'station_id' ? 'station' : ''; - select.innerHTML = ''; + container.innerHTML = '
加载中...
'; try { // 先查询已选择的实体信息 @@ -747,6 +644,10 @@ async function loadEntitiesForEdit(splitType, selectedValues) { // 构建已选择实体的ID集合 const selectedIdSet = new Set(selectedValues); + // 清空并重建 selectedEntityIds + selectedEntityIds.clear(); + selectedValues.forEach(v => selectedEntityIds.add(String(v))); + // 合并已选择的实体和第一页数据(去重) const mergedEntities = []; const addedIds = new Set(); @@ -806,19 +707,27 @@ async function loadEntitiesForEdit(splitType, selectedValues) { } } - // 渲染选项 - select.innerHTML = mergedEntities.map(item => - `` - ).join(''); + // 渲染 checkbox 列表 + container.innerHTML = mergedEntities.map(item => { + const isChecked = item.isSelected ? 'checked' : ''; + const checkedClass = item.isSelected ? 'checked' : ''; + return ` +
+ + ${item.name} ${item.typeLabel} +
+ `; + }).join(''); // 更新分页UI currentEntityType = entityType; entityPage = 1; - updatePagination(totalPages, total); + updateEntityPagination(totalPages, total); + updateSelectedCount(); } } catch (error) { console.error('加载列表失败:', error); - select.innerHTML = ''; + container.innerHTML = '
加载失败
'; } } diff --git a/public/static/js/entity.js b/public/static/js/entity.js index f0ed775..75d4429 100644 --- a/public/static/js/entity.js +++ b/public/static/js/entity.js @@ -1,23 +1,29 @@ -// 加载企业/用户列表(支持分页和搜索) +// 当前选中的实体ID集合 +let selectedEntityIds = new Set(); + +// 加载企业/用户/场站列表(checkbox 列表) async function loadEntities(page = 1, search = '') { const splitType = document.getElementById('split-type').value; - const select = document.getElementById('split-value'); - - // 显示/隐藏合并特来电选项(仅按企业拆分时显示) - const mergeTelecomGroup = document.getElementById('merge-telecom-group'); - if (mergeTelecomGroup) { - mergeTelecomGroup.style.display = splitType === 'company_id' ? 'block' : 'none'; - if (splitType !== 'company_id') { - document.getElementById('merge-telecom').checked = false; - toggleTelecomVehicleNo(); - } - } + const container = document.getElementById('entity-list'); if (!splitType) { - select.innerHTML = ''; + container.innerHTML = '
请先选择拆分方式
'; return; } + // 显示/隐藏合并特来电选项(仅按企业拆分时显示) + const mergeTelecomSection = document.getElementById('telecom-vehicle-section'); + const mergeTelecomCheckbox = document.getElementById('merge-telecom'); + if (mergeTelecomSection && mergeTelecomCheckbox) { + if (splitType === 'company_id') { + mergeTelecomCheckbox.parentElement.style.display = 'block'; + } else { + mergeTelecomCheckbox.parentElement.style.display = 'none'; + mergeTelecomCheckbox.checked = false; + toggleTelecomVehicleNo(); + } + } + // 保存当前状态 currentEntityType = splitType === 'company_id' ? 'company' : splitType === 'user_id' ? 'user' : @@ -25,7 +31,7 @@ async function loadEntities(page = 1, search = '') { entityPage = page; currentSearch = search; - select.innerHTML = ''; + container.innerHTML = '
加载中...
'; try { const response = await fetch(`/api/entities?type=${currentEntityType}&page=${page}&page_size=${entityPageSize}&search=${encodeURIComponent(search)}`); @@ -37,9 +43,9 @@ async function loadEntities(page = 1, search = '') { const totalPages = Math.ceil(total / entityPageSize); if (entities.length === 0) { - select.innerHTML = ''; + container.innerHTML = '
无数据
'; } else { - select.innerHTML = entities.map(e => { + container.innerHTML = entities.map(e => { let value = ''; let name = ''; let typeLabel = ''; @@ -59,31 +65,85 @@ async function loadEntities(page = 1, search = '') { name = e.station_name; } - return ``; + const isChecked = selectedEntityIds.has(String(value)) ? 'checked' : ''; + return ` +
+ + ${name} ${typeLabel} +
+ `; }).join(''); } // 更新分页UI - updatePagination(totalPages, total); + updateEntityPagination(totalPages, total); + updateSelectedCount(); } } catch (error) { console.error('加载列表失败:', error); - select.innerHTML = ''; + container.innerHTML = '
加载失败
'; } } -// 更新分页UI -function updatePagination(totalPages, total) { +// 切换实体 checkbox +function toggleEntityCheckbox(item, value) { + const checkbox = item.querySelector('input[type="checkbox"]'); + checkbox.checked = !checkbox.checked; + + if (checkbox.checked) { + item.classList.add('checked'); + selectedEntityIds.add(String(value)); + } else { + item.classList.remove('checked'); + selectedEntityIds.delete(String(value)); + } + + updateSelectedCount(); +} + +// 更新已选数量显示 +function updateSelectedCount() { + const countSpan = document.getElementById('selected-count'); + if (countSpan) { + countSpan.textContent = `已选:${selectedEntityIds.size} 个`; + } +} + +// 全选/取消全选实体 +function toggleSelectAllEntities() { + const container = document.getElementById('entity-list'); + const checkboxes = container.querySelectorAll('input[type="checkbox"]'); + const allChecked = Array.from(checkboxes).every(cb => cb.checked); + + checkboxes.forEach(cb => { + cb.checked = !allChecked; + const item = cb.closest('.checkbox-item'); + if (cb.checked) { + item.classList.add('checked'); + selectedEntityIds.add(cb.value); + } else { + item.classList.remove('checked'); + selectedEntityIds.delete(cb.value); + } + }); + + updateSelectedCount(); +} + +// 更新实体分页UI +function updateEntityPagination(totalPages, total) { const paginationDiv = document.getElementById('entity-pagination'); + if (!paginationDiv) return; + if (totalPages <= 1) { - paginationDiv.innerHTML = `共 ${total} 条`; + paginationDiv.innerHTML = `共 ${total} 条`; return; } - let html = `共 ${total} 条`; - html += ``; + let html = `共 ${total} 条`; + html += ``; html += `${entityPage}/${totalPages}`; - html += ``; + html += ``; paginationDiv.innerHTML = html; } @@ -106,3 +166,8 @@ document.addEventListener('DOMContentLoaded', function() { } }); +// 拆分方式变化时重新加载实体列表 +function onSplitTypeChange() { + selectedEntityIds.clear(); + loadEntities(1, ''); +}