fix: 修复实体管理模块,使用 checkbox 列表替代 select 下拉框
Coze-Commit-Type: user Coze-User-ID: 3722323274763196 Coze-Conversation-ID: 9894087
This commit is contained in:
@@ -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 = '<option value="">请先选择拆分方式</option>';
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存当前状态
|
||||
currentEntityType = splitType === 'company_id' ? 'company' :
|
||||
splitType === 'user_id' ? 'user' :
|
||||
splitType === 'station_id' ? 'station' : '';
|
||||
entityPage = page;
|
||||
currentSearch = search;
|
||||
|
||||
select.innerHTML = '<option value="">加载中...</option>';
|
||||
|
||||
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 = '<option value="">无数据</option>';
|
||||
} 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 `<option value="${value}" data-name="${name}">${name} ${typeLabel}</option>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// 更新分页UI
|
||||
updatePagination(totalPages, total);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载列表失败:', error);
|
||||
select.innerHTML = '<option value="">加载失败</option>';
|
||||
}
|
||||
}
|
||||
|
||||
// 更新分页UI
|
||||
function updatePagination(totalPages, total) {
|
||||
const paginationDiv = document.getElementById('entity-pagination');
|
||||
if (totalPages <= 1) {
|
||||
paginationDiv.innerHTML = `<small class="text-muted">共 ${total} 条</small>`;
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `<small class="text-muted">共 ${total} 条</small>`;
|
||||
html += `<button type="button" class="btn btn-sm btn-secondary" onclick="loadEntities(${entityPage - 1}, currentSearch)" ${entityPage <= 1 ? 'disabled' : ''}>上一页</button>`;
|
||||
html += `<span>${entityPage}/${totalPages}</span>`;
|
||||
html += `<button type="button" class="btn btn-sm btn-secondary" onclick="loadEntities(${entityPage + 1}, currentSearch)" ${entityPage >= totalPages ? 'disabled' : ''}>下一页</button>`;
|
||||
|
||||
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 = '<option value="">请先选择拆分方式</option>';
|
||||
container.innerHTML = '<div class="empty">请先选择拆分方式</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -718,7 +615,7 @@ async function loadEntitiesForEdit(splitType, selectedValues) {
|
||||
splitType === 'user_id' ? 'user' :
|
||||
splitType === 'station_id' ? 'station' : '';
|
||||
|
||||
select.innerHTML = '<option value="">加载中...</option>';
|
||||
container.innerHTML = '<div class="loading">加载中...</div>';
|
||||
|
||||
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 =>
|
||||
`<option value="${item.value}" data-name="${item.name}" ${item.isSelected ? 'selected' : ''}>${item.name} ${item.typeLabel}</option>`
|
||||
).join('');
|
||||
// 渲染 checkbox 列表
|
||||
container.innerHTML = mergedEntities.map(item => {
|
||||
const isChecked = item.isSelected ? 'checked' : '';
|
||||
const checkedClass = item.isSelected ? 'checked' : '';
|
||||
return `
|
||||
<div class="checkbox-item ${checkedClass}" onclick="toggleEntityCheckbox(this, '${item.value}')">
|
||||
<input type="checkbox" value="${item.value}" ${isChecked} onclick="event.stopPropagation()">
|
||||
<span>${item.name} ${item.typeLabel}</span>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
// 更新分页UI
|
||||
currentEntityType = entityType;
|
||||
entityPage = 1;
|
||||
updatePagination(totalPages, total);
|
||||
updateEntityPagination(totalPages, total);
|
||||
updateSelectedCount();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载列表失败:', error);
|
||||
select.innerHTML = '<option value="">加载失败</option>';
|
||||
container.innerHTML = '<div class="empty">加载失败</div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = '<option value="">请先选择拆分方式</option>';
|
||||
container.innerHTML = '<div class="empty">请先选择拆分方式</div>';
|
||||
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 = '<option value="">加载中...</option>';
|
||||
container.innerHTML = '<div class="loading">加载中...</div>';
|
||||
|
||||
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 = '<option value="">无数据</option>';
|
||||
container.innerHTML = '<div class="empty">无数据</div>';
|
||||
} 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 `<option value="${value}" data-name="${name}">${name} ${typeLabel}</option>`;
|
||||
const isChecked = selectedEntityIds.has(String(value)) ? 'checked' : '';
|
||||
return `
|
||||
<div class="checkbox-item ${isChecked}" onclick="toggleEntityCheckbox(this, '${value}')">
|
||||
<input type="checkbox" value="${value}" ${isChecked} onclick="event.stopPropagation()">
|
||||
<span>${name} ${typeLabel}</span>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// 更新分页UI
|
||||
updatePagination(totalPages, total);
|
||||
updateEntityPagination(totalPages, total);
|
||||
updateSelectedCount();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载列表失败:', error);
|
||||
select.innerHTML = '<option value="">加载失败</option>';
|
||||
container.innerHTML = '<div class="empty">加载失败</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// 更新分页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 = `<small class="text-muted">共 ${total} 条</small>`;
|
||||
paginationDiv.innerHTML = `<small style="color: var(--muted-foreground);">共 ${total} 条</small>`;
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `<small class="text-muted">共 ${total} 条</small>`;
|
||||
html += `<button type="button" class="btn btn-sm btn-secondary" onclick="loadEntities(${entityPage - 1}, currentSearch)" ${entityPage <= 1 ? 'disabled' : ''}>上一页</button>`;
|
||||
let html = `<small style="color: var(--muted-foreground);">共 ${total} 条</small>`;
|
||||
html += `<button type="button" class="btn btn-sm" onclick="loadEntities(${entityPage - 1}, currentSearch)" ${entityPage <= 1 ? 'disabled' : ''}>上一页</button>`;
|
||||
html += `<span>${entityPage}/${totalPages}</span>`;
|
||||
html += `<button type="button" class="btn btn-sm btn-secondary" onclick="loadEntities(${entityPage + 1}, currentSearch)" ${entityPage >= totalPages ? 'disabled' : ''}>下一页</button>`;
|
||||
html += `<button type="button" class="btn btn-sm" onclick="loadEntities(${entityPage + 1}, currentSearch)" ${entityPage >= totalPages ? 'disabled' : ''}>下一页</button>`;
|
||||
|
||||
paginationDiv.innerHTML = html;
|
||||
}
|
||||
@@ -106,3 +166,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
});
|
||||
|
||||
// 拆分方式变化时重新加载实体列表
|
||||
function onSplitTypeChange() {
|
||||
selectedEntityIds.clear();
|
||||
loadEntities(1, '');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user