From d19700738e78c8a7cc5313f401db9c7dddfa2ae3 Mon Sep 17 00:00:00 2001 From: X1627315083 <1627315083@qq.com> Date: Wed, 19 Nov 2025 09:35:58 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddetail=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=A1=A3=E6=9C=8D=E7=94=BB=E5=B8=83=E6=B2=A1=E6=9C=89=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Detail/model/modelNav.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/component/Detail/model/modelNav.vue b/src/component/Detail/model/modelNav.vue index c00d4554..0b94e180 100644 --- a/src/component/Detail/model/modelNav.vue +++ b/src/component/Detail/model/modelNav.vue @@ -108,7 +108,6 @@ export default defineComponent({ detailData.designDetail.clothes = detailData.designDetail.clothes.filter((item:any)=>item.id != id) detailData.frontBack_.back = detailData.frontBack_.back.filter((item:any)=>item.id != id) detailData.frontBack_.front = detailData.frontBack_.front.filter((item:any)=>item.id != id) - console.log(detailData.designDetail.clothes) //判断删除后是否还有服装 if(detailData.designDetail.clothes.length == 0){ addSketch() @@ -118,7 +117,7 @@ export default defineComponent({ const maxObj = detailData.designDetail.clothes.find(item => item.priority === maxValue); store.commit('DesignDetail/setDesignColthes',maxObj.id) } - + emit('canvasReload') emit('deleteItem') } const addSketch = ()=>{ From 2c9c73b1d922159c0af3e9b434a58bfa6de2b5dd Mon Sep 17 00:00:00 2001 From: X1627315083 <1627315083@qq.com> Date: Wed, 19 Nov 2025 09:51:00 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E8=AF=8D=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/tools/poseTransfer/promptInput.vue | 147 ++++++++++++++++-- 1 file changed, 131 insertions(+), 16 deletions(-) diff --git a/src/component/home/tools/poseTransfer/promptInput.vue b/src/component/home/tools/poseTransfer/promptInput.vue index e8e188c9..5e798c9c 100644 --- a/src/component/home/tools/poseTransfer/promptInput.vue +++ b/src/component/home/tools/poseTransfer/promptInput.vue @@ -16,13 +16,13 @@ const props = defineProps({ }) const data = reactive({ - // content: [ - // { id: '1', type: 'text', value: '11111' }, - // { id: '2', type: 'input', value: '222', placeholder: '[请输入内容]' }, - // { id: '3', type: 'text', value: '333333' }, - // { id: '4', type: 'input', value: '', placeholder: '[请输入内容]' } - // ] as ContentItem[] - content: props.content + // content: [ + // { id: '1', type: 'text', value: '11111' }, + // { id: '2', type: 'input', value: '222', placeholder: '[请输入内容]' }, + // { id: '3', type: 'text', value: '333333' }, + // { id: '4', type: 'input', value: '', placeholder: '[请输入内容]' } + // ] as ContentItem[] + content: props.content }) const editableArea = ref() @@ -32,6 +32,12 @@ const cursorState = ref({ isContainerClick: false }) +// 添加中文输入状态管理 +const compositionState = reactive({ + isComposing: false, + currentInputIndex: -1 +}) + // 检查并删除末尾的空文本框 const removeLastEmptyTextIfNeeded = () => { const lastItem = content.value[content.value.length - 1] @@ -266,12 +272,30 @@ const updateInputDisplay = (index: number) => { } } -// 输入框内容变化处理 const handleInputChange = (index: number, event: Event) => { + // 如果是中文输入过程中,不处理 + if (compositionState.isComposing && compositionState.currentInputIndex === index) { + return + } + const target = event.target as HTMLSpanElement const item = content.value[index] - // 如果当前显示placeholder,不更新实际值 + // 如果当前显示placeholder,但内容已改变(比如通过粘贴),清除placeholder + if (target.classList.contains('has-placeholder') && target.textContent !== item.placeholder) { + target.classList.remove('has-placeholder') + const newValue = target.textContent || '' + content.value[index].value = newValue + + // 如果粘贴后内容为空,重新显示 placeholder + if (newValue.trim() === '' && item.placeholder) { + target.classList.add('has-placeholder') + target.textContent = item.placeholder + } + return + } + + // 正常情况下的处理 if (!target.classList.contains('has-placeholder')) { const newValue = target.textContent || '' content.value[index].value = newValue @@ -284,7 +308,33 @@ const handleInputChange = (index: number, event: Event) => { } } -// 输入框键盘事件 +// 添加专门的粘贴事件处理 +const handleInputPaste = (event: ClipboardEvent, index: number) => { + const target = event.target as HTMLSpanElement + const item = content.value[index] + + // 如果当前显示 placeholder,先清除它 + if (target.classList.contains('has-placeholder')) { + event.preventDefault() + target.classList.remove('has-placeholder') + target.textContent = '' + + // 获取粘贴的内容 + const pasteData = event.clipboardData?.getData('text') || '' + document.execCommand('insertText', false, pasteData) + + // 更新值 + const newValue = target.textContent || '' + content.value[index].value = newValue + + // 如果粘贴后内容为空,重新显示 placeholder + if (newValue.trim() === '' && item.placeholder) { + target.classList.add('has-placeholder') + target.textContent = item.placeholder + } + } +} + const handleInputKeydown = (event: KeyboardEvent, index: number) => { const target = event.target as HTMLSpanElement @@ -320,9 +370,76 @@ const handleInputKeydown = (event: KeyboardEvent, index: number) => { }) } } + // 添加对 Ctrl+V 的处理 + else if ((event.ctrlKey || event.metaKey) && event.key === 'v') { + // 延迟处理,等待粘贴内容实际插入 + setTimeout(() => { + handlePasteInInput(index, target) + }, 0) + } +} + +const handlePasteInInput = (index: number, element: HTMLElement) => { + const item = content.value[index] + + // 如果当前显示 placeholder,清除它 + if (element.classList.contains('has-placeholder')) { + element.classList.remove('has-placeholder') + // 获取粘贴后的实际内容 + const newValue = element.textContent || '' + content.value[index].value = newValue + + // 如果粘贴后内容为空,重新显示 placeholder + if (newValue.trim() === '' && item.placeholder) { + element.classList.add('has-placeholder') + element.textContent = item.placeholder + } + } else { + // 正常情况,直接更新值 + const newValue = element.textContent || '' + content.value[index].value = newValue + + // 检查是否需要显示 placeholder + if (newValue.trim() === '' && item.placeholder) { + element.classList.add('has-placeholder') + element.textContent = item.placeholder + } + } +} + +// 添加中文输入事件处理 +const handleCompositionStart = (index: number, event: CompositionEvent) => { + compositionState.isComposing = true + compositionState.currentInputIndex = index + + const target = event.target as HTMLSpanElement + // 如果是placeholder状态,开始中文输入时清除placeholder + if (target.classList.contains('has-placeholder')) { + target.classList.remove('has-placeholder') + target.textContent = '' + content.value[index].value = '' + } +} + +const handleCompositionEnd = (index: number, event: CompositionEvent) => { + compositionState.isComposing = false + compositionState.currentInputIndex = -1 + + const target = event.target as HTMLSpanElement + const newValue = target.textContent || '' + content.value[index].value = newValue + + // 如果中文输入后内容为空,显示placeholder + const item = content.value[index] + if (newValue.trim() === '' && item.placeholder) { + target.classList.add('has-placeholder') + target.textContent = item.placeholder + } } const handleInputBlur = (index: number) => { + compositionState.isComposing = false + compositionState.currentInputIndex = -1 updateInputDisplay(index) } @@ -433,6 +550,9 @@ defineExpose({ @input="e => handleInputChange(index, e)" @keydown="e => handleInputKeydown(e, index)" @blur="() => handleInputBlur(index)" + @paste="e => handleInputPaste(e, index)" + @compositionstart="e => handleCompositionStart(index, e)" + @compositionend="e => handleCompositionEnd(index, e)" > @@ -478,13 +598,10 @@ defineExpose({ font-size: 1.8rem; min-width: 2px; font-weight: 400; - /* 确保空文本框也能点击 */ } .input-field { display: inline-block; - // background: #e3f2fd; - // border: 1px solid #bbdefb; margin: 0 0.2rem; padding: 0.2rem 1rem; font-size: 1.8rem; @@ -497,7 +614,6 @@ defineExpose({ &.has-placeholder { color: #b9b9b9; - // font-style: italic; } } } @@ -547,7 +663,6 @@ defineExpose({ font-size: 1rem; margin-right: 0; width: initial; - // margin-top: -0.2rem; } } - + \ No newline at end of file From 4dcf4b1eb28cd94304bbcba077680bdf56eedc38 Mon Sep 17 00:00:00 2001 From: X1627315083 <1627315083@qq.com> Date: Wed, 19 Nov 2025 10:17:18 +0800 Subject: [PATCH 3/3] fix --- .../home/tools/poseTransfer/promptInput.vue | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/component/home/tools/poseTransfer/promptInput.vue b/src/component/home/tools/poseTransfer/promptInput.vue index 5e798c9c..e5ca1e8c 100644 --- a/src/component/home/tools/poseTransfer/promptInput.vue +++ b/src/component/home/tools/poseTransfer/promptInput.vue @@ -22,7 +22,7 @@ const data = reactive({ // { id: '3', type: 'text', value: '333333' }, // { id: '4', type: 'input', value: '', placeholder: '[请输入内容]' } // ] as ContentItem[] - content: props.content + content: [ { id: '1', type: 'text', value: '' },], }) const editableArea = ref() @@ -40,9 +40,9 @@ const compositionState = reactive({ // 检查并删除末尾的空文本框 const removeLastEmptyTextIfNeeded = () => { - const lastItem = content.value[content.value.length - 1] + const lastItem = data.content[data.content.length - 1] if (lastItem && lastItem.type === 'text' && lastItem.value === '') { - content.value.pop() + data.content.pop() return true } return false @@ -50,14 +50,14 @@ const removeLastEmptyTextIfNeeded = () => { // 确保末尾有空文本框 const ensureEmptyTextAtEnd = () => { - const lastItem = content.value[content.value.length - 1] + const lastItem = data.content[data.content.length - 1] if (!lastItem || lastItem.type !== 'text' || lastItem.value !== '') { const newItem: ContentItem = { id: Date.now().toString(), type: 'text', value: '' } - content.value.push(newItem) + data.content.push(newItem) return true } return false @@ -96,7 +96,7 @@ const getCurrentElementInfo = () => { index = parseInt(parent?.getAttribute('data-index') || '-1') type = 'input' - const item = content.value[index] + const item = data.content[index] if (element.classList.contains('has-placeholder')) { // placeholder状态下,光标在任意位置都认为是"在元素内" isAtStart = range.startOffset === 0 @@ -172,10 +172,10 @@ const handleKeydown = (event: KeyboardEvent) => { break case 'ArrowRight': - if (isAtEnd && index < content.value.length - 1) { + if (isAtEnd && index < data.content.length - 1) { event.preventDefault() navigateToElement(index + 1, 'start') - } else if (isAtEnd && index === content.value.length - 1) { + } else if (isAtEnd && index === data.content.length - 1) { // 在最后一个元素末尾按右箭头,确保有一个空文本框 ensureEmptyTextAtEnd() nextTick(() => { @@ -189,26 +189,26 @@ const handleKeydown = (event: KeyboardEvent) => { // 跨元素删除逻辑 const handleCrossElementDelete = (currentIndex: number) => { const prevIndex = currentIndex - 1 - const prevItem = content.value[prevIndex] + const prevItem = data.content[prevIndex] if (prevItem.type === 'input') { if (prevItem.value.trim() === '') { // 删除空输入框 - content.value.splice(prevIndex, 1) + data.content.splice(prevIndex, 1) nextTick(() => { // 删除输入框后,先删除末尾的空文本框 removeLastEmptyTextIfNeeded() // 然后聚焦到正确的位置 - if (prevIndex < content.value.length) { + if (prevIndex < data.content.length) { focusElement(prevIndex, 'end') - } else if (content.value.length > 0) { - focusElement(content.value.length - 1, 'end') + } else if (data.content.length > 0) { + focusElement(data.content.length - 1, 'end') } }) } else { // 删除输入框最后一个字符,但保留输入框 const newValue = prevItem.value.slice(0, -1) - content.value[prevIndex].value = newValue + data.content[prevIndex].value = newValue updateInputDisplay(prevIndex) nextTick(() => focusElement(prevIndex, 'end')) } @@ -222,7 +222,7 @@ const handleCrossElementDelete = (currentIndex: number) => { // 导航到元素 const navigateToElement = (targetIndex: number, position: 'start' | 'end') => { - const targetItem = content.value[targetIndex] + const targetItem = data.content[targetIndex] const element = targetItem.type === 'text' ? (editableArea.value?.querySelector( @@ -237,7 +237,7 @@ const navigateToElement = (targetIndex: number, position: 'start' | 'end') => { // 焦点设置 const focusElement = (index: number, position: 'start' | 'end') => { - const item = content.value[index] + const item = data.content[index] const element = item.type === 'text' ? (editableArea.value?.querySelector( @@ -252,7 +252,7 @@ const focusElement = (index: number, position: 'start' | 'end') => { // 输入框显示管理 const updateInputDisplay = (index: number) => { - const item = content.value[index] + const item = data.content[index] if (item.type !== 'input') return const inputElement = editableArea.value?.querySelector( @@ -279,13 +279,13 @@ const handleInputChange = (index: number, event: Event) => { } const target = event.target as HTMLSpanElement - const item = content.value[index] + const item = data.content[index] // 如果当前显示placeholder,但内容已改变(比如通过粘贴),清除placeholder if (target.classList.contains('has-placeholder') && target.textContent !== item.placeholder) { target.classList.remove('has-placeholder') const newValue = target.textContent || '' - content.value[index].value = newValue + data.content[index].value = newValue // 如果粘贴后内容为空,重新显示 placeholder if (newValue.trim() === '' && item.placeholder) { @@ -298,7 +298,7 @@ const handleInputChange = (index: number, event: Event) => { // 正常情况下的处理 if (!target.classList.contains('has-placeholder')) { const newValue = target.textContent || '' - content.value[index].value = newValue + data.content[index].value = newValue // 如果内容变空,显示placeholder if (newValue.trim() === '' && item.placeholder) { @@ -311,7 +311,7 @@ const handleInputChange = (index: number, event: Event) => { // 添加专门的粘贴事件处理 const handleInputPaste = (event: ClipboardEvent, index: number) => { const target = event.target as HTMLSpanElement - const item = content.value[index] + const item = data.content[index] // 如果当前显示 placeholder,先清除它 if (target.classList.contains('has-placeholder')) { @@ -325,7 +325,7 @@ const handleInputPaste = (event: ClipboardEvent, index: number) => { // 更新值 const newValue = target.textContent || '' - content.value[index].value = newValue + data.content[index].value = newValue // 如果粘贴后内容为空,重新显示 placeholder if (newValue.trim() === '' && item.placeholder) { @@ -362,7 +362,7 @@ const handleInputKeydown = (event: KeyboardEvent, index: number) => { event.preventDefault() target.textContent = event.key target.classList.remove('has-placeholder') - content.value[index].value = event.key + data.content[index].value = event.key // 移动光标到末尾 nextTick(() => { @@ -380,14 +380,14 @@ const handleInputKeydown = (event: KeyboardEvent, index: number) => { } const handlePasteInInput = (index: number, element: HTMLElement) => { - const item = content.value[index] + const item = data.content[index] // 如果当前显示 placeholder,清除它 if (element.classList.contains('has-placeholder')) { element.classList.remove('has-placeholder') // 获取粘贴后的实际内容 const newValue = element.textContent || '' - content.value[index].value = newValue + data.content[index].value = newValue // 如果粘贴后内容为空,重新显示 placeholder if (newValue.trim() === '' && item.placeholder) { @@ -397,7 +397,7 @@ const handlePasteInInput = (index: number, element: HTMLElement) => { } else { // 正常情况,直接更新值 const newValue = element.textContent || '' - content.value[index].value = newValue + data.content[index].value = newValue // 检查是否需要显示 placeholder if (newValue.trim() === '' && item.placeholder) { @@ -417,7 +417,7 @@ const handleCompositionStart = (index: number, event: CompositionEvent) => { if (target.classList.contains('has-placeholder')) { target.classList.remove('has-placeholder') target.textContent = '' - content.value[index].value = '' + data.content[index].value = '' } } @@ -427,10 +427,10 @@ const handleCompositionEnd = (index: number, event: CompositionEvent) => { const target = event.target as HTMLSpanElement const newValue = target.textContent || '' - content.value[index].value = newValue + data.content[index].value = newValue // 如果中文输入后内容为空,显示placeholder - const item = content.value[index] + const item = data.content[index] if (newValue.trim() === '' && item.placeholder) { target.classList.add('has-placeholder') target.textContent = item.placeholder @@ -454,7 +454,7 @@ const handleContainerClick = (event: MouseEvent) => { // 确保末尾有空文本框并聚焦到它 ensureEmptyTextAtEnd() nextTick(() => { - focusElement(content.value.length - 1, 'start') + focusElement(data.content.length - 1, 'start') }) } } @@ -462,7 +462,7 @@ const handleContainerClick = (event: MouseEvent) => { // 初始化 const initPlaceholders = () => { nextTick(() => { - content.value.forEach((_, index) => updateInputDisplay(index)) + data.content.forEach((_, index) => updateInputDisplay(index)) // 确保初始状态下有一个空文本框 ensureEmptyTextAtEnd() }) @@ -470,7 +470,7 @@ const initPlaceholders = () => { const getFullText = () => { if (assistModel.value) { - return content.value + return data.content .map(item => { if (item.type === 'text') { return item.value @@ -498,12 +498,15 @@ const textareaValue = ref('') const assistModel = ref(false) const handleClickAssistBtn = () => { assistModel.value = !assistModel.value + if(assistModel.value){ + data.content = JSON.parse(JSON.stringify(props.content)) + initPlaceholders() + } } const textareaRef = useTemplateRef('textareaRef') onMounted(() => { - initPlaceholders() }) defineExpose({ @@ -533,7 +536,7 @@ defineExpose({ @click="handleContainerClick" >
-