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 = ()=>{ diff --git a/src/component/home/tools/poseTransfer/promptInput.vue b/src/component/home/tools/poseTransfer/promptInput.vue index c38b7c8c..5de45ff0 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: [ { id: '1', type: 'text', value: '' },], }) const editableArea = ref() @@ -32,11 +32,17 @@ const cursorState = ref({ isContainerClick: false }) +// 添加中文输入状态管理 +const compositionState = reactive({ + isComposing: false, + currentInputIndex: -1 +}) + // 检查并删除末尾的空文本框 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 @@ -44,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 @@ -90,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 @@ -166,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(() => { @@ -183,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')) } @@ -216,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( @@ -231,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( @@ -246,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( @@ -266,15 +272,33 @@ const updateInputDisplay = (index: number) => { } } -// 输入框内容变化处理 const handleInputChange = (index: number, event: Event) => { - const target = event.target as HTMLSpanElement - const item = content.value[index] + // 如果是中文输入过程中,不处理 + if (compositionState.isComposing && compositionState.currentInputIndex === index) { + return + } - // 如果当前显示placeholder,不更新实际值 + const target = event.target as HTMLSpanElement + 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 || '' + data.content[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 + data.content[index].value = newValue // 如果内容变空,显示placeholder if (newValue.trim() === '' && item.placeholder) { @@ -284,7 +308,33 @@ const handleInputChange = (index: number, event: Event) => { } } -// 输入框键盘事件 +// 添加专门的粘贴事件处理 +const handleInputPaste = (event: ClipboardEvent, index: number) => { + const target = event.target as HTMLSpanElement + const item = data.content[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 || '' + data.content[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 @@ -312,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(() => { @@ -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 = data.content[index] + + // 如果当前显示 placeholder,清除它 + if (element.classList.contains('has-placeholder')) { + element.classList.remove('has-placeholder') + // 获取粘贴后的实际内容 + const newValue = element.textContent || '' + data.content[index].value = newValue + + // 如果粘贴后内容为空,重新显示 placeholder + if (newValue.trim() === '' && item.placeholder) { + element.classList.add('has-placeholder') + element.textContent = item.placeholder + } + } else { + // 正常情况,直接更新值 + const newValue = element.textContent || '' + data.content[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 = '' + data.content[index].value = '' + } +} + +const handleCompositionEnd = (index: number, event: CompositionEvent) => { + compositionState.isComposing = false + compositionState.currentInputIndex = -1 + + const target = event.target as HTMLSpanElement + const newValue = target.textContent || '' + data.content[index].value = newValue + + // 如果中文输入后内容为空,显示placeholder + const item = data.content[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) } @@ -337,7 +454,7 @@ const handleContainerClick = (event: MouseEvent) => { // 确保末尾有空文本框并聚焦到它 ensureEmptyTextAtEnd() nextTick(() => { - focusElement(content.value.length - 1, 'start') + focusElement(data.content.length - 1, 'start') }) } } @@ -345,7 +462,7 @@ const handleContainerClick = (event: MouseEvent) => { // 初始化 const initPlaceholders = () => { nextTick(() => { - content.value.forEach((_, index) => updateInputDisplay(index)) + data.content.forEach((_, index) => updateInputDisplay(index)) // 确保初始状态下有一个空文本框 ensureEmptyTextAtEnd() }) @@ -353,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 @@ -381,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({ @@ -416,7 +536,7 @@ defineExpose({ @click="handleContainerClick" >
-