-
+

@@ -39,19 +36,6 @@
-
@@ -60,8 +44,9 @@
import Proportion from './proportion/index.vue'
import Quantity from './quantity/index.vue'
import Model from './model/index.vue'
+import ImageUploader from './imageUploader/index.vue'
import { Sender } from 'vue-element-plus-x'
-import { useDisplayStore, useParamStore } from '@/stores'
+import { useDisplayStore } from '@/stores'
import { generate } from '@/utils/websocket'
import { useRouter } from 'vue-router'
@@ -77,19 +62,17 @@ const props = defineProps({
})
const router = useRouter()
const useDisplay = useDisplayStore()
-const useParams = useParamStore()
-const uploadurl = import.meta.env.VITE_API_WORKFLOW_UPLOAD
-const uploadRef = ref(null)
+const type = ref('image')
+
+const prompt = ref('一个女孩在树下吃苹果')
const model = ref('flux')
-const proportion = ref('9:16')
+const proportion = ref('4:3')
const quantity = ref(1)
const resolution = ref('1k')
const promptPlaceholder = '描述你想生成的画面和动作。'
-const prompt = ref('一个女孩在树下吃苹果')
-const imageurl = ref('')
-const imageurlShow = ref('')
+const referenceImages = ref([])
const isgerenate = ref(false)
const autoSizeConfig = computed(() => {
@@ -100,61 +83,6 @@ const autoSizeConfig = computed(() => {
}
})
-// 处理图片选择
-const handleSelect = async (url) => {
- imageurlShow.value = url
- // 从URL获取图片Blob对象
- const initialFile = await fetch(url)
- const blob = await initialFile.blob()
-
- // 创建文件对象
- const file = new File([blob], `selected_image_${Date.now()}.jpg`, { type: blob.type })
- file.uid = genFileId()
- console.log('file', file)
-
- uploadRef.value.clearFiles() // 如果上传数量为1且已存在图片,则清除已存在的图
-
- // 获取当前文件列表
- uploadRef.value.handleStart(file)
- uploadRef.value.submit()
-}
-
-// 检查文件类型和大小
-const beforeUpload = (rawFile) => {
- console.log('beforeUpload', rawFile)
- const allowedTypes = ['image/jpeg', 'image/png']
-
- // 检查文件类型
- if (!allowedTypes.includes(rawFile.type)) {
- // eslint-disable-next-line no-undef
- ElMessage.error('不支持的文件类型,请上传 JPG、PNG 格式的图片')
- return false
- }
-
- // 检查文件大小(限制为2MB)
- if (rawFile.size / 1024 / 1024 > 10) {
- // eslint-disable-next-line no-undef
- ElMessage.error('图片大小不能超过 10MB')
- return false
- }
-}
-
-// 成功上传后,将文件信息保存到 state 中
-const SuccessSet = (response) => {
- console.log('上传成功', response)
- // eslint-disable-next-line no-undef
- ElMessage.success('上传成功')
- imageurl.value = response.url
-}
-
-// 错误处理
-const Errors = (error) => {
- console.log('上传失败', error)
- // eslint-disable-next-line no-undef
- ElMessage.error('上传失败,请重新选择图片')
- imageurlShow.value = ''
-}
-
const handleStart = async () => {
if (!props.isGenerate) {
router.push({ name: 'home', query: { loading: false, Generate: true } })
@@ -166,17 +94,25 @@ const handleStart = async () => {
}
isgerenate.value = true
console.log('生成开始', isgerenate.value)
+ const imgs = []
+ referenceImages.value.forEach((img, index) => {
+ imgs.push({ name: `image_${index + 1}`, data: img.url })
+ })
+
const data = {
AIGC: 'Painting',
platform: 'runninghub',
file_type: 'image',
modelName: model.value,
- prompt: prompt.value,
- quantity: quantity.value,
- aspect_ratio: proportion.value,
- resolution: resolution.value,
+ params: [
+ { name: 'prompt', data: prompt.value},
+ { name: 'quantity', data: quantity.value},
+ { name: 'aspect_ratio', data: proportion.value},
+ { name: 'resolution', data: resolution.value},
+ ],
+ imgs
}
- await generate('text', data)
+ await generate(type.value, data)
console.log('生成中', isgerenate.value)
}
@@ -193,24 +129,14 @@ const handleScrollToBottom = () => {
watch(() => useDisplay.isSubGerenate, (newValue) => {
console.log('生成状态', newValue)
- if (!newValue) {
- console.log('生成完成', isgerenate.value)
- isgerenate.value = useDisplay.isSubGerenate
- }
+ isgerenate.value = newValue
+ // handleScrollToBottom()
+}, { immediate: true })
+
+watch(() => type.value, (newValue) => {
+ console.log('type.value', newValue)
})
-watch(() => useParams.AIvideoImage, (newValue) => {
- if (newValue) {
- if (newValue.url === imageurl.value) return
- console.log('图片选择成功,打开视频页面', newValue)
- parentTime.value = newValue.time
- parentIndex.value = newValue.parentIndex
- parentTaskId.value = newValue.parentTaskId
- imageurl.value = newValue.url
- handleSelect(newValue.url)
- useParams.AIvideoImage = ''
- }
-})
onMounted(() => {
if (props.generate) {
generate()
@@ -231,7 +157,7 @@ onMounted(() => {
transition: all 0.3s ease;
}
-.scroll-to-bottom-btn {
+.sender-top {
width: 100%;
display: flex;
justify-content: flex-end;
@@ -239,24 +165,48 @@ onMounted(() => {
transition: all 0.3s ease;
z-index: 101;
margin-bottom: 10px;
+ position: relative;
.scroll-to-bottom-text {
- padding: 8px;
+ padding: 10px;
width: auto;
height: auto;
border-radius: 10px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
- background-color: rgba(0, 15, 51, 0.836);
- color: #ffffff;
+ // box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ background-color: #F8F9FA;
+ color: #666;
font-size: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 5px;
&:active {
transform: scale(0.95);
}
&:hover {
- background-color: rgb(0, 15, 51);
+ background-color: #F0F1F2;
+ }
+ }
+
+ // 上传图片
+ .upload-img-container{
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 80%;
+ display: flex;
+ justify-content: start;
+ align-items: center;
+ z-index: 1;
+ gap: 16px;
+
+ .reference-diagram {
+ display: flex;
+ align-items: center;
}
}
}
+
.generate{
height: 100%;
display: flex;
diff --git a/src/components/dialogBox/model/index.vue b/src/components/dialogBox/model/index.vue
index f4de1a9..a34ef50 100644
--- a/src/components/dialogBox/model/index.vue
+++ b/src/components/dialogBox/model/index.vue
@@ -54,27 +54,34 @@ const props = defineProps({
modelValue: {
type: String,
default: 'flux'
+ },
+ typeValue: {
+ type: String,
+ default: 'text'
}
})
-const emit = defineEmits(['update:modelValue'])
+const emit = defineEmits(['update:modelValue', 'update:typeValue'])
const model = computed({
get: () => props.modelValue,
- set: (value) => emit('update:modelValue', value)
+ set: (value) => {
+ emit('update:modelValue', value)
+ const newType = getModelType(value)
+ emit('update:typeValue', newType)
+ }
})
const generateModels = [
{ value: 'flux', label: 'flux' },
- { value: 'Z-image', label: 'Z-image' },
+ { value: 'zImage', label: 'Z-image' },
{ value: 'jimeng', label: 'jimeng' },
- { value: 'Qwen-image', label: 'Qwen-image' }
+ { value: 'QwenImage', label: 'QwenImage' }
]
const editModels = [
- { value: 'Banana-Pro', label: 'Banana-Pro' },
+ { value: 'BananaPro', label: 'Banana-Pro' },
{ value: 'Qwen-image', label: 'Qwen-image' },
- { value: 'Banana', label: 'Banana' },
{ value: 'Kontext', label: 'Kontext' },
{ value: 'Jimeng_4.0', label: 'Jimeng.4.0' }
]
@@ -87,6 +94,19 @@ const selectModel = (value) => {
model.value = value
}
+const getModelType = (value) => {
+ if (generateModels.find(m => m.value === value)) {
+ return 'text'
+ }
+ if (editModels.find(m => m.value === value)) {
+ return 'image'
+ }
+ if (visionModels.find(m => m.value === value)) {
+ return 'vision'
+ }
+ return 'text'
+}
+
const getModelLabel = (value) => {
const allModels = [...generateModels, ...editModels, ...visionModels]
const model = allModels.find(item => item.value === value)
diff --git a/src/config/runninghub/index.js b/src/config/runninghub/index.js
index 70793b8..e6fe68b 100644
--- a/src/config/runninghub/index.js
+++ b/src/config/runninghub/index.js
@@ -1,8 +1,42 @@
-export function Playload(data, type) {
- data = getWidthHeight(data)
- console.log('宽与高', data)
- if(data.modelName === 'flux'){
- return flux(data)
+export async function Playload(data,type) {
+ // data = getWidthHeight(data)
+ try {
+ const response = await fetch(`https://resources.xueai.art/AIGC/static/public/Platform/Painting/workflows/${type}/${data.modelName}.json`)
+ const json = await response.json()
+
+ const nodeInfoList = []
+
+ if (Array.isArray(data.imgs)) {
+ for (const key of data.imgs) {
+ if (json.nodeInfoList[key.name]) {
+ console.log(key)
+ json.nodeInfoList[key.name].fieldValue = key.url
+ nodeInfoList.push(json.nodeInfoList[key.name])
+ }
+ }
+ json.nodeInfoList[index].fieldValue = data.imgs.length() - 1
+ }
+
+ if (Array.isArray(data.params)) {
+ for (const key of data.params) {
+ if (json.nodeInfoList[key.name]) {
+ console.log(key)
+ json.nodeInfoList[key.name].fieldValue = key.data
+ nodeInfoList.push(json.nodeInfoList[key.name])
+ }
+ }
+ }
+
+ if (Array.isArray(json.must)) {
+ nodeInfoList.push(...json.must)
+ }
+ return {
+ workflowId: json.workflowId,
+ nodeInfoList
+ }
+ } catch (error) {
+ console.error('获取 JSON 文件失败:', error)
+ throw error
}
}
@@ -32,46 +66,21 @@ function getWidthHeight(data) {
return data
}
-function LTX2(data) {
-
- const nodeInfoList = [
- { nodeId: '9', fieldName: 'text', fieldValue: data.prompt },
- { nodeId: '40', fieldName: 'text', fieldValue: data.aspect_ratio },
- { nodeId: '39', fieldName: 'text', fieldValue: data.resolution },
- { nodeId: '29', fieldName: 'index', fieldValue: '' }
- ]
- switch (index){
- case 1:
- nodeInfoList[3].fieldValue = '1'
- break
- case 2:
- nodeInfoList[3].fieldValue = '2'
- break
- case 3:
- nodeInfoList[3].fieldValue = '3'
- break
- case 4:
- nodeInfoList[3].fieldValue = '4'
- break
- }
- if (data.image1) nodeInfoList.push({ nodeId: '2', fieldName: 'image', fieldValue: data.image1 })
- if (data.image2) nodeInfoList.push({ nodeId: '3', fieldName: 'image', fieldValue: data.image2 })
- if (data.image3) nodeInfoList.push({ nodeId: '4', fieldName: 'image', fieldValue: data.image3 })
- if (data.image4) nodeInfoList.push({ nodeId: '13', fieldName: 'image', fieldValue: data.image4 })
- if (data.image5) nodeInfoList.push({ nodeId: '14', fieldName: 'image', fieldValue: data.image5 })
-
- return {
- workflowId: '2031032712240304130',
- nodeInfoList
- }
-}
-
function flux(data) {
const nodeInfoList = [
{ nodeId: '23', fieldName: 'text', fieldValue: data.prompt },
{ nodeId: '129', fieldName: 'aspect_ratio', fieldValue: data.aspect_ratio },
- { nodeId: '101', fieldName: 'control_after_generate', fieldValue: 'randomize' }
+ { nodeId: '101', fieldName: 'control_after_generate', fieldValue: 'randomize' },
+ { nodeId: '15', fieldName: 'index', fieldValue: 0 },
+
+ {nodeId: '2', fieldName: 'vae_name', fieldValue: 'ae.sft'},
+ {nodeId: '5', fieldName: 'sampler_name', fieldValue: 'euler'},
+ {nodeId: '50', fieldName: 'value', fieldValue: 1},
+ {nodeId: '102', fieldName: 'value', fieldValue: 20},
+ {nodeId: '103', fieldName: 'value', fieldValue: 1},
+ {nodeId: '104', fieldName: 'value', fieldValue: 1},
+ {nodeId: '105', fieldName: 'value', fieldValue: 0.8}
]
return {
diff --git a/src/stores/display.js b/src/stores/display.js
index 7d1be53..57e12b1 100644
--- a/src/stores/display.js
+++ b/src/stores/display.js
@@ -2,6 +2,7 @@ const DisplayStoreSetup = () => {
const Sender_variant = ref('updown')
const scrollerRef = ref(null)
const tempList = ref([])
+ const isSubGerenate = ref(false)
const addGeneratingItem = (item) => {
const newItem = {
@@ -63,6 +64,7 @@ const DisplayStoreSetup = () => {
Sender_variant,
scrollerRef,
tempList,
+ isSubGerenate,
addGeneratingItem,
updateItemToSuccess,
initHistoryList,
diff --git a/src/utils/createTask.js b/src/utils/createTask.js
index c463bd2..df24ce2 100644
--- a/src/utils/createTask.js
+++ b/src/utils/createTask.js
@@ -3,7 +3,7 @@ import outPlatform from '@/config/index'
// 处理音频生成任务的数据并返回
export async function createTask(data, type, taskId, token) {
console.log(data, type)
- const payload = await outPlatform[data.platform].Playload(data)
+ const payload = await outPlatform[data.platform].Playload(data, type)
return {
AIGC: data.AIGC,
diff --git a/src/utils/websocket.js b/src/utils/websocket.js
index 948c6d2..4d2a564 100644
--- a/src/utils/websocket.js
+++ b/src/utils/websocket.js
@@ -55,11 +55,13 @@ export async function generate(type, data) {
const token = getToken()
const taskId = crypto.randomUUID()
let currentTaskId = null
+
+ useDisplay.isSubGerenate = true
const result = await createTask(data, type, taskId, token)
console.log(result)
// const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjY0NDEwODAyMjk1OTgzNzIzMCwicm5TdHIiOiJiWkVwS2JLWFJyZmRIaFFHWXZKTkdzOGdGM0JSRmxQOCJ9.5eQ2GtVdrDntQDe2tnF8vl_DhTfd2uW-KNqzvl1imc0'
- const wsURL = `${import.meta.env.VITE_API_WORKFLOW_WS}/?token=${token}`
+ const wsURL = `${import.meta.env.VITE_API_WORKFLOW_WS}/?token=Bearer ${token}`
const socket = new WebSocket(wsURL)
console.log('WebSocket连接已建立')
@@ -94,7 +96,9 @@ export async function generate(type, data) {
name: data.prompt || '生成中...',
type: type
})
-
+ setTimeout(() => {
+ useDisplay.scrollToBottom()
+ }, 100)
return
}
message.value = event.data
@@ -121,7 +125,7 @@ export async function generate(type, data) {
// 处理链接关闭
socket.onclose = async (event) => {
console.log('WebSocket已关闭:', event)
-
+ useDisplay.isSubGerenate = false
// 清理心跳定时器
if (heartbeatInterval) {
clearInterval(heartbeatInterval)
diff --git a/src/views/home/display/components/set.vue b/src/views/home/display/components/set.vue
index 08ec2b8..70964c0 100644
--- a/src/views/home/display/components/set.vue
+++ b/src/views/home/display/components/set.vue
@@ -365,9 +365,11 @@ const addCollection = (url) => {
align-items: center;
justify-content: center;
gap: 5px;
- padding: 5px 10px;
- border-radius: 5px;
+ width: 120px;
+ height: 36px;
+ border-radius: 10px;
cursor: pointer;
+ background-color: #F8F9FA;
}
.bottom-btn:hover{
background-color: #e4e7ed;
diff --git a/src/views/home/display/index.vue b/src/views/home/display/index.vue
deleted file mode 100644
index 7611d82..0000000
--- a/src/views/home/display/index.vue
+++ /dev/null
@@ -1,389 +0,0 @@
-
-
-
-
-
-

-
退出
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-