From d34dd82bd55295e15e014937be11e133ad587fe1 Mon Sep 17 00:00:00 2001 From: haoslm <6083297@qq.com> Date: Wed, 15 Jul 2026 14:35:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=BE=91=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=8C=E4=BF=9D=E5=AD=98=E5=92=8C=E5=9B=9E=E6=98=BE?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/field_mapping.py | 2 +- public/static/css/style.css | 12 ++++++ public/static/js/config.js | 83 ++++++++++++++++++++++++------------- public/static/js/entity.js | 55 +++++++++++++++++++++--- templates/index.html | 14 +++---- 5 files changed, 125 insertions(+), 41 deletions(-) diff --git a/lib/field_mapping.py b/lib/field_mapping.py index 8b137b0..406086d 100644 --- a/lib/field_mapping.py +++ b/lib/field_mapping.py @@ -129,7 +129,7 @@ FIELD_MAPPING = { # 订单完成信息 'finish_type': '完成类型', 'finish_code': '完成代码', - 'finish_msg': '完成消息', + 'finish_msg': '结束原因', 'finish_time': '完成时间', # 取消信息 diff --git a/public/static/css/style.css b/public/static/css/style.css index 2e4f0a2..b0b683b 100644 --- a/public/static/css/style.css +++ b/public/static/css/style.css @@ -397,6 +397,18 @@ font-weight: 500; margin-left: 4px; } +.field-key-name { +color: #999; +font-size: 12px; +font-family: Consolas, Monaco, monospace; +font-weight: normal; +} + +.entity-selected-top { +border-left: 3px solid #4472C4; +padding-left: 7px; +} + .checkbox-item input[type="checkbox"] { width: 16px; height: 16px; diff --git a/public/static/js/config.js b/public/static/js/config.js index 721ecaa..15ad49d 100644 --- a/public/static/js/config.js +++ b/public/static/js/config.js @@ -62,6 +62,8 @@ function showCreateModal() { document.getElementById('modal-title').textContent = '创建配置'; document.getElementById('config-name').value = ''; document.getElementById('split-type').value = ''; + // 清空已选实体 + selectedEntityIds.clear(); // 清空实体列表 document.getElementById('entity-list').innerHTML = '
请先选择拆分方式
'; document.getElementById('entity-search').value = ''; @@ -141,7 +143,7 @@ function renderFields(selectedFields = [], sumFields = []) { ${isSelected ? 'checked' : ''} ${isRequired ? 'disabled checked' : ''} onchange="onFieldCheckboxChange(this)"> - + `; }).join(''); @@ -209,13 +211,13 @@ function refreshSelectedFieldsOrder(selectedFields, customNames = null) { return `
#${index + 1} - ${displayName} + ${displayName} (${fieldKey})
- - + +
`; @@ -238,10 +240,12 @@ function getFieldCustomNames() { } // 字段上移 -function moveFieldUp(index) { - if (index <= 0) return; +function moveFieldUp(fieldKey) { const orderList = document.getElementById('selected-fields-order'); const items = Array.from(orderList.querySelectorAll('.selected-field-item')); + const index = items.findIndex(item => item.dataset.field === fieldKey); + if (index <= 0) return; + const item = items[index]; const prevItem = items[index - 1]; orderList.insertBefore(item, prevItem); @@ -249,10 +253,12 @@ function moveFieldUp(index) { } // 字段下移 -function moveFieldDown(index) { +function moveFieldDown(fieldKey) { const orderList = document.getElementById('selected-fields-order'); const items = Array.from(orderList.querySelectorAll('.selected-field-item')); - if (index >= items.length - 1) return; + const index = items.findIndex(item => item.dataset.field === fieldKey); + if (index < 0 || index >= items.length - 1) return; + const item = items[index]; const nextItem = items[index + 1]; orderList.insertBefore(nextItem, item); @@ -297,7 +303,7 @@ function refreshSumFieldsList(selectedFields, currentSumFields) {
- +
`).join(''); } @@ -465,14 +471,43 @@ async function saveConfig() { // 处理多选:从 selectedEntityIds 获取选中的实体 const splitValue = Array.from(selectedEntityIds).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(','); + // 通过 API 查询所有已选实体的名称(确保翻页后也能正确获取) + let splitName = ''; + if (selectedEntityIds.size > 0) { + const entityType = splitType === 'company_id' ? 'company' : + splitType === 'user_id' ? 'user' : 'station'; + try { + const response = await fetch('/api/entities/by_ids', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ type: entityType, ids: Array.from(selectedEntityIds) }) + }); + const result = await response.json(); + if (result.success && result.data) { + const idSet = new Set(Array.from(selectedEntityIds)); + const sortedEntities = result.data.filter(e => { + const value = splitType === 'company_id' ? e.company_id : + splitType === 'user_id' ? e.user_id : e.station_id; + return idSet.has(String(value)); + }).sort((a, b) => { + const aVal = splitType === 'company_id' ? a.company_id : + splitType === 'user_id' ? a.user_id : a.station_id; + const bVal = splitType === 'company_id' ? b.company_id : + splitType === 'user_id' ? b.user_id : b.station_id; + const aIdx = Array.from(selectedEntityIds).indexOf(String(aVal)); + const bIdx = Array.from(selectedEntityIds).indexOf(String(bVal)); + return aIdx - bIdx; + }); + splitName = sortedEntities.map(e => { + if (splitType === 'company_id') return e.company_name; + if (splitType === 'user_id') return e.user_name; + return e.station_name; + }).join(','); + } + } catch (err) { + console.error('获取实体名称失败:', err); + } + } // 获取字段顺序(从已选字段顺序列表获取) const selectedFields = getSelectedFieldsOrder(); @@ -747,8 +782,9 @@ async function loadEntitiesForEdit(splitType, selectedValues) { container.innerHTML = mergedEntities.map(item => { const isChecked = item.isSelected ? 'checked' : ''; const checkedClass = item.isSelected ? 'checked' : ''; + const topClass = item.isSelected ? 'entity-selected-top' : ''; return ` -
+
${item.name} ${item.typeLabel}
@@ -882,6 +918,7 @@ async function moveConfig(configId, direction) { // 关闭模态框 function closeModal() { document.getElementById('config-modal').classList.remove('active'); + selectedEntityIds.clear(); } @@ -902,16 +939,6 @@ function setDefaultTimePeriods() { updateTimePeriodSummary(); } -// 拆分方式改变时加载实体列表 -function onSplitTypeChange() { - const splitType = document.getElementById('split-type').value; - if (splitType) { - loadEntities(1, ''); - } else { - document.getElementById('entity-list').innerHTML = '
请先选择拆分方式
'; - } -} - // 导出配置 function exportConfigs() { try { diff --git a/public/static/js/entity.js b/public/static/js/entity.js index 197a497..ceec7fc 100644 --- a/public/static/js/entity.js +++ b/public/static/js/entity.js @@ -42,7 +42,9 @@ async function loadEntities(page = 1, search = '') { if (entities.length === 0) { container.innerHTML = '
无数据
'; } else { - container.innerHTML = entities.map(e => { + const selected = []; + const unselected = []; + entities.forEach(e => { let value = ''; let name = ''; let typeLabel = ''; @@ -62,11 +64,23 @@ async function loadEntities(page = 1, search = '') { name = e.station_name; } - const isChecked = selectedEntityIds.has(String(value)) ? 'checked' : ''; + const item = { value, name, typeLabel }; + if (selectedEntityIds.has(String(value))) { + selected.push(item); + } else { + unselected.push(item); + } + }); + + const sortedEntities = [...selected, ...unselected]; + + container.innerHTML = sortedEntities.map(e => { + const isChecked = selectedEntityIds.has(String(e.value)) ? 'checked' : ''; + const isSelectedTop = selectedEntityIds.has(String(e.value)); return ` -
- - ${name} ${typeLabel} +
+ + ${e.name} ${e.typeLabel}
`; }).join(''); @@ -89,15 +103,45 @@ function toggleEntityCheckbox(item, value) { if (checkbox.checked) { item.classList.add('checked'); + item.classList.add('entity-selected-top'); selectedEntityIds.add(String(value)); } else { item.classList.remove('checked'); + item.classList.remove('entity-selected-top'); selectedEntityIds.delete(String(value)); } updateSelectedCount(); } +// 重新排序列表(已选的在前面) +function reorderEntityList() { + const container = document.getElementById('entity-list'); + const items = Array.from(container.querySelectorAll('.checkbox-item')); + if (items.length === 0) return; + + const selected = []; + const unselected = []; + + items.forEach(item => { + const checkbox = item.querySelector('input[type="checkbox"]'); + if (checkbox.checked) { + selected.push(item); + item.classList.add('entity-selected-top'); + } else { + unselected.push(item); + item.classList.remove('entity-selected-top'); + } + }); + + // 用文档片段移动,避免 innerHTML 清空导致状态丢失 + const fragment = document.createDocumentFragment(); + [...selected, ...unselected].forEach(item => { + fragment.appendChild(item); + }); + container.appendChild(fragment); +} + // 更新已选数量显示 function updateSelectedCount() { const countSpan = document.getElementById('selected-count'); @@ -125,6 +169,7 @@ function toggleSelectAllEntities() { }); updateSelectedCount(); + reorderEntityList(); } // 更新实体分页UI diff --git a/templates/index.html b/templates/index.html index abf0552..b6a5288 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,7 +4,7 @@ 订单日报系统 - +
@@ -350,11 +350,11 @@
- - - - - - + + + + + +