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, '');
+}