chore: 代码格式化统一(空格、换行、属性排序、LF规范化)
This commit is contained in:
parent
b964c826ce
commit
e98ff3a2c4
@ -7,7 +7,8 @@
|
||||
"Bash(git -C \"D:/WebUI/Kexue/操作平台/AI_Painting_V2.0\" log --oneline --all -- src/stores/display.js)",
|
||||
"Bash(git -C \"D:/WebUI/Kexue/操作平台/AI_Painting_V2.0\" log --oneline --all -- src/components/dialogBox/index.vue)",
|
||||
"Bash(git -C \"D:/WebUI/Kexue/操作平台/AI_Painting_V2.0\" log --all --oneline --follow -p -- src/stores/display.js)",
|
||||
"Bash(git -C \"D:/WebUI/Kexue/操作平台/AI_Painting_V2.0\" log --all --oneline -p -- src/components/dialogBox/index.vue)"
|
||||
"Bash(git -C \"D:/WebUI/Kexue/操作平台/AI_Painting_V2.0\" log --all --oneline -p -- src/components/dialogBox/index.vue)",
|
||||
"Bash(npx eslint *)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,5 +43,5 @@ export const getUserInfo = () => {
|
||||
}
|
||||
|
||||
export const checkUsertoken = () => {
|
||||
return service.post(`/login/validateToken`)
|
||||
return service.post('/login/validateToken')
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="custom-popover" ref="popoverRef">
|
||||
<div class="popover-trigger" ref="triggerRef" @click.stop="togglePopover">
|
||||
<div ref="popoverRef" class="custom-popover">
|
||||
<div ref="triggerRef" class="popover-trigger" @click.stop="togglePopover">
|
||||
<slot name="reference" />
|
||||
</div>
|
||||
<Teleport to="body">
|
||||
@ -143,10 +143,10 @@ const handleClickOutside = (e) => {
|
||||
const contentEl = contentRef.value
|
||||
|
||||
if (
|
||||
triggerEl &&
|
||||
!triggerEl.contains(e.target) &&
|
||||
contentEl &&
|
||||
!contentEl.contains(e.target)
|
||||
triggerEl
|
||||
&& !triggerEl.contains(e.target)
|
||||
&& contentEl
|
||||
&& !contentEl.contains(e.target)
|
||||
) {
|
||||
visible.value = false
|
||||
window.__currentOpenPopoverId__ = null
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
ref="editableDivRef"
|
||||
contenteditable="true"
|
||||
class="custom-textarea"
|
||||
@input="handleInput"
|
||||
:data-placeholder="!inputText ? '请输入提示词或使用圆形/矩形工具' : ''"
|
||||
@input="handleInput"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -114,8 +114,8 @@
|
||||
ref="brushTextareaRef"
|
||||
contenteditable="true"
|
||||
class="brush-textarea"
|
||||
@input="handleBrushInput"
|
||||
:data-placeholder="!currentShapeDescription ? '请输入描述...' : ''"
|
||||
@input="handleBrushInput"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
@ -160,10 +160,10 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { generate } from '@/utils/taskPolling'
|
||||
import { useDisplayStore } from '@/stores'
|
||||
import request from '@/utils/request'
|
||||
import { getModelId } from '@/utils/modelApi'
|
||||
import request from '@/utils/request'
|
||||
import { generate } from '@/utils/taskPolling'
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
@ -268,7 +268,7 @@ watch(() => props.visible, (newVal) => {
|
||||
historyIndex.value = -1
|
||||
promptHistory.value = []
|
||||
promptHistoryIndex.value = -1
|
||||
allReferenceImages.value = props.referenceImages.map(img => img.url || img)
|
||||
allReferenceImages.value = props.referenceImages.map((img) => img.url || img)
|
||||
brushPanelVisible.value = false
|
||||
isPanelOpen.value = false
|
||||
currentShapeDescription.value = ''
|
||||
@ -310,8 +310,8 @@ const initCanvas = () => {
|
||||
img.src = imageUrl
|
||||
} else {
|
||||
fetch(imageUrl)
|
||||
.then(res => res.blob())
|
||||
.then(blob => {
|
||||
.then((res) => res.blob())
|
||||
.then((blob) => {
|
||||
const img = new Image()
|
||||
img.onload = () => {
|
||||
const imgScale = Math.min(containerWidth / img.width, containerHeight / img.height)
|
||||
@ -378,7 +378,7 @@ const handleMouseMove = (e) => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
ctx.drawImage(bgImage.value, 0, 0)
|
||||
|
||||
shapes.value.forEach(shape => {
|
||||
shapes.value.forEach((shape) => {
|
||||
drawShape(ctx, shape)
|
||||
})
|
||||
|
||||
@ -396,7 +396,7 @@ const handleMouseMove = (e) => {
|
||||
ctx.fillStyle = '#fff'
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||
|
||||
shapes.value.forEach(shape => {
|
||||
shapes.value.forEach((shape) => {
|
||||
drawShape(ctx, shape)
|
||||
})
|
||||
|
||||
@ -431,8 +431,8 @@ const handleMouseUp = (e) => {
|
||||
type: currentShape.value,
|
||||
startX: startX.value,
|
||||
startY: startY.value,
|
||||
endX: endX,
|
||||
endY: endY,
|
||||
endX,
|
||||
endY,
|
||||
color: shapeColors[colorIndex],
|
||||
description: '',
|
||||
referenceImages: []
|
||||
@ -515,7 +515,7 @@ const redrawCanvas = () => {
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height)
|
||||
}
|
||||
|
||||
shapes.value.forEach(shape => {
|
||||
shapes.value.forEach((shape) => {
|
||||
drawShape(ctx, shape)
|
||||
})
|
||||
}
|
||||
@ -530,7 +530,7 @@ const drawShape = (ctx, shape) => {
|
||||
ctx.strokeRect(shape.startX, shape.startY, width, height)
|
||||
} else if (shape.type === 'circle') {
|
||||
const radius = Math.sqrt(
|
||||
Math.pow(shape.endX - shape.startX, 2) + Math.pow(shape.endY - shape.startY, 2)
|
||||
(shape.endX - shape.startX) ** 2 + (shape.endY - shape.startY) ** 2
|
||||
)
|
||||
ctx.beginPath()
|
||||
ctx.arc(shape.startX, shape.startY, radius, 0, Math.PI * 2)
|
||||
@ -743,9 +743,9 @@ const handleSend = async () => {
|
||||
modelId,
|
||||
quantity: 1,
|
||||
params: [
|
||||
{ name: 'prompt', data: inputText.value + '并且去除掉图1中的框' },
|
||||
{ name: 'prompt', data: `${inputText.value}并且去除掉图1中的框` },
|
||||
{ name: 'index', data: 1 },
|
||||
{ name: 'proportion', data: proportion?.aspectRatio || '4:3' },
|
||||
{ name: 'proportion', data: proportion?.aspectRatio || '4:3' }
|
||||
],
|
||||
imgs: uploadedImgs,
|
||||
request: JSON.stringify(generateData)
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
<div v-show="showUploader" class="upload-img-container">
|
||||
<div class="reference-diagram">
|
||||
<component
|
||||
v-if="platform.ImageUploader"
|
||||
:is="platform.ImageUploader"
|
||||
v-if="platform.ImageUploader"
|
||||
ref="referenceDiagramRef"
|
||||
v-model="referenceImages"
|
||||
v-bind="uploaderBindings"
|
||||
@ -34,11 +34,11 @@
|
||||
<div class="prefix-self-wrap">
|
||||
<component
|
||||
:is="platform.ModelSelector"
|
||||
:modelValue="platform.model.value"
|
||||
@update:modelValue="platform.model.value = $event"
|
||||
:typeValue="platform.modelType.value"
|
||||
@update:typeValue="platform.modelType.value = $event"
|
||||
:model-value="platform.model.value"
|
||||
:type-value="platform.modelType.value"
|
||||
v-bind="(platform.modelSelectorProps && platform.modelSelectorProps()) || {}"
|
||||
@update:model-value="platform.model.value = $event"
|
||||
@update:type-value="platform.modelType.value = $event"
|
||||
/>
|
||||
<template v-for="ctrl in visibleControls" :key="ctrl.name">
|
||||
<component
|
||||
@ -62,18 +62,17 @@
|
||||
</div>
|
||||
</template>
|
||||
</Sender>
|
||||
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Sender } from 'vue-element-plus-x'
|
||||
import { useDisplayStore } from '@/stores'
|
||||
import { generate } from '@/utils/taskPolling'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { createPlatform } from '@/platforms/registry.js'
|
||||
import { useDisplayStore } from '@/stores'
|
||||
import { getModelId } from '@/utils/modelApi'
|
||||
import { generate } from '@/utils/taskPolling'
|
||||
|
||||
// 确保平台包被加载(触发自注册)
|
||||
import '@/platforms/painting/index.js'
|
||||
@ -82,7 +81,7 @@ import '@/platforms/video/index.js'
|
||||
const props = defineProps({
|
||||
isGenerate: { type: Boolean, default: false },
|
||||
generate: { type: Boolean, default: false },
|
||||
type: { type: String, default: 'Painting' },
|
||||
type: { type: String, default: 'Painting' }
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
@ -99,7 +98,7 @@ const getCurrentConfig = () => {
|
||||
|
||||
const visibleControls = computed(() => {
|
||||
const config = getCurrentConfig()
|
||||
return platform.value.controls.filter(c => c.show(config))
|
||||
return platform.value.controls.filter((c) => c.show(config))
|
||||
})
|
||||
|
||||
const showUploader = computed(() => {
|
||||
@ -148,7 +147,7 @@ const handleStart = async () => {
|
||||
modelType: p.modelType.value,
|
||||
prompt: prompt.value,
|
||||
referenceImages: referenceImages.value,
|
||||
modelParams: body,
|
||||
modelParams: body
|
||||
}
|
||||
|
||||
const data = {
|
||||
@ -157,7 +156,7 @@ const handleStart = async () => {
|
||||
modelName: p.model.value,
|
||||
modelId: modelId || '',
|
||||
body,
|
||||
request: JSON.stringify(generateData),
|
||||
request: JSON.stringify(generateData)
|
||||
}
|
||||
|
||||
await generate(data, generateData)
|
||||
@ -190,7 +189,7 @@ watch(
|
||||
async ([newModel, newModelType]) => {
|
||||
if (!newModel) return
|
||||
await platform.value.loadConfig(newModel, newModelType)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// 平台切换 → 设置默认模型 + 预加载模型列表
|
||||
|
||||
@ -100,6 +100,8 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['scroll', 'scroll-start', 'scroll-end', 'visible-change'])
|
||||
|
||||
const computedData = computed(() => {
|
||||
return props.data.length > 0 ? props.data : props.items
|
||||
})
|
||||
@ -114,8 +116,6 @@ const computedBuffer = computed(() => {
|
||||
return props.buffer !== 3 ? props.buffer : props.bufferSize
|
||||
})
|
||||
|
||||
const emit = defineEmits(['scroll', 'scroll-start', 'scroll-end', 'visible-change'])
|
||||
|
||||
const containerRef = ref(null)
|
||||
const wrapperRef = ref(null)
|
||||
const renderContainerRef = ref(null)
|
||||
@ -275,7 +275,7 @@ const bottomPlaceholderStyle = computed(() => ({
|
||||
top: 0,
|
||||
width: '100%',
|
||||
height: `${props.bottomPlaceholderHeight}px`,
|
||||
transform: `translateY(0px)`,
|
||||
transform: 'translateY(0px)',
|
||||
zIndex: 1
|
||||
}))
|
||||
|
||||
@ -335,7 +335,7 @@ const setupResizeObserver = () => {
|
||||
|
||||
resizeObserver.value = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
const index = parseInt(entry.target.dataset.index, 10)
|
||||
const index = Number.parseInt(entry.target.dataset.index, 10)
|
||||
if (!isNaN(index)) {
|
||||
measureItem(index, entry.target)
|
||||
}
|
||||
@ -529,7 +529,7 @@ const cleanupExtraItems = (currentVisibleItems) => {
|
||||
if (!renderContainerRef.value || !currentVisibleItems.length) return
|
||||
|
||||
// 构建当前应该可见的索引集合
|
||||
const visibleIndices = new Set(currentVisibleItems.map(item => item.index))
|
||||
const visibleIndices = new Set(currentVisibleItems.map((item) => item.index))
|
||||
|
||||
// 直接获取 render-container 内所有实际渲染的 .virtual-scroller-item 元素
|
||||
const renderedItems = renderContainerRef.value.querySelectorAll('.virtual-scroller-item')
|
||||
@ -537,7 +537,7 @@ const cleanupExtraItems = (currentVisibleItems) => {
|
||||
const toRemove = []
|
||||
|
||||
for (const el of renderedItems) {
|
||||
const dataIndex = parseInt(el.getAttribute('data-index'), 10)
|
||||
const dataIndex = Number.parseInt(el.getAttribute('data-index'), 10)
|
||||
|
||||
// 如果元素的 data-index 不在可见范围内,标记为删除
|
||||
if (!isNaN(dataIndex) && !visibleIndices.has(dataIndex)) {
|
||||
@ -551,7 +551,7 @@ const cleanupExtraItems = (currentVisibleItems) => {
|
||||
el.parentNode.removeChild(el)
|
||||
}
|
||||
// 同步清理 itemRefs Map
|
||||
const index = parseInt(el.getAttribute('data-index'), 10)
|
||||
const index = Number.parseInt(el.getAttribute('data-index'), 10)
|
||||
if (!isNaN(index)) {
|
||||
itemRefs.delete(index)
|
||||
}
|
||||
|
||||
@ -99,6 +99,8 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['scroll', 'scroll-start', 'scroll-end', 'visible-change'])
|
||||
|
||||
const computedData = computed(() => {
|
||||
return props.data.length > 0 ? props.data : props.items
|
||||
})
|
||||
@ -113,8 +115,6 @@ const computedBuffer = computed(() => {
|
||||
return props.buffer !== 3 ? props.buffer : props.bufferSize
|
||||
})
|
||||
|
||||
const emit = defineEmits(['scroll', 'scroll-start', 'scroll-end', 'visible-change'])
|
||||
|
||||
const containerRef = ref(null)
|
||||
const wrapperRef = ref(null)
|
||||
const renderContainerRef = ref(null)
|
||||
@ -269,7 +269,7 @@ const bottomPlaceholderStyle = computed(() => ({
|
||||
top: 0,
|
||||
width: '100%',
|
||||
height: `${props.bottomPlaceholderHeight}px`,
|
||||
transform: `translateY(0px)`,
|
||||
transform: 'translateY(0px)',
|
||||
zIndex: 1
|
||||
}))
|
||||
|
||||
@ -347,7 +347,7 @@ const setupResizeObserver = () => {
|
||||
|
||||
resizeObserver.value = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
const index = parseInt(entry.target.dataset.index, 10)
|
||||
const index = Number.parseInt(entry.target.dataset.index, 10)
|
||||
if (!isNaN(index)) {
|
||||
measureItem(index, entry.target)
|
||||
}
|
||||
|
||||
@ -1,194 +1,194 @@
|
||||
window.TEST_DATA = [
|
||||
{
|
||||
"id": "839217090555557410",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/27/69ef43d23888d39e4ed1d062.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '839217090555557410',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/27/69ef43d23888d39e4ed1d062.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "839211834861958673",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/27/69ef3eed3888d39e4ed1d061.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "BananaPro"
|
||||
id: '839211834861958673',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/27/69ef3eed3888d39e4ed1d061.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'BananaPro'
|
||||
},
|
||||
{
|
||||
"id": "839209605929121287",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/27/69ef3cd93888d39e4ed1d060.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '839209605929121287',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/27/69ef3cd93888d39e4ed1d060.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "837370053866304564",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/22/69e88ba23888d39e4ed1d05c.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '837370053866304564',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/22/69e88ba23888d39e4ed1d05c.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "837360015437214709",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/22/69e882493888d39e4ed1d05b.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '837360015437214709',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/22/69e882493888d39e4ed1d05b.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "836534979084169461",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/20/69e581e93888d39e4ed1d025.png",
|
||||
"prompt": "<div data-v-43afc57f=\"\" class=\"prompt-container\" style=\"width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255); height: 39px;\"><div data-v-43afc57f=\"\" class=\"prompt-wrapper\" style=\"width: 1118px;\"><div data-v-43afc57f=\"\" class=\"prompt expanded\" style=\"max-height: none; overflow: visible;\"><span data-v-43afc57f=\"\" class=\"prompt-text\">将图1红色框内的【苹果】替换为【火龙果】</span></div><div><span data-v-43afc57f=\"\" class=\"prompt-text\"><br></span></div></div></div><div data-v-43afc57f=\"\" class=\"box success-box\" style=\"width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255);\"><div data-v-43afc57f=\"\" class=\"one-box\"></div></div>",
|
||||
"model": "banana"
|
||||
id: '836534979084169461',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/20/69e581e93888d39e4ed1d025.png',
|
||||
prompt: '<div data-v-43afc57f="" class="prompt-container" style="width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255); height: 39px;"><div data-v-43afc57f="" class="prompt-wrapper" style="width: 1118px;"><div data-v-43afc57f="" class="prompt expanded" style="max-height: none; overflow: visible;"><span data-v-43afc57f="" class="prompt-text">将图1红色框内的【苹果】替换为【火龙果】</span></div><div><span data-v-43afc57f="" class="prompt-text"><br></span></div></div></div><div data-v-43afc57f="" class="box success-box" style="width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255);"><div data-v-43afc57f="" class="one-box"></div></div>',
|
||||
model: 'banana'
|
||||
},
|
||||
{
|
||||
"id": "835464458670191734",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/17/69e19ce93888d39e4ed1cfaf.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '835464458670191734',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/17/69e19ce93888d39e4ed1cfaf.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "835463648116749398",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/17/69e19c273888d39e4ed1cfac.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '835463648116749398',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/17/69e19c273888d39e4ed1cfac.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "835463392293565520",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/17/69e19bea3888d39e4ed1cfab.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '835463392293565520',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/17/69e19bea3888d39e4ed1cfab.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "832562717234575283",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf66.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf67.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf68.png,http://test.xueai.art/file/2026/4/9/69d70e743888d39e4ed1cf69.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '832562717234575283',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf66.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf67.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf68.png,http://test.xueai.art/file/2026/4/9/69d70e743888d39e4ed1cf69.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "839217090555557410",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/27/69ef43d23888d39e4ed1d062.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '839217090555557410',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/27/69ef43d23888d39e4ed1d062.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "839211834861958673",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/27/69ef3eed3888d39e4ed1d061.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "BananaPro"
|
||||
id: '839211834861958673',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/27/69ef3eed3888d39e4ed1d061.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'BananaPro'
|
||||
},
|
||||
{
|
||||
"id": "839209605929121287",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/27/69ef3cd93888d39e4ed1d060.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '839209605929121287',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/27/69ef3cd93888d39e4ed1d060.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "837370053866304564",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/22/69e88ba23888d39e4ed1d05c.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '837370053866304564',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/22/69e88ba23888d39e4ed1d05c.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "837360015437214709",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/22/69e882493888d39e4ed1d05b.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '837360015437214709',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/22/69e882493888d39e4ed1d05b.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "836534979084169461",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/20/69e581e93888d39e4ed1d025.png",
|
||||
"prompt": "<div data-v-43afc57f=\"\" class=\"prompt-container\" style=\"width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255); height: 39px;\"><div data-v-43afc57f=\"\" class=\"prompt-wrapper\" style=\"width: 1118px;\"><div data-v-43afc57f=\"\" class=\"prompt expanded\" style=\"max-height: none; overflow: visible;\"><span data-v-43afc57f=\"\" class=\"prompt-text\">将图1红色框内的【苹果】替换为【火龙果】</span></div><div><span data-v-43afc57f=\"\" class=\"prompt-text\"><br></span></div></div></div><div data-v-43afc57f=\"\" class=\"box success-box\" style=\"width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255);\"><div data-v-43afc57f=\"\" class=\"one-box\"></div></div>",
|
||||
"model": "banana"
|
||||
id: '836534979084169461',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/20/69e581e93888d39e4ed1d025.png',
|
||||
prompt: '<div data-v-43afc57f="" class="prompt-container" style="width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255); height: 39px;"><div data-v-43afc57f="" class="prompt-wrapper" style="width: 1118px;"><div data-v-43afc57f="" class="prompt expanded" style="max-height: none; overflow: visible;"><span data-v-43afc57f="" class="prompt-text">将图1红色框内的【苹果】替换为【火龙果】</span></div><div><span data-v-43afc57f="" class="prompt-text"><br></span></div></div></div><div data-v-43afc57f="" class="box success-box" style="width: 1118px; font-size: 14px; background-color: rgb(255, 255, 255);"><div data-v-43afc57f="" class="one-box"></div></div>',
|
||||
model: 'banana'
|
||||
},
|
||||
{
|
||||
"id": "835464458670191734",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/17/69e19ce93888d39e4ed1cfaf.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '835464458670191734',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/17/69e19ce93888d39e4ed1cfaf.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "835463648116749398",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/17/69e19c273888d39e4ed1cfac.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '835463648116749398',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/17/69e19c273888d39e4ed1cfac.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "835463392293565520",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/17/69e19bea3888d39e4ed1cfab.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '835463392293565520',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/17/69e19bea3888d39e4ed1cfab.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "832562717234575283",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf66.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf67.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf68.png,http://test.xueai.art/file/2026/4/9/69d70e743888d39e4ed1cf69.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '832562717234575283',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf66.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf67.png,http://test.xueai.art/file/2026/4/9/69d70e733888d39e4ed1cf68.png,http://test.xueai.art/file/2026/4/9/69d70e743888d39e4ed1cf69.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "830138209152283808",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/2/69ce3c743888d39e4ed1cf4f.png",
|
||||
"prompt": "将图1红色框内的【苹果】替换为【火龙果】",
|
||||
"model": "banana"
|
||||
id: '830138209152283808',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/2/69ce3c743888d39e4ed1cf4f.png',
|
||||
prompt: '将图1红色框内的【苹果】替换为【火龙果】',
|
||||
model: 'banana'
|
||||
},
|
||||
{
|
||||
"id": "830136945106498711",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/2/69ce3b463888d39e4ed1cf4e.png",
|
||||
"prompt": "一个女孩在树下吃苹果",
|
||||
"model": "flux"
|
||||
id: '830136945106498711',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/2/69ce3b463888d39e4ed1cf4e.png',
|
||||
prompt: '一个女孩在树下吃苹果',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "830083758811001839",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/4/2/69ce09be3888d39e4ed1cf48.png",
|
||||
"prompt": "一个女孩在树下吃苹果",
|
||||
"model": "flux"
|
||||
id: '830083758811001839',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/4/2/69ce09be3888d39e4ed1cf48.png',
|
||||
prompt: '一个女孩在树下吃苹果',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "829393290267734386",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb86b13888d39e4ed1cf32.png",
|
||||
"prompt": "将图1红色框内的【女孩】替换为【图2中的女孩】",
|
||||
"model": "banana"
|
||||
id: '829393290267734386',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb86b13888d39e4ed1cf32.png',
|
||||
prompt: '将图1红色框内的【女孩】替换为【图2中的女孩】',
|
||||
model: 'banana'
|
||||
},
|
||||
{
|
||||
"id": "829389466203337022",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb83223888d39e4ed1cf31.png",
|
||||
"prompt": "将图1红色框内的【<span style=\"font-size: 14px;\">女孩</span>】替换为【图2中的女孩】",
|
||||
"model": "banana"
|
||||
id: '829389466203337022',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb83223888d39e4ed1cf31.png',
|
||||
prompt: '将图1红色框内的【<span style="font-size: 14px;">女孩</span>】替换为【图2中的女孩】',
|
||||
model: 'banana'
|
||||
},
|
||||
{
|
||||
"id": "829388114303660338",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb81df3888d39e4ed1cf30.png",
|
||||
"prompt": "将图1红色框内的【女孩】替换为【男孩】",
|
||||
"model": "banana"
|
||||
id: '829388114303660338',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb81df3888d39e4ed1cf30.png',
|
||||
prompt: '将图1红色框内的【女孩】替换为【男孩】',
|
||||
model: 'banana'
|
||||
},
|
||||
{
|
||||
"id": "829381253919682782",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb7b7c3888d39e4ed1cf2d.png",
|
||||
"prompt": "将图1红色框内的【女孩】替换为【图2中的男孩】",
|
||||
"model": "banana"
|
||||
id: '829381253919682782',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb7b7c3888d39e4ed1cf2d.png',
|
||||
prompt: '将图1红色框内的【女孩】替换为【图2中的男孩】',
|
||||
model: 'banana'
|
||||
},
|
||||
{
|
||||
"id": "829324561060212843",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb46af3888d39e4ed1cf29.png",
|
||||
"prompt": "一个女孩在树下吃苹果",
|
||||
"model": "flux"
|
||||
id: '829324561060212843',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb46af3888d39e4ed1cf29.png',
|
||||
prompt: '一个女孩在树下吃苹果',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "829319226454978647",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf25.png,http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf26.png,http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf27.png,http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf28.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '829319226454978647',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf25.png,http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf26.png,http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf27.png,http://test.xueai.art/file/2026/3/31/69cb41b73888d39e4ed1cf28.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "829317957644464188",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb40893888d39e4ed1cf20.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '829317957644464188',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb40893888d39e4ed1cf20.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "829305227994738709",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/31/69cb34ae3888d39e4ed1cf1e.png",
|
||||
"prompt": "这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格",
|
||||
"model": "flux"
|
||||
id: '829305227994738709',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/31/69cb34ae3888d39e4ed1cf1e.png',
|
||||
prompt: '这是一幅治愈写实风格的插画,画面中展现了一处城市石砌民居的顶层露台。石砌民居带有木质门、铁栅栏窗台、锈色金属屋顶,空调外机挂在墙边,金属防护栏环绕四周,外置楼梯延伸下来。露台上摆放着竹制躺椅和木质桌椅,旁边还有小凳。彩色水桶,一个是红色,一个是蓝色,放置在角落,花盆里栽种着金桔,水仙花、蝴蝶兰,整齐排列,大量花卉在露台上盛放。露台旁有一棵枝叶繁茂、遮天蔽日的大树,绿意浓郁,与建筑共生。周围还摆放着一些绿植盆栽。远处是城市的高楼,整个场景被绿意环绕,明亮柔和的光线洒下,充满了都市生活与自然融合感的顶层露台风情。Moebius (Jean Giraud)风格',
|
||||
model: 'flux'
|
||||
},
|
||||
{
|
||||
"id": "829068575099597628",
|
||||
"fileUrl": "http://test.xueai.art/file/2026/3/30/69ca58473888d39e0bb8728b.png",
|
||||
"prompt": "",
|
||||
"model": ""
|
||||
id: '829068575099597628',
|
||||
fileUrl: 'http://test.xueai.art/file/2026/3/30/69ca58473888d39e0bb8728b.png',
|
||||
prompt: '',
|
||||
model: ''
|
||||
}
|
||||
];
|
||||
]
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
<div class="input-group">
|
||||
<label>W</label>
|
||||
<input
|
||||
type="number"
|
||||
v-model.number="localWidth"
|
||||
type="number"
|
||||
:min="minW"
|
||||
:max="maxW"
|
||||
@input="onWidthChange"
|
||||
@ -21,8 +21,8 @@
|
||||
<div class="input-group">
|
||||
<label>H</label>
|
||||
<input
|
||||
type="number"
|
||||
v-model.number="localHeight"
|
||||
type="number"
|
||||
:min="minH"
|
||||
:max="maxH"
|
||||
@input="onHeightChange"
|
||||
@ -41,9 +41,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Popover from '@/components/Popover/index.vue'
|
||||
import lockIcon from '@/assets/dialog/lock.svg'
|
||||
import lockNoIcon from '@/assets/dialog/lockNo.svg'
|
||||
import Popover from '@/components/Popover/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
width: { type: Number, default: 1024 },
|
||||
@ -51,7 +51,7 @@ const props = defineProps({
|
||||
minW: { type: Number, default: 256 },
|
||||
maxW: { type: Number, default: 6197 },
|
||||
minH: { type: Number, default: 256 },
|
||||
maxH: { type: Number, default: 4096 },
|
||||
maxH: { type: Number, default: 4096 }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:width', 'update:height'])
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
<div class="size-inputs">
|
||||
<div class="input-group">
|
||||
<label>W</label>
|
||||
<input type="number" v-model.number="width" @input="updateWidth" :disabled="isLocked">
|
||||
<input v-model.number="width" type="number" :disabled="isLocked" @input="updateWidth">
|
||||
</div>
|
||||
<div class="lock-icon" :class="{ locked: isLocked }" @click="toggleLock">
|
||||
<img :src="isLocked ? lockIcon : lockNoIcon" alt="约束比例">
|
||||
@ -45,7 +45,7 @@
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label>H</label>
|
||||
<input type="number" v-model.number="height" @input="updateHeight" :disabled="isLocked">
|
||||
<input v-model.number="height" type="number" :disabled="isLocked" @input="updateHeight">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -60,9 +60,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Popover from '@/components/Popover/index.vue'
|
||||
import lockIcon from '@/assets/dialog/lock.svg'
|
||||
import lockNoIcon from '@/assets/dialog/lockNo.svg'
|
||||
import Popover from '@/components/Popover/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@ -95,7 +95,7 @@ const props = defineProps({
|
||||
},
|
||||
allowCustom: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
resolutionOptions: {
|
||||
type: Array,
|
||||
@ -461,5 +461,4 @@ watch(() => [props.modelValue, props.resolution], () => {
|
||||
background: #f5f6f7;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -19,8 +19,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
v-show="false"
|
||||
ref="uploadRef"
|
||||
:action="uploadurl"
|
||||
multiple
|
||||
:limit="limit"
|
||||
|
||||
@ -15,10 +15,9 @@
|
||||
import Select from '@/components/Select/index.vue'
|
||||
import { fetchPlatformModels, getPlatformCode } from '@/utils/modelApi'
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: String, default: 'Flux 2' },
|
||||
typeValue: { type: String, default: 'text' },
|
||||
typeValue: { type: String, default: 'text' }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'update:typeValue'])
|
||||
@ -28,7 +27,7 @@ const platformModels = ref([])
|
||||
const categoryMap = [
|
||||
{ tag: 'text', label: '生成模型', inputType: 'text' },
|
||||
{ tag: 'edit', label: '编辑模型', inputType: 'image' },
|
||||
{ tag: 'vision', label: '视觉理解模型', inputType: 'vision' },
|
||||
{ tag: 'vision', label: '视觉理解模型', inputType: 'vision' }
|
||||
]
|
||||
|
||||
function parseValue(encoded) {
|
||||
@ -44,14 +43,14 @@ function encodeValue(tag, modelName) {
|
||||
|
||||
function findTagForModel(modelName) {
|
||||
for (const cat of categoryMap) {
|
||||
const model = platformModels.value.find(m => (m.display_name || m.name) === modelName && m.tags?.includes(cat.tag))
|
||||
const model = platformModels.value.find((m) => (m.display_name || m.name) === modelName && m.tags?.includes(cat.tag))
|
||||
if (model) return cat.tag
|
||||
}
|
||||
return 'text'
|
||||
}
|
||||
|
||||
function tagToInputType(tag) {
|
||||
const cat = categoryMap.find(c => c.tag === tag)
|
||||
const cat = categoryMap.find((c) => c.tag === tag)
|
||||
return cat?.inputType || 'text'
|
||||
}
|
||||
|
||||
@ -67,7 +66,7 @@ const selectValue = computed({
|
||||
if (!parsed) return
|
||||
emit('update:modelValue', parsed.modelName)
|
||||
emit('update:typeValue', tagToInputType(parsed.tag))
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// 从 API 加载模型列表
|
||||
@ -89,26 +88,26 @@ const modelGroups = computed(() => {
|
||||
if (models.length === 0) return []
|
||||
|
||||
return categoryMap
|
||||
.filter(cat => models.some(m => m.tags?.includes(cat.tag)))
|
||||
.map(cat => ({
|
||||
.filter((cat) => models.some((m) => m.tags?.includes(cat.tag)))
|
||||
.map((cat) => ({
|
||||
label: cat.label,
|
||||
options: models
|
||||
.filter(m => m.tags?.includes(cat.tag))
|
||||
.map(m => ({
|
||||
.filter((m) => m.tags?.includes(cat.tag))
|
||||
.map((m) => ({
|
||||
value: `${cat.tag}::${m.display_name || m.name}`,
|
||||
label: m.display_name || m.name,
|
||||
disabled: m.disabled || false,
|
||||
disabled: m.disabled || false
|
||||
}))
|
||||
.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' })),
|
||||
.sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))
|
||||
}))
|
||||
})
|
||||
|
||||
// 模型列表加载后自动纠正不可用模型
|
||||
watch(platformModels, (models) => {
|
||||
if (models.length === 0) return
|
||||
const currentModel = models.find(m => (m.display_name || m.name) === props.modelValue || m.id === props.modelValue)
|
||||
const currentModel = models.find((m) => (m.display_name || m.name) === props.modelValue || m.id === props.modelValue)
|
||||
if (!currentModel || currentModel.disabled) {
|
||||
const firstEnabled = models.find(m => !m.disabled)
|
||||
const firstEnabled = models.find((m) => !m.disabled)
|
||||
if (firstEnabled) {
|
||||
emit('update:modelValue', firstEnabled.display_name || firstEnabled.name)
|
||||
emit('update:typeValue', tagToInputType(findTagForModel(firstEnabled.display_name || firstEnabled.name)))
|
||||
@ -121,9 +120,9 @@ watch(() => props.modelValue, (newValue) => {
|
||||
if (!newValue) return
|
||||
const models = platformModels.value
|
||||
if (models.length === 0) return
|
||||
const currentModel = models.find(m => (m.display_name || m.name) === newValue)
|
||||
const currentModel = models.find((m) => (m.display_name || m.name) === newValue)
|
||||
if (currentModel && currentModel.disabled) {
|
||||
const firstEnabled = models.find(m => !m.disabled)
|
||||
const firstEnabled = models.find((m) => !m.disabled)
|
||||
if (firstEnabled) {
|
||||
emit('update:modelValue', firstEnabled.display_name || firstEnabled.name)
|
||||
emit('update:typeValue', tagToInputType(findTagForModel(firstEnabled.display_name || firstEnabled.name)))
|
||||
|
||||
@ -18,12 +18,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Select from '@/components/Select/index.vue'
|
||||
|
||||
import videoPattern2 from '@/assets/dialog/videoPattern2.svg'
|
||||
|
||||
import videoPattern4 from '@/assets/dialog/videoPattern4.svg'
|
||||
import videoPattern5 from '@/assets/dialog/videoPattern5.svg'
|
||||
import videoPattern6 from '@/assets/dialog/videoPattern6.svg'
|
||||
import Select from '@/components/Select/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
@ -49,7 +49,7 @@ const quantityOptions = [
|
||||
]
|
||||
|
||||
const selectedIcon = computed(() => {
|
||||
const option = quantityOptions.find(opt => opt.value === quantity.value)
|
||||
const option = quantityOptions.find((opt) => opt.value === quantity.value)
|
||||
return option ? option.icon : videoPattern1
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
</div>
|
||||
<el-upload
|
||||
v-for="i in maxImages"
|
||||
v-show="false"
|
||||
:key="i"
|
||||
:ref="el => setUploadRef(el, i - 1)"
|
||||
v-show="false"
|
||||
:action="uploadurl"
|
||||
:limit="1"
|
||||
:before-upload="beforeUpload"
|
||||
|
||||
@ -44,15 +44,14 @@ const fetchConfig = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fetchConfig()
|
||||
|
||||
watch(() => videoConfig.value, (newConfig) => {
|
||||
const models = newConfig[props.videoPattern] || []
|
||||
if (models.length > 0) {
|
||||
const enabledModels = models.filter(m => !m.disabled)
|
||||
const enabledModels = models.filter((m) => !m.disabled)
|
||||
if (enabledModels.length > 0) {
|
||||
const currentModelExists = enabledModels.find(m => m.value === props.modelValue)
|
||||
const currentModelExists = enabledModels.find((m) => m.value === props.modelValue)
|
||||
if (!currentModelExists) {
|
||||
model.value = enabledModels[0].value
|
||||
}
|
||||
@ -60,7 +59,6 @@ watch(() => videoConfig.value, (newConfig) => {
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
|
||||
const model = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => {
|
||||
@ -91,9 +89,9 @@ const getModelType = (value) => {
|
||||
watch(() => props.videoPattern, (newPattern) => {
|
||||
const models = videoConfig.value[newPattern] || []
|
||||
if (models.length > 0) {
|
||||
const enabledModels = models.filter(m => !m.disabled)
|
||||
const enabledModels = models.filter((m) => !m.disabled)
|
||||
if (enabledModels.length > 0) {
|
||||
const currentModelExists = enabledModels.find(m => m.value === props.modelValue)
|
||||
const currentModelExists = enabledModels.find((m) => m.value === props.modelValue)
|
||||
if (!currentModelExists) {
|
||||
model.value = enabledModels[0].value
|
||||
}
|
||||
@ -103,9 +101,9 @@ watch(() => props.videoPattern, (newPattern) => {
|
||||
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
const models = videoConfig.value[props.videoPattern] || []
|
||||
const currentModel = models.find(m => m.value === newValue)
|
||||
const currentModel = models.find((m) => m.value === newValue)
|
||||
if (currentModel && currentModel.disabled) {
|
||||
const enabledModels = models.filter(m => !m.disabled)
|
||||
const enabledModels = models.filter((m) => !m.disabled)
|
||||
if (enabledModels.length > 0) {
|
||||
model.value = enabledModels[0].value
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { useDisplayStore, useUserStore } from '@/stores'
|
||||
import { useUserStore } from '@/stores'
|
||||
import { getToken, setToken } from '@/utils/auth'
|
||||
|
||||
const routes = [
|
||||
|
||||
@ -28,7 +28,7 @@ const DisplayStoreSetup = () => {
|
||||
}
|
||||
|
||||
const updateItemToSuccess = (taskId, fileUrls) => {
|
||||
const index = tempList.value.findIndex(item => item.id === taskId)
|
||||
const index = tempList.value.findIndex((item) => item.id === taskId)
|
||||
if (index !== -1) {
|
||||
tempList.value[index].status = 'success'
|
||||
tempList.value[index].files = Array.isArray(fileUrls) ? fileUrls : [fileUrls]
|
||||
@ -56,7 +56,7 @@ const DisplayStoreSetup = () => {
|
||||
}
|
||||
|
||||
const deleteHistoryItem = (id) => {
|
||||
const index = tempList.value.findIndex(item => item.id === id)
|
||||
const index = tempList.value.findIndex((item) => item.id === id)
|
||||
if (index !== -1) {
|
||||
tempList.value.splice(index, 1)
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
const ParamStoreSetup = () => {
|
||||
|
||||
return {
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ export async function generateFilename(url, prefix = 'image') {
|
||||
|
||||
// 如果URL中没有文件名或扩展名,根据类型生成
|
||||
if (!filename || !filename.includes('.')) {
|
||||
const timestamp = new Date().getTime()
|
||||
const timestamp = Date.now()
|
||||
// 根据URL内容推断文件类型,否则默认为png
|
||||
const extension = url.includes('.jpg') || url.includes('.jpeg')
|
||||
? '.jpg'
|
||||
@ -21,7 +21,7 @@ export async function generateFilename(url, prefix = 'image') {
|
||||
} catch (error) {
|
||||
console.error('URL解析失败:', error)
|
||||
// 如果URL解析失败,生成默认文件名
|
||||
const timestamp = new Date().getTime()
|
||||
const timestamp = Date.now()
|
||||
return `${prefix}_${timestamp}.png`
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,20 @@
|
||||
<template>
|
||||
<div style="width: 100%;display: flex;justify-content: center;align-items: center;transform: rotate(180deg);">
|
||||
<div class="primary-box" :class="{ 'none-primary-box': props.item.status === 'none' }">
|
||||
|
||||
<div class="prompt-container" ref="promptContainerRef">
|
||||
<div class="prompt-wrapper" ref="promptWrapperRef">
|
||||
<div class="prompt" ref="promptRef" :class="{ 'expanded': isHovering }" @mouseenter="isHovering = true" @mouseleave="isHovering = false">
|
||||
<div ref="promptContainerRef" class="prompt-container">
|
||||
<div ref="promptWrapperRef" class="prompt-wrapper">
|
||||
<div ref="promptRef" class="prompt" :class="{ expanded: isHovering }" @mouseenter="isHovering = true" @mouseleave="isHovering = false">
|
||||
<span class="prompt-text">
|
||||
{{ props.item.generateData.prompt || '生成图片' }}
|
||||
<i-ep-DocumentCopy class="Copy" @click.stop="copyPrompt" />
|
||||
</span>
|
||||
<div class="generate-data internal" v-show="!isHovering && !showExternalGenerateData">
|
||||
<div v-show="!isHovering && !showExternalGenerateData" class="generate-data internal">
|
||||
<div class="detailed-data first-detailed-data">{{ props.item.generateData.model }}</div>
|
||||
<div class="detailed-data">{{ props.item.generateData.proportion }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="generate-data external" v-show="!isHovering && showExternalGenerateData">
|
||||
<div v-show="!isHovering && showExternalGenerateData" class="generate-data external">
|
||||
<div class="detailed-data first-detailed-data">{{ props.item.generateData.model }}</div>
|
||||
<div class="detailed-data">{{ props.item.generateData.proportion }}</div>
|
||||
</div>
|
||||
@ -49,7 +48,7 @@
|
||||
|
||||
<!-- 已完成 图片 -->
|
||||
<div v-if="props.item.status === 'success' && props.item.type === 'Painting'" class="box success-box">
|
||||
<div v-for="(file, index) in props.item.files" :key="index" class="one-box" :class="{ 'collected': isCollected(file) }" @mouseenter="hoverIndex = index" @mouseleave="hoverIndex = -1">
|
||||
<div v-for="(file, index) in props.item.files" :key="index" class="one-box" :class="{ collected: isCollected(file) }" @mouseenter="hoverIndex = index" @mouseleave="hoverIndex = -1">
|
||||
<!-- <img :src="file" alt="index" class="img" /> -->
|
||||
<Img :src="file" alt="index" class="img" />
|
||||
|
||||
@ -65,7 +64,7 @@
|
||||
placement="top"
|
||||
:hide-after="0"
|
||||
>
|
||||
<div @click.stop="AIbrush(file, index)" class="bottom-brush">
|
||||
<div class="bottom-brush" @click.stop="AIbrush(file, index)">
|
||||
<img :src="brush" />
|
||||
</div>
|
||||
</el-tooltip>
|
||||
@ -74,7 +73,7 @@
|
||||
|
||||
<!-- 已完成 视频 -->
|
||||
<div v-if="props.item.status === 'success' && props.item.type === 'Video'" class="box success-box">
|
||||
<div class="one-box" :class="{ 'collected': isCollected(props.item.files[0]) }" @mouseenter="hoverIndex = 0" @mouseleave="hoverIndex = -1">
|
||||
<div class="one-box" :class="{ collected: isCollected(props.item.files[0]) }" @mouseenter="hoverIndex = 0" @mouseleave="hoverIndex = -1">
|
||||
<!-- <img :src="file" alt="index" class="img" /> -->
|
||||
<video :src="props.item.files[0]" class="video" controls playsinline />
|
||||
|
||||
@ -97,16 +96,16 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { cancelOrCollect, deleteGenerateHistory } from '@/apis/display'
|
||||
import againGenerateIcon from '@/assets/display/againGenerate.svg'
|
||||
import brush from '@/assets/display/brush.svg'
|
||||
import collectionIcon from '@/assets/display/collection.svg'
|
||||
import collectionActiveIcon from '@/assets/display/collection-active.svg'
|
||||
import collectionIcon from '@/assets/display/collection.svg'
|
||||
import deleteImageIcon from '@/assets/display/deleteImage.svg'
|
||||
import reEditIcon from '@/assets/display/reEdit.svg'
|
||||
import Img from '@/components/Img/index.vue'
|
||||
import { useDisplayStore, useParamStore, useUserStore } from '@/stores'
|
||||
import { downloadImage } from '@/utils/downloadImage.js'
|
||||
import reEditIcon from '@/assets/display/reEdit.svg'
|
||||
import againGenerateIcon from '@/assets/display/againGenerate.svg'
|
||||
import deleteImageIcon from '@/assets/display/deleteImage.svg'
|
||||
import Img from '@/components/Img/index.vue'
|
||||
import { cancelOrCollect, deleteGenerateHistory } from '@/apis/display'
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
@ -276,7 +275,7 @@ const addCollection = async (url) => {
|
||||
const res = await cancelOrCollect({
|
||||
taskId: props.item.id,
|
||||
userId: useUser.userInfo.id,
|
||||
url: url,
|
||||
url
|
||||
})
|
||||
if (res.success) {
|
||||
ElMessage.success(res.message || '操作成功')
|
||||
|
||||
@ -43,8 +43,8 @@
|
||||
</div>
|
||||
|
||||
<VirtualScroller
|
||||
ref="scrollerRef"
|
||||
v-if="props.if"
|
||||
ref="scrollerRef"
|
||||
:items="list"
|
||||
key-field="id"
|
||||
:estimated-height="300"
|
||||
@ -66,17 +66,17 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useDisplayStore, useParamStore, useUserStore } from '@/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import Set from './components/set.vue'
|
||||
import RefreshOverlay from './components/RefreshOverlay.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { requestTaskHistory } from '@/apis/display'
|
||||
import Canvas from '@/components/canvas/index.vue'
|
||||
import Select from '@/components/Select/index.vue'
|
||||
import { VirtualScroller } from '@/components/virtual-scroller'
|
||||
import Canvas from '@/components/canvas/index.vue'
|
||||
import { requestTaskHistory } from '@/apis/display'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getChargeType } from '@/utils/taskPolling'
|
||||
import { useDisplayStore, useParamStore, useUserStore } from '@/stores'
|
||||
import { getPlatformCode } from '@/utils/modelApi'
|
||||
import { getChargeType } from '@/utils/taskPolling'
|
||||
import RefreshOverlay from './components/RefreshOverlay.vue'
|
||||
import Set from './components/set.vue'
|
||||
|
||||
const props = defineProps({
|
||||
if: {
|
||||
@ -138,7 +138,7 @@ const toggleDisplay = (newValue, oldValue) => {
|
||||
const conversion = (newlist) => {
|
||||
const temp = newlist.map((item) => {
|
||||
// 从 outputs 扁平数组提取 URL
|
||||
const files = item.outputs?.map(o => o.url) || []
|
||||
const files = item.outputs?.map((o) => o.url) || []
|
||||
const request = item.request || {}
|
||||
const generateData = {
|
||||
model: item.model_name || '',
|
||||
@ -152,7 +152,7 @@ const conversion = (newlist) => {
|
||||
customHight: request.customHight,
|
||||
duration: request.duration || '',
|
||||
videoPattern: request.videoPattern || '',
|
||||
modelParams: { ...request },
|
||||
modelParams: { ...request }
|
||||
}
|
||||
// 将 API status 映射为 UI 展示状态
|
||||
let uiStatus = 'success'
|
||||
@ -168,7 +168,7 @@ const conversion = (newlist) => {
|
||||
generateData,
|
||||
time: item.created_at || '',
|
||||
files,
|
||||
collectStatus: item.collectStatus || {},
|
||||
collectStatus: item.collectStatus || {}
|
||||
}
|
||||
})
|
||||
return temp
|
||||
@ -235,7 +235,6 @@ const fetchHistory = async (isLoadMore = false) => {
|
||||
}
|
||||
|
||||
hasMoreData.value = dataList.length === 10
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取历史失败:', error)
|
||||
ElMessage({
|
||||
@ -380,5 +379,4 @@ onBeforeUnmount(() => {
|
||||
background-color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<script setup>
|
||||
import { computed, ref, onMounted, watch } from 'vue'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import display from './display/index.vue'
|
||||
import { useDisplayStore } from '@/stores'
|
||||
import display from './display/index.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const useDisplay = useDisplayStore()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user