merge: fix/country-mode-good-reorder-dev into develop (local only, not pushed)
This commit is contained in:
@@ -675,6 +675,78 @@ async function onLeftTreeDragEnd(dragNode: any, dropNode: any, position: string)
|
|||||||
} catch { ElMessage.error('调整失败'); await reloadCategories() }
|
} catch { ElMessage.error('调整失败'); await reloadCategories() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── 国家模式:商品在国家分组内拖拽排序(保序重排优先级) ───
|
||||||
|
const treeDragGoodId = ref<string | null>(null)
|
||||||
|
const treeDragOver = ref<{ id: string; pos: 'before' | 'after' } | null>(null)
|
||||||
|
|
||||||
|
function onTreeGoodDragStart(event: DragEvent, data: any) {
|
||||||
|
if (mode.value !== 'country') return
|
||||||
|
treeDragGoodId.value = data.goodId
|
||||||
|
if (event.dataTransfer) {
|
||||||
|
event.dataTransfer.effectAllowed = 'move'
|
||||||
|
event.dataTransfer.setData('text/plain', String(data.goodId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTreeGoodDragOver(event: DragEvent, data: any) {
|
||||||
|
if (mode.value !== 'country' || !treeDragGoodId.value || treeDragGoodId.value === data.goodId) return
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()
|
||||||
|
treeDragOver.value = {
|
||||||
|
id: data.goodId,
|
||||||
|
pos: event.clientY < rect.top + rect.height / 2 ? 'before' : 'after',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTreeGoodDragLeave(_event: DragEvent, data: any) {
|
||||||
|
if (treeDragOver.value?.id === data.goodId) treeDragOver.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onTreeGoodDrop(event: DragEvent, data: any) {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
const draggedId = treeDragGoodId.value
|
||||||
|
const target = treeDragOver.value
|
||||||
|
treeDragGoodId.value = null
|
||||||
|
treeDragOver.value = null
|
||||||
|
if (mode.value !== 'country' || !draggedId || !target) return
|
||||||
|
if (target.id !== data.goodId || draggedId === data.goodId) return
|
||||||
|
|
||||||
|
// 目标所在国家分组的商品(新顺序)
|
||||||
|
const group = leftTreeData.value.find((c: any) =>
|
||||||
|
(c.children ?? []).some((g: any) => g.goodId === target.id),
|
||||||
|
)
|
||||||
|
if (!group) return
|
||||||
|
const nodes = [...group.children]
|
||||||
|
const fromIdx = nodes.findIndex(n => n.goodId === draggedId)
|
||||||
|
if (fromIdx === -1) return // 跨国拖动不支持(商品归属固定国家)
|
||||||
|
const [moved] = nodes.splice(fromIdx, 1)
|
||||||
|
let insertIdx = nodes.findIndex(n => n.goodId === target.id)
|
||||||
|
if (target.pos === 'after') insertIdx++
|
||||||
|
nodes.splice(insertIdx, 0, moved)
|
||||||
|
|
||||||
|
// 保序重排:该国家现有优先级集合不变,按新顺序重新分配(尽量少扰动全局/品类排序)
|
||||||
|
const priorities = nodes.map(n => Number(n.priority || 0)).sort((a, b) => b - a)
|
||||||
|
moveTopLoading.value = 'drag'
|
||||||
|
try {
|
||||||
|
await goodsApi.batchUpdatePriority({
|
||||||
|
items: nodes.map((n, i) => ({ id: Number(n.goodId), priority: priorities[i] ?? 0 })),
|
||||||
|
})
|
||||||
|
ElMessage.success('排序已保存')
|
||||||
|
await refreshLeftTree()
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('排序失败')
|
||||||
|
} finally {
|
||||||
|
moveTopLoading.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTreeGoodDragEnd() {
|
||||||
|
treeDragGoodId.value = null
|
||||||
|
treeDragOver.value = null
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Country CRUD ───
|
// ─── Country CRUD ───
|
||||||
const countryEditVisible = ref(false)
|
const countryEditVisible = ref(false)
|
||||||
const countryEditMode = ref<'create' | 'edit'>('create')
|
const countryEditMode = ref<'create' | 'edit'>('create')
|
||||||
@@ -978,8 +1050,20 @@ onMounted(() => loadAll())
|
|||||||
<div
|
<div
|
||||||
v-else-if="data.isGood"
|
v-else-if="data.isGood"
|
||||||
class="good-node"
|
class="good-node"
|
||||||
:class="{ 'good-node--flash': data.goodId === locateFlashGoodId }"
|
:class="{
|
||||||
|
'good-node--flash': data.goodId === locateFlashGoodId,
|
||||||
|
'is-dragging': mode === 'country' && treeDragGoodId === data.goodId,
|
||||||
|
'is-drop-before': mode === 'country' && treeDragOver?.id === data.goodId && treeDragOver?.pos === 'before',
|
||||||
|
'is-drop-after': mode === 'country' && treeDragOver?.id === data.goodId && treeDragOver?.pos === 'after',
|
||||||
|
}"
|
||||||
|
:draggable="mode === 'country'"
|
||||||
|
title="拖拽调整在国家内的排序"
|
||||||
@click="openEdit(data.raw)"
|
@click="openEdit(data.raw)"
|
||||||
|
@dragstart="onTreeGoodDragStart($event, data)"
|
||||||
|
@dragover="onTreeGoodDragOver($event, data)"
|
||||||
|
@dragleave="onTreeGoodDragLeave($event, data)"
|
||||||
|
@drop="onTreeGoodDrop($event, data)"
|
||||||
|
@dragend="onTreeGoodDragEnd"
|
||||||
>
|
>
|
||||||
<el-image v-if="data.goodImage" :src="data.goodImage" fit="cover" class="good-thumb" />
|
<el-image v-if="data.goodImage" :src="data.goodImage" fit="cover" class="good-thumb" />
|
||||||
<div v-else class="good-thumb-placeholder" />
|
<div v-else class="good-thumb-placeholder" />
|
||||||
@@ -1403,6 +1487,9 @@ onMounted(() => loadAll())
|
|||||||
transition: background 0.12s;
|
transition: background 0.12s;
|
||||||
}
|
}
|
||||||
.good-node:hover { background: #f0f2f5; }
|
.good-node:hover { background: #f0f2f5; }
|
||||||
|
.good-node.is-dragging { opacity: 0.5; }
|
||||||
|
.good-node.is-drop-before { box-shadow: inset 0 2px 0 var(--el-color-primary); }
|
||||||
|
.good-node.is-drop-after { box-shadow: inset 0 -2px 0 var(--el-color-primary); }
|
||||||
.good-thumb {
|
.good-thumb {
|
||||||
width: 36px; height: 36px; border-radius: 6px; flex-shrink: 0;
|
width: 36px; height: 36px; border-radius: 6px; flex-shrink: 0;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
|||||||
Reference in New Issue
Block a user