Merge branch 'dev_vite' of ssh://18.167.251.121:10002/aidlab/aida_front into dev_vite
This commit is contained in:
@@ -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 = ()=>{
|
||||
|
||||
@@ -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<HTMLElement>()
|
||||
@@ -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<HTMLTextAreaElement>('textareaRef')
|
||||
|
||||
onMounted(() => {
|
||||
initPlaceholders()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
@@ -416,7 +536,7 @@ defineExpose({
|
||||
@click="handleContainerClick"
|
||||
>
|
||||
<div class="promptinput-wrapper">
|
||||
<template v-for="(item, index) in content" :key="item.id">
|
||||
<template v-for="(item, index) in data.content" :key="item.id">
|
||||
<span
|
||||
v-if="item.type === 'text'"
|
||||
class="text-field"
|
||||
@@ -433,6 +553,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)"
|
||||
></span>
|
||||
</span>
|
||||
</template>
|
||||
@@ -478,13 +601,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 +617,6 @@ defineExpose({
|
||||
|
||||
&.has-placeholder {
|
||||
color: #b9b9b9;
|
||||
// font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,7 +667,6 @@ defineExpose({
|
||||
font-size: 1rem;
|
||||
margin-right: 0;
|
||||
width: initial;
|
||||
// margin-top: -0.2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
Reference in New Issue
Block a user