fix(template): 修复区域生成编号和画布点击交互问题
修复批量生成区域时编号未考虑现有区域的问题,现在会基于现有最大编号递增。 修复画布点击交互:支持点击空白处取消选中,并优化多选切换为单选的逻辑。
This commit is contained in:
@ -62,11 +62,23 @@ function handleGenerate() {
|
||||
const groupId = crypto.randomUUID()
|
||||
const newRegions: Region[] = []
|
||||
|
||||
// 计算起始编号:查找现有的最大 Qx 编号
|
||||
let maxNum = 0
|
||||
regions.value.forEach((r) => {
|
||||
const match = r.label.match(/^Q(\d+)$/)
|
||||
if (match) {
|
||||
const n = Number.parseInt(match[1], 10)
|
||||
if (!Number.isNaN(n) && n > maxNum) {
|
||||
maxNum = n
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const currentX = genSettings.value.startX
|
||||
const currentY = genSettings.value.startY
|
||||
|
||||
for (let r = 0; r < genSettings.value.rows; r++) {
|
||||
for (let c = 0; c < genSettings.value.cols; c++) {
|
||||
const index = maxNum + r * genSettings.value.cols + c + 1 // 计算当前区域的编号
|
||||
newRegions.push({
|
||||
id: crypto.randomUUID(),
|
||||
groupId,
|
||||
@ -74,7 +86,7 @@ function handleGenerate() {
|
||||
y: currentY + r * (genSettings.value.h + genSettings.value.gapY),
|
||||
w: genSettings.value.w,
|
||||
h: genSettings.value.h,
|
||||
label: `Q${newRegions.length + 1}`, // Placeholder label
|
||||
label: `Q${index}`, // 题目编号递增
|
||||
selected: false,
|
||||
})
|
||||
}
|
||||
@ -121,6 +133,7 @@ async function handleSave() {
|
||||
height: Math.round(templateInfo.value.height),
|
||||
tempContent: JSON.stringify(regions.value),
|
||||
}
|
||||
console.log(params, 'params')
|
||||
|
||||
const { error } = await fetchAddTemplate(params)
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ watch(() => props.imgSrc, () => {
|
||||
|
||||
// 拖拽初始状态记录
|
||||
const dragStartPositions = ref<Map<string, { x: number, y: number }>>(new Map())
|
||||
const mouseDownPos = ref<{ x: number, y: number } | null>(null)
|
||||
|
||||
// --- 拖拽与调整大小逻辑 ---
|
||||
|
||||
@ -52,6 +53,9 @@ const dragStartPositions = ref<Map<string, { x: number, y: number }>>(new Map())
|
||||
* 支持多选:按住 Shift/Ctrl/Meta 键
|
||||
*/
|
||||
function onRegionMouseDown(region: Region, e: MouseEvent) {
|
||||
// e.stopPropagation() // 移除阻止冒泡,以便 vue-draggable-resizable 能接收到事件并启动拖拽
|
||||
mouseDownPos.value = { x: e.clientX, y: e.clientY }
|
||||
|
||||
const isModifierDown = e.shiftKey || e.ctrlKey || e.metaKey
|
||||
const isSelected = props.selectedRegionIds.has(region.id)
|
||||
|
||||
@ -77,6 +81,46 @@ function onRegionMouseDown(region: Region, e: MouseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理区域鼠标松开
|
||||
* 用于在未拖拽的情况下,从多选切换为单选
|
||||
*/
|
||||
function onRegionMouseUp(region: Region, e: MouseEvent) {
|
||||
if (!mouseDownPos.value)
|
||||
return
|
||||
|
||||
const dx = Math.abs(e.clientX - mouseDownPos.value.x)
|
||||
const dy = Math.abs(e.clientY - mouseDownPos.value.y)
|
||||
const isClick = dx < 3 && dy < 3
|
||||
const isModifierDown = e.shiftKey || e.ctrlKey || e.metaKey
|
||||
|
||||
// 如果是单纯点击,且没有按修饰键,且已经选中(在 onRegionMouseDown 中处理了未选中的情况)
|
||||
// 那么将多选变为单选
|
||||
if (isClick && !isModifierDown && props.selectedRegionIds.has(region.id)) {
|
||||
// 如果当前选中的数量大于 1,则切换为单选当前这个
|
||||
if (props.selectedRegionIds.size > 1) {
|
||||
emit('update:selectedRegionIds', new Set([region.id]))
|
||||
}
|
||||
}
|
||||
|
||||
mouseDownPos.value = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击画布空白处取消选中
|
||||
*/
|
||||
function onCanvasMouseDown(e: MouseEvent) {
|
||||
// 检查点击目标是否是区域相关元素
|
||||
const target = e.target as HTMLElement
|
||||
// 如果点击的是区域(.region-box, .region-content, .vdr-container 等),则忽略
|
||||
if (target.closest('.region-box') || target.closest('.region-content') || target.closest('.vdr-container') || target.closest('.vdr-handle')) {
|
||||
return
|
||||
}
|
||||
|
||||
// 只有点击真正的空白处才取消选中
|
||||
emit('update:selectedRegionIds', new Set())
|
||||
}
|
||||
|
||||
// 移除 onActivated 的选中逻辑,完全由 onRegionMouseDown 接管
|
||||
function onActivated(_id: string) {
|
||||
// 空实现,避免覆盖多选逻辑
|
||||
@ -272,6 +316,7 @@ onUnmounted(() => {
|
||||
width: `${templateInfo.width}px`,
|
||||
height: `${templateInfo.height}px`,
|
||||
}"
|
||||
@mousedown="onCanvasMouseDown"
|
||||
>
|
||||
<!-- 背景图片 -->
|
||||
<img
|
||||
@ -307,6 +352,7 @@ onUnmounted(() => {
|
||||
class="region-content group relative h-full w-full flex items-center justify-center transition-transform"
|
||||
:style="{ transform: `rotate(${region.rotation || 0}deg)` }"
|
||||
@mousedown="onRegionMouseDown(region, $event)"
|
||||
@mouseup="onRegionMouseUp(region, $event)"
|
||||
>
|
||||
<!-- 视觉边框 (旋转) -->
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user