mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-04-30 23:14:28 +08:00
调整即梦AI移动端参数
This commit is contained in:
@@ -94,47 +94,6 @@
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #f9fafb;
|
background-color: #f9fafb;
|
||||||
|
|
||||||
/* 参数容器样式 - 参考 Jimeng.vue */
|
|
||||||
&__params-container {
|
|
||||||
padding: 16px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 12px;
|
|
||||||
margin-top: 16px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 功能面板样式 - 参考 Jimeng.vue */
|
|
||||||
&__function-panel {
|
|
||||||
.jimeng-create__param-line {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 参数行样式 - 参考 Jimeng.vue */
|
|
||||||
&__param-line {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
&.pt {
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 参数标签样式 - 参考 Jimeng.vue */
|
|
||||||
&__param-label {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #374151;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 页面头部样式 */
|
/* 页面头部样式 */
|
||||||
&__header {
|
&__header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else class="upload-item single-image-item">
|
<div v-else class="upload-item single-image-item">
|
||||||
<el-image :src="imageList[0]" fit="cover" class="upload-image" />
|
<el-image :src="imageList[0]" fit="cover" class="upload-image" />
|
||||||
<div class="upload-overlay" style="opacity: 1">
|
<div class="upload-overlay">
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
:icon="Delete"
|
:icon="Delete"
|
||||||
@@ -270,8 +270,7 @@ const removeImage = (index) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
opacity: 0;
|
opacity: 1;
|
||||||
transition: opacity 0.3s;
|
|
||||||
|
|
||||||
.remove-btn {
|
.remove-btn {
|
||||||
background: rgba(245, 108, 108, 0.8);
|
background: rgba(245, 108, 108, 0.8);
|
||||||
@@ -279,10 +278,6 @@ const removeImage = (index) => {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover .upload-overlay {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-btn {
|
.upload-btn {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="custom-select">
|
<div class="custom-select w-full">
|
||||||
<label v-if="label" class="block text-gray-700 font-medium mb-2">{{ label }}</label>
|
|
||||||
<button
|
<button
|
||||||
@click="showPicker = true"
|
@click="showPicker = true"
|
||||||
class="w-full flex items-center justify-between px-4 py-3 bg-gray-50 rounded-lg border border-gray-200 hover:border-blue-300 transition-colors"
|
class="w-full flex items-center justify-between px-4 py-3 bg-gray-50 rounded-lg border border-gray-200 hover:border-blue-300 transition-colors"
|
||||||
@@ -51,7 +50,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, watch } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import CustomSelectOption from './CustomSelectOption.vue'
|
import CustomSelectOption from './CustomSelectOption.vue'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
@@ -64,10 +63,6 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '请选择',
|
default: '请选择',
|
||||||
|
|||||||
@@ -32,25 +32,86 @@ export const useJimengStore = defineStore('mobile-jimeng', () => {
|
|||||||
|
|
||||||
// 选项数据
|
// 选项数据
|
||||||
const imageSizeOptions = [
|
const imageSizeOptions = [
|
||||||
{ label: '512x512', value: '512x512' },
|
{ label: '1:1 (1328x1328)', value: '1328x1328' },
|
||||||
{ label: '768x768', value: '768x768' },
|
{ label: '3:2 (1584x1056)', value: '1584x1056' },
|
||||||
{ label: '1024x1024', value: '1024x1024' },
|
{ label: '2:3 (1056x1584)', value: '1056x1584' },
|
||||||
{ label: '1024x1536', value: '1024x1536' },
|
{ label: '4:3 (1472x1104)', value: '1472x1104' },
|
||||||
{ label: '1536x1024', value: '1536x1024' },
|
{ label: '3:4 (1104x1472)', value: '1104x1472' },
|
||||||
|
{ label: '16:9 (1664x936)', value: '1664x936' },
|
||||||
|
{ label: '9:16 (936x1664)', value: '936x1664' },
|
||||||
|
{ label: '21:9 (2016x864)', value: '2016x864' },
|
||||||
|
{ label: '9:21 (864x2016)', value: '864x2016' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const videoAspectRatioOptions = [
|
const videoAspectRatioOptions = [
|
||||||
{ label: '16:9', value: '16:9' },
|
{ label: '1:1 (正方形)', value: '1:1' },
|
||||||
{ label: '9:16', value: '9:16' },
|
{ label: '16:9 (横版)', value: '16:9' },
|
||||||
{ label: '1:1', value: '1:1' },
|
{ label: '9:16 (竖版)', value: '9:16' },
|
||||||
{ label: '4:3', value: '4:3' },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const imageEffectsTemplateOptions = [
|
const imageEffectsTemplateOptions = [
|
||||||
{ label: '亚克力装饰', value: 'acrylic_ornaments' },
|
{
|
||||||
{ label: '天使小雕像', value: 'angel_figurine' },
|
label: '毛毡3D拍立得风格',
|
||||||
{ label: '毛毫3D拍立得', value: 'felt_3d_polaroid' },
|
value: 'felt_3d_polaroid',
|
||||||
{ label: '水彩插图', value: 'watercolor_illustration' },
|
preview: '/images/jimeng/templates/felt_3d_polaroid.png',
|
||||||
|
},
|
||||||
|
{ label: '像素世界风', value: 'my_world', preview: '/images/jimeng/templates/my_world.png' },
|
||||||
|
{
|
||||||
|
label: '像素世界-万物通用版',
|
||||||
|
value: 'my_world_universal',
|
||||||
|
preview: '/images/jimeng/templates/my_world_universal.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '盲盒玩偶风',
|
||||||
|
value: 'plastic_bubble_figure',
|
||||||
|
preview: '/images/jimeng/templates/plastic_bubble_figure.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '塑料泡罩人偶-文字卡头版',
|
||||||
|
value: 'plastic_bubble_figure_cartoon_text',
|
||||||
|
preview: '/images/jimeng/templates/plastic_bubble_figure_cartoon_text.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '毛绒玩偶风',
|
||||||
|
value: 'furry_dream_doll',
|
||||||
|
preview: '/images/jimeng/templates/furry_dream_doll.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '迷你世界玩偶风',
|
||||||
|
value: 'micro_landscape_mini_world',
|
||||||
|
preview: '/images/jimeng/templates/micro_landscape_mini_world.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '微型景观小世界-职业版',
|
||||||
|
value: 'micro_landscape_mini_world_professional',
|
||||||
|
preview: '/images/jimeng/templates/micro_landscape_mini_world_professional.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '亚克力挂饰',
|
||||||
|
value: 'acrylic_ornaments',
|
||||||
|
preview: '/images/jimeng/templates/acrylic_ornaments.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '毛毡钥匙扣',
|
||||||
|
value: 'felt_keychain',
|
||||||
|
preview: '/images/jimeng/templates/felt_keychain.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Lofi 像素人物小卡',
|
||||||
|
value: 'lofi_pixel_character_mini_card',
|
||||||
|
preview: '/images/jimeng/templates/lofi_pixel_character_mini_card.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '天使形象手办',
|
||||||
|
value: 'angel_figurine',
|
||||||
|
preview: '/images/jimeng/templates/angel_figurine.png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '躺在毛茸茸肚皮里',
|
||||||
|
value: 'lying_in_fluffy_belly',
|
||||||
|
preview: '/images/jimeng/templates/lying_in_fluffy_belly.png',
|
||||||
|
},
|
||||||
|
{ label: '玻璃球', value: 'glass_ball', preview: '/images/jimeng/templates/glass_ball.png' },
|
||||||
]
|
]
|
||||||
|
|
||||||
// 功能参数
|
// 功能参数
|
||||||
|
|||||||
@@ -1,8 +1,221 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="audio-chat-page">
|
<div class="audio-chat-page">
|
||||||
<el-button style="margin: 20px" type="primary" size="large" @click="connect()"
|
<!-- 图像特效 -->
|
||||||
>开始语音对话</el-button
|
<div class="jimeng-create__function-panel">
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">上传图片:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<div class="jimeng-create__upload">
|
||||||
|
<input
|
||||||
|
ref="imageEffectsInput"
|
||||||
|
type="file"
|
||||||
|
accept=".jpg,.png,.jpeg"
|
||||||
|
@change="
|
||||||
|
(e) =>
|
||||||
|
jimengStore.onImageUpload({
|
||||||
|
file: e.target.files[0],
|
||||||
|
name: e.target.files[0]?.name,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
class="hidden"
|
||||||
|
/>
|
||||||
|
<div @click="$refs.imageEffectsInput?.click()" class="jimeng-create__upload-content">
|
||||||
|
<i
|
||||||
|
v-if="!jimengStore.imageEffectsParams.image_input1.length"
|
||||||
|
class="jimeng-create__upload-icon iconfont icon-upload"
|
||||||
|
></i>
|
||||||
|
<span
|
||||||
|
v-if="!jimengStore.imageEffectsParams.image_input1.length"
|
||||||
|
class="jimeng-create__upload-text"
|
||||||
|
>上传图片</span
|
||||||
|
>
|
||||||
|
<div v-else class="jimeng-create__upload-preview">
|
||||||
|
<el-image
|
||||||
|
:src="
|
||||||
|
jimengStore.imageEffectsParams.image_input1[0]?.url ||
|
||||||
|
jimengStore.imageEffectsParams.image_input1[0]?.content
|
||||||
|
"
|
||||||
|
fit="cover"
|
||||||
|
class="w-32 h-32 rounded"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
@click.stop="jimengStore.imageEffectsParams.image_input1 = []"
|
||||||
|
class="jimeng-create__upload-remove-btn"
|
||||||
|
>
|
||||||
|
<i class="iconfont icon-close"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">特效模板:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<CustomSelect
|
||||||
|
v-model="jimengStore.imageEffectsParams.template_id"
|
||||||
|
:options="
|
||||||
|
jimengStore.imageEffectsTemplateOptions.map((opt) => ({
|
||||||
|
label: opt.label,
|
||||||
|
value: opt.value,
|
||||||
|
}))
|
||||||
|
"
|
||||||
|
label="特效模板"
|
||||||
|
title="选择特效模板"
|
||||||
|
@update:modelValue="handleTemplateChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">输出尺寸:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<CustomSelect
|
||||||
|
v-model="jimengStore.imageEffectsParams.size"
|
||||||
|
:options="
|
||||||
|
jimengStore.imageSizeOptions.map((opt) => ({
|
||||||
|
label: opt.label,
|
||||||
|
value: opt.value,
|
||||||
|
}))
|
||||||
|
"
|
||||||
|
label="输出尺寸"
|
||||||
|
title="选择尺寸"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 文生视频 -->
|
||||||
|
<div
|
||||||
|
v-if="jimengStore.activeFunction === 'text_to_video'"
|
||||||
|
class="jimeng-create__function-panel"
|
||||||
>
|
>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">提示词:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<textarea
|
||||||
|
v-model="jimengStore.currentPrompt"
|
||||||
|
placeholder="描述你想要的视频内容"
|
||||||
|
class="jimeng-create__form-section-textarea"
|
||||||
|
rows="4"
|
||||||
|
maxlength="2000"
|
||||||
|
/>
|
||||||
|
<div class="jimeng-create__form-section-counter">
|
||||||
|
<span>{{ jimengStore.currentPrompt.length }}/2000</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">视频比例:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<CustomSelect
|
||||||
|
v-model="jimengStore.textToVideoParams.aspect_ratio"
|
||||||
|
:options="
|
||||||
|
jimengStore.videoAspectRatioOptions.map((opt) => ({
|
||||||
|
label: opt.label,
|
||||||
|
value: opt.value,
|
||||||
|
}))
|
||||||
|
"
|
||||||
|
label="视频比例"
|
||||||
|
title="选择比例"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 图生视频 -->
|
||||||
|
<div
|
||||||
|
v-if="jimengStore.activeFunction === 'image_to_video'"
|
||||||
|
class="jimeng-create__function-panel"
|
||||||
|
>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">上传图片:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<div class="jimeng-create__upload">
|
||||||
|
<input
|
||||||
|
ref="imageToVideoInput"
|
||||||
|
type="file"
|
||||||
|
accept=".jpg,.png,.jpeg"
|
||||||
|
multiple
|
||||||
|
@change="(e) => jimengStore.handleMultipleImageUpload(e)"
|
||||||
|
class="hidden"
|
||||||
|
/>
|
||||||
|
<div @click="$refs.imageToVideoInput?.click()" class="jimeng-create__upload-content">
|
||||||
|
<i
|
||||||
|
v-if="!jimengStore.imageToVideoParams.image_urls.length"
|
||||||
|
class="jimeng-create__upload-icon iconfont icon-upload"
|
||||||
|
></i>
|
||||||
|
<span
|
||||||
|
v-if="!jimengStore.imageToVideoParams.image_urls.length"
|
||||||
|
class="jimeng-create__upload-text"
|
||||||
|
>上传图片</span
|
||||||
|
>
|
||||||
|
<div v-else class="jimeng-create__upload-multiple">
|
||||||
|
<div
|
||||||
|
v-for="(image, index) in jimengStore.imageToVideoParams.image_urls"
|
||||||
|
:key="index"
|
||||||
|
class="jimeng-create__upload-multiple-item"
|
||||||
|
>
|
||||||
|
<el-image
|
||||||
|
:src="image?.url || image?.content"
|
||||||
|
fit="cover"
|
||||||
|
class="w-24 h-24 rounded"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
@click.stop="jimengStore.removeImage(index)"
|
||||||
|
class="jimeng-create__upload-remove-btn"
|
||||||
|
>
|
||||||
|
<i class="iconfont icon-close"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="jimengStore.imageToVideoParams.image_urls.length < 2"
|
||||||
|
@click.stop="$refs.imageToVideoInput?.click()"
|
||||||
|
class="jimeng-create__upload-multiple-add"
|
||||||
|
>
|
||||||
|
<i class="iconfont icon-plus"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">提示词:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<textarea
|
||||||
|
v-model="jimengStore.currentPrompt"
|
||||||
|
placeholder="描述你想要的视频效果"
|
||||||
|
class="jimeng-create__form-section-textarea"
|
||||||
|
rows="4"
|
||||||
|
maxlength="2000"
|
||||||
|
/>
|
||||||
|
<div class="jimeng-create__form-section-counter">
|
||||||
|
<span>{{ jimengStore.currentPrompt.length }}/2000</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<span class="jimeng-create__param-label">视频比例:</span>
|
||||||
|
</div>
|
||||||
|
<div class="jimeng-create__param-line">
|
||||||
|
<CustomSelect
|
||||||
|
v-model="jimengStore.imageToVideoParams.aspect_ratio"
|
||||||
|
:options="
|
||||||
|
jimengStore.videoAspectRatioOptions.map((opt) => ({
|
||||||
|
label: opt.label,
|
||||||
|
value: opt.value,
|
||||||
|
}))
|
||||||
|
"
|
||||||
|
label="视频比例"
|
||||||
|
title="选择比例"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -16,33 +16,39 @@
|
|||||||
|
|
||||||
<!-- 功能分类选择 -->
|
<!-- 功能分类选择 -->
|
||||||
<div class="jimeng-create__content">
|
<div class="jimeng-create__content">
|
||||||
<div class="jimeng-create__category-section">
|
<CustomTabs
|
||||||
<CustomTabs
|
v-model="jimengStore.activeCategory"
|
||||||
v-model="jimengStore.activeCategory"
|
@update:modelValue="jimengStore.switchCategory"
|
||||||
@update:modelValue="jimengStore.switchCategory"
|
>
|
||||||
|
<CustomTabPane
|
||||||
|
:label="jimengStore.categories[0].name"
|
||||||
|
:name="jimengStore.categories[0].key"
|
||||||
>
|
>
|
||||||
<CustomTabPane
|
<template #label>
|
||||||
v-for="category in jimengStore.categories"
|
<span>{{ jimengStore.categories[0].name }}</span>
|
||||||
:key="category.key"
|
</template>
|
||||||
:label="category.name"
|
|
||||||
:name="category.key"
|
<!-- 参数容器 -->
|
||||||
>
|
<div class="py-3">
|
||||||
<template #label>
|
<!-- 文生图 -->
|
||||||
<span>{{ category.name }}</span>
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
</template>
|
<div class="mb-3">
|
||||||
|
<label class="text-gray-700 font-semibold">提示词:</label>
|
||||||
|
</div>
|
||||||
|
<el-input
|
||||||
|
v-model="jimengStore.currentPrompt"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="请输入图片描述,越详细越好"
|
||||||
|
:rows="4"
|
||||||
|
maxlength="2000"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 功能开关 -->
|
<!-- 功能开关 -->
|
||||||
<div
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
class="jimeng-create__mode-section"
|
<div class="flex justify-between items-center w-full">
|
||||||
v-if="category.key === 'image_generation' || category.key === 'video_generation'"
|
<span class="text-gray-700 font-semibold">图生图人像写真</span>
|
||||||
>
|
|
||||||
<div class="jimeng-create__mode-section-content">
|
|
||||||
<div>
|
|
||||||
<span class="jimeng-create__mode-section-title">生成模式</span>
|
|
||||||
<p class="jimeng-create__mode-section-description">
|
|
||||||
{{ category.key === 'image_generation' ? '图生图人像写真' : '图生视频' }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="jimengStore.useImageInput"
|
v-model="jimengStore.useImageInput"
|
||||||
@change="jimengStore.switchInputMode"
|
@change="jimengStore.switchInputMode"
|
||||||
@@ -51,485 +57,215 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 参数容器 -->
|
<!-- 图生图参数 -->
|
||||||
<div class="jimeng-create__params-container">
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3" v-if="jimengStore.useImageInput">
|
||||||
<!-- 文生图 -->
|
<ImageUpload
|
||||||
<div
|
v-model="jimengStore.imageToImageParams.image_input[0]"
|
||||||
v-if="jimengStore.activeFunction === 'text_to_image'"
|
:max-count="1"
|
||||||
class="jimeng-create__function-panel"
|
:multiple="false"
|
||||||
>
|
/>
|
||||||
<div class="jimeng-create__param-line">
|
</div>
|
||||||
<span class="jimeng-create__param-label">提示词:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<textarea
|
|
||||||
v-model="jimengStore.currentPrompt"
|
|
||||||
placeholder="请输入图片描述,越详细越好"
|
|
||||||
class="jimeng-create__form-section-textarea"
|
|
||||||
rows="4"
|
|
||||||
maxlength="2000"
|
|
||||||
/>
|
|
||||||
<div class="jimeng-create__form-section-counter">
|
|
||||||
<span>{{ jimengStore.currentPrompt.length }}/2000</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
<span class="jimeng-create__param-label">图片尺寸:</span>
|
<label class="block text-gray-700 mb-3 font-semibold">图片尺寸:</label>
|
||||||
</div>
|
<CustomSelect
|
||||||
<div class="jimeng-create__param-line">
|
v-model="jimengStore.textToImageParams.size"
|
||||||
<CustomSelect
|
:options="jimengStore.imageSizeOptions"
|
||||||
v-model="jimengStore.textToImageParams.size"
|
title="选择尺寸"
|
||||||
:options="
|
/>
|
||||||
jimengStore.imageSizeOptions.map((opt) => ({
|
</div>
|
||||||
label: opt.label,
|
|
||||||
value: opt.value,
|
|
||||||
}))
|
|
||||||
"
|
|
||||||
label="图片尺寸"
|
|
||||||
title="选择尺寸"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
<span class="jimeng-create__param-label">
|
<span class="flex justify-between items-center mb-3">
|
||||||
创意度
|
<span class="text-gray-700 font-semibold">创意度:</span>
|
||||||
<el-tooltip content="创意度越高,影响文本描述的程度越高" placement="top">
|
<el-tooltip content="创意度越高,影响文本描述的程度越高" placement="top">
|
||||||
<i class="iconfont icon-info cursor-pointer ml-1"></i>
|
<i class="iconfont icon-info cursor-pointer ml-1"></i>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<el-slider
|
|
||||||
v-model="jimengStore.textToImageParams.scale"
|
|
||||||
:min="1"
|
|
||||||
:max="10"
|
|
||||||
:step="0.5"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
<div class="mt-3">
|
||||||
<div class="jimeng-create__switch-section">
|
<el-slider
|
||||||
<span class="jimeng-create__param-label">智能优化提示词</span>
|
v-model="jimengStore.textToImageParams.scale"
|
||||||
<el-switch v-model="jimengStore.textToImageParams.use_pre_llm" size="default" />
|
:min="1"
|
||||||
</div>
|
:max="10"
|
||||||
</div>
|
:step="0.5"
|
||||||
</div>
|
/>
|
||||||
|
|
||||||
<!-- 图生图 -->
|
|
||||||
<div
|
|
||||||
v-if="jimengStore.activeFunction === 'image_to_image'"
|
|
||||||
class="jimeng-create__function-panel"
|
|
||||||
>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">上传图片:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<div class="jimeng-create__upload">
|
|
||||||
<input
|
|
||||||
ref="imageToImageInput"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg,.png,.jpeg"
|
|
||||||
@change="
|
|
||||||
(e) =>
|
|
||||||
jimengStore.onImageUpload({
|
|
||||||
file: e.target.files[0],
|
|
||||||
name: e.target.files[0]?.name,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
class="hidden"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
@click="$refs.imageToImageInput?.click()"
|
|
||||||
class="jimeng-create__upload-content"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
v-if="!jimengStore.imageToImageParams.image_input.length"
|
|
||||||
class="jimeng-create__upload-icon iconfont icon-upload"
|
|
||||||
></i>
|
|
||||||
<span
|
|
||||||
v-if="!jimengStore.imageToImageParams.image_input.length"
|
|
||||||
class="jimeng-create__upload-text"
|
|
||||||
>上传图片</span
|
|
||||||
>
|
|
||||||
<div v-else class="jimeng-create__upload-preview">
|
|
||||||
<el-image
|
|
||||||
:src="
|
|
||||||
jimengStore.imageToImageParams.image_input[0]?.url ||
|
|
||||||
jimengStore.imageToImageParams.image_input[0]?.content
|
|
||||||
"
|
|
||||||
fit="cover"
|
|
||||||
class="w-32 h-32 rounded"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
@click.stop="jimengStore.imageToImageParams.image_input = []"
|
|
||||||
class="jimeng-create__upload-remove-btn"
|
|
||||||
>
|
|
||||||
<i class="iconfont icon-close"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">提示词:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<textarea
|
|
||||||
v-model="jimengStore.currentPrompt"
|
|
||||||
placeholder="描述你想要的图片效果"
|
|
||||||
class="jimeng-create__form-section-textarea"
|
|
||||||
rows="4"
|
|
||||||
maxlength="2000"
|
|
||||||
/>
|
|
||||||
<div class="jimeng-create__form-section-counter">
|
|
||||||
<span>{{ jimengStore.currentPrompt.length }}/2000</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">图片尺寸:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<CustomSelect
|
|
||||||
v-model="jimengStore.imageToImageParams.size"
|
|
||||||
:options="
|
|
||||||
jimengStore.imageSizeOptions.map((opt) => ({
|
|
||||||
label: opt.label,
|
|
||||||
value: opt.value,
|
|
||||||
}))
|
|
||||||
"
|
|
||||||
label="图片尺寸"
|
|
||||||
title="选择尺寸"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 图像编辑 -->
|
|
||||||
<div
|
|
||||||
v-if="jimengStore.activeFunction === 'image_edit'"
|
|
||||||
class="jimeng-create__function-panel"
|
|
||||||
>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">上传图片:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<div class="jimeng-create__upload">
|
|
||||||
<input
|
|
||||||
ref="imageEditInput"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg,.png,.jpeg"
|
|
||||||
@change="
|
|
||||||
(e) =>
|
|
||||||
jimengStore.onImageUpload({
|
|
||||||
file: e.target.files[0],
|
|
||||||
name: e.target.files[0]?.name,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
class="hidden"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
@click="$refs.imageEditInput?.click()"
|
|
||||||
class="jimeng-create__upload-content"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
v-if="!jimengStore.imageEditParams.image_urls.length"
|
|
||||||
class="jimeng-create__upload-icon iconfont icon-upload"
|
|
||||||
></i>
|
|
||||||
<span
|
|
||||||
v-if="!jimengStore.imageEditParams.image_urls.length"
|
|
||||||
class="jimeng-create__upload-text"
|
|
||||||
>上传图片</span
|
|
||||||
>
|
|
||||||
<div v-else class="jimeng-create__upload-preview">
|
|
||||||
<el-image
|
|
||||||
:src="
|
|
||||||
jimengStore.imageEditParams.image_urls[0]?.url ||
|
|
||||||
jimengStore.imageEditParams.image_urls[0]?.content
|
|
||||||
"
|
|
||||||
fit="cover"
|
|
||||||
class="w-32 h-32 rounded"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
@click.stop="jimengStore.imageEditParams.image_urls = []"
|
|
||||||
class="jimeng-create__upload-remove-btn"
|
|
||||||
>
|
|
||||||
<i class="iconfont icon-close"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">编辑提示词:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<textarea
|
|
||||||
v-model="jimengStore.currentPrompt"
|
|
||||||
placeholder="描述你想要的编辑效果"
|
|
||||||
class="jimeng-create__form-section-textarea"
|
|
||||||
rows="4"
|
|
||||||
maxlength="2000"
|
|
||||||
/>
|
|
||||||
<div class="jimeng-create__form-section-counter">
|
|
||||||
<span>{{ jimengStore.currentPrompt.length }}/2000</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">编辑强度:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<el-slider
|
|
||||||
v-model="jimengStore.imageEditParams.scale"
|
|
||||||
:min="0"
|
|
||||||
:max="1"
|
|
||||||
:step="0.1"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 图像特效 -->
|
|
||||||
<div
|
|
||||||
v-if="jimengStore.activeFunction === 'image_effects'"
|
|
||||||
class="jimeng-create__function-panel"
|
|
||||||
>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">上传图片:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<div class="jimeng-create__upload">
|
|
||||||
<input
|
|
||||||
ref="imageEffectsInput"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg,.png,.jpeg"
|
|
||||||
@change="
|
|
||||||
(e) =>
|
|
||||||
jimengStore.onImageUpload({
|
|
||||||
file: e.target.files[0],
|
|
||||||
name: e.target.files[0]?.name,
|
|
||||||
})
|
|
||||||
"
|
|
||||||
class="hidden"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
@click="$refs.imageEffectsInput?.click()"
|
|
||||||
class="jimeng-create__upload-content"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
v-if="!jimengStore.imageEffectsParams.image_input1.length"
|
|
||||||
class="jimeng-create__upload-icon iconfont icon-upload"
|
|
||||||
></i>
|
|
||||||
<span
|
|
||||||
v-if="!jimengStore.imageEffectsParams.image_input1.length"
|
|
||||||
class="jimeng-create__upload-text"
|
|
||||||
>上传图片</span
|
|
||||||
>
|
|
||||||
<div v-else class="jimeng-create__upload-preview">
|
|
||||||
<el-image
|
|
||||||
:src="
|
|
||||||
jimengStore.imageEffectsParams.image_input1[0]?.url ||
|
|
||||||
jimengStore.imageEffectsParams.image_input1[0]?.content
|
|
||||||
"
|
|
||||||
fit="cover"
|
|
||||||
class="w-32 h-32 rounded"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
@click.stop="jimengStore.imageEffectsParams.image_input1 = []"
|
|
||||||
class="jimeng-create__upload-remove-btn"
|
|
||||||
>
|
|
||||||
<i class="iconfont icon-close"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">特效模板:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<CustomSelect
|
|
||||||
v-model="jimengStore.imageEffectsParams.template_id"
|
|
||||||
:options="
|
|
||||||
jimengStore.imageEffectsTemplateOptions.map((opt) => ({
|
|
||||||
label: opt.label,
|
|
||||||
value: opt.value,
|
|
||||||
}))
|
|
||||||
"
|
|
||||||
label="特效模板"
|
|
||||||
title="选择特效模板"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">输出尺寸:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<CustomSelect
|
|
||||||
v-model="jimengStore.imageEffectsParams.size"
|
|
||||||
:options="
|
|
||||||
jimengStore.imageSizeOptions.map((opt) => ({
|
|
||||||
label: opt.label,
|
|
||||||
value: opt.value,
|
|
||||||
}))
|
|
||||||
"
|
|
||||||
label="输出尺寸"
|
|
||||||
title="选择尺寸"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 文生视频 -->
|
|
||||||
<div
|
|
||||||
v-if="jimengStore.activeFunction === 'text_to_video'"
|
|
||||||
class="jimeng-create__function-panel"
|
|
||||||
>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">提示词:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<textarea
|
|
||||||
v-model="jimengStore.currentPrompt"
|
|
||||||
placeholder="描述你想要的视频内容"
|
|
||||||
class="jimeng-create__form-section-textarea"
|
|
||||||
rows="4"
|
|
||||||
maxlength="2000"
|
|
||||||
/>
|
|
||||||
<div class="jimeng-create__form-section-counter">
|
|
||||||
<span>{{ jimengStore.currentPrompt.length }}/2000</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">视频比例:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<CustomSelect
|
|
||||||
v-model="jimengStore.textToVideoParams.aspect_ratio"
|
|
||||||
:options="
|
|
||||||
jimengStore.videoAspectRatioOptions.map((opt) => ({
|
|
||||||
label: opt.label,
|
|
||||||
value: opt.value,
|
|
||||||
}))
|
|
||||||
"
|
|
||||||
label="视频比例"
|
|
||||||
title="选择比例"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 图生视频 -->
|
|
||||||
<div
|
|
||||||
v-if="jimengStore.activeFunction === 'image_to_video'"
|
|
||||||
class="jimeng-create__function-panel"
|
|
||||||
>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">上传图片:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<div class="jimeng-create__upload">
|
|
||||||
<input
|
|
||||||
ref="imageToVideoInput"
|
|
||||||
type="file"
|
|
||||||
accept=".jpg,.png,.jpeg"
|
|
||||||
multiple
|
|
||||||
@change="(e) => jimengStore.handleMultipleImageUpload(e)"
|
|
||||||
class="hidden"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
@click="$refs.imageToVideoInput?.click()"
|
|
||||||
class="jimeng-create__upload-content"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
v-if="!jimengStore.imageToVideoParams.image_urls.length"
|
|
||||||
class="jimeng-create__upload-icon iconfont icon-upload"
|
|
||||||
></i>
|
|
||||||
<span
|
|
||||||
v-if="!jimengStore.imageToVideoParams.image_urls.length"
|
|
||||||
class="jimeng-create__upload-text"
|
|
||||||
>上传图片</span
|
|
||||||
>
|
|
||||||
<div v-else class="jimeng-create__upload-multiple">
|
|
||||||
<div
|
|
||||||
v-for="(image, index) in jimengStore.imageToVideoParams.image_urls"
|
|
||||||
:key="index"
|
|
||||||
class="jimeng-create__upload-multiple-item"
|
|
||||||
>
|
|
||||||
<el-image
|
|
||||||
:src="image?.url || image?.content"
|
|
||||||
fit="cover"
|
|
||||||
class="w-24 h-24 rounded"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
@click.stop="jimengStore.removeImage(index)"
|
|
||||||
class="jimeng-create__upload-remove-btn"
|
|
||||||
>
|
|
||||||
<i class="iconfont icon-close"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="jimengStore.imageToVideoParams.image_urls.length < 2"
|
|
||||||
@click.stop="$refs.imageToVideoInput?.click()"
|
|
||||||
class="jimeng-create__upload-multiple-add"
|
|
||||||
>
|
|
||||||
<i class="iconfont icon-plus"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">提示词:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<textarea
|
|
||||||
v-model="jimengStore.currentPrompt"
|
|
||||||
placeholder="描述你想要的视频效果"
|
|
||||||
class="jimeng-create__form-section-textarea"
|
|
||||||
rows="4"
|
|
||||||
maxlength="2000"
|
|
||||||
/>
|
|
||||||
<div class="jimeng-create__form-section-counter">
|
|
||||||
<span>{{ jimengStore.currentPrompt.length }}/2000</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<span class="jimeng-create__param-label">视频比例:</span>
|
|
||||||
</div>
|
|
||||||
<div class="jimeng-create__param-line">
|
|
||||||
<CustomSelect
|
|
||||||
v-model="jimengStore.imageToVideoParams.aspect_ratio"
|
|
||||||
:options="
|
|
||||||
jimengStore.videoAspectRatioOptions.map((opt) => ({
|
|
||||||
label: opt.label,
|
|
||||||
value: opt.value,
|
|
||||||
}))
|
|
||||||
"
|
|
||||||
label="视频比例"
|
|
||||||
title="选择比例"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 提交按钮 -->
|
|
||||||
<div class="jimeng-create__submit-btn">
|
|
||||||
<button @click="jimengStore.submitTask" :disabled="jimengStore.submitting">
|
|
||||||
<i v-if="jimengStore.submitting" class="iconfont icon-loading animate-spin"></i>
|
|
||||||
<span>{{
|
|
||||||
jimengStore.submitting
|
|
||||||
? '创作中...'
|
|
||||||
: `立即生成 (${jimengStore.currentPowerCost}算力)`
|
|
||||||
}}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CustomTabPane>
|
|
||||||
</CustomTabs>
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="flex justify-between items-center w-full">
|
||||||
|
<label class="text-gray-700 font-semibold">智能优化提示词</label>
|
||||||
|
<el-switch v-model="jimengStore.textToImageParams.use_pre_llm" size="default" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CustomTabPane>
|
||||||
|
|
||||||
|
<CustomTabPane
|
||||||
|
:name="jimengStore.categories[1].key"
|
||||||
|
:label="jimengStore.categories[1].name"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span>{{ jimengStore.categories[1].name }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="py-3">
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="text-gray-700 font-semibold">编辑提示词:</label>
|
||||||
|
</div>
|
||||||
|
<el-input
|
||||||
|
v-model="jimengStore.currentPrompt"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="描述你想要的编辑效果"
|
||||||
|
:rows="4"
|
||||||
|
maxlength="2000"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<ImageUpload
|
||||||
|
v-model="jimengStore.imageEditParams.image_input"
|
||||||
|
:max-count="1"
|
||||||
|
:multiple="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="text-gray-700 font-semibold">编辑强度:</label>
|
||||||
|
</div>
|
||||||
|
<el-slider
|
||||||
|
v-model="jimengStore.imageEditParams.scale"
|
||||||
|
:min="0"
|
||||||
|
:max="1"
|
||||||
|
:step="0.1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CustomTabPane>
|
||||||
|
|
||||||
|
<CustomTabPane
|
||||||
|
:name="jimengStore.categories[2].key"
|
||||||
|
:label="jimengStore.categories[2].name"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span>{{ jimengStore.categories[2].name }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="py-3">
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<ImageUpload
|
||||||
|
v-model="jimengStore.imageEffectsParams.image_input"
|
||||||
|
:max-count="1"
|
||||||
|
:multiple="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="text-gray-700 font-semibold">特效模板:</label>
|
||||||
|
</div>
|
||||||
|
<CustomSelect
|
||||||
|
v-model="jimengStore.imageEffectsParams.template_id"
|
||||||
|
:options="jimengStore.imageEffectsTemplateOptions"
|
||||||
|
title="选择模板"
|
||||||
|
>
|
||||||
|
<template #option="{ option, selected }">
|
||||||
|
<div class="flex items-center w-full">
|
||||||
|
<el-image :src="option.preview" fit="cover" class="w-10 h-10 rounded-lg mr-2" />
|
||||||
|
<span class="font-bold text-blue-600 mr-2">{{ option.label }}</span>
|
||||||
|
<span v-if="selected" class="ml-auto text-green-500"
|
||||||
|
><i class="iconfont icon-success"></i
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</CustomSelect>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="text-gray-700 font-semibold">输出尺寸:</label>
|
||||||
|
</div>
|
||||||
|
<CustomSelect
|
||||||
|
v-model="jimengStore.imageEffectsParams.size"
|
||||||
|
:options="jimengStore.imageSizeOptions"
|
||||||
|
title="选择尺寸"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CustomTabPane>
|
||||||
|
|
||||||
|
<CustomTabPane
|
||||||
|
:name="jimengStore.categories[3].key"
|
||||||
|
:label="jimengStore.categories[3].name"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span>{{ jimengStore.categories[3].name }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="py-3">
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="text-gray-700 font-semibold">提示词:</label>
|
||||||
|
</div>
|
||||||
|
<el-input
|
||||||
|
v-model="jimengStore.currentPrompt"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="请输入你想要的视频效果"
|
||||||
|
:rows="4"
|
||||||
|
maxlength="2000"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="flex justify-between items-center w-full">
|
||||||
|
<label class="text-gray-700 font-semibold">使用图片辅助生成:</label>
|
||||||
|
<el-switch v-model="jimengStore.textToVideoParams.use_image_input" size="default" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bg-white rounded-xl p-4 shadow-sm mb-3"
|
||||||
|
v-if="jimengStore.textToVideoParams.use_image_input"
|
||||||
|
>
|
||||||
|
<ImageUpload
|
||||||
|
v-model="jimengStore.textToVideoParams.image_input"
|
||||||
|
:max-count="2"
|
||||||
|
:multiple="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="text-gray-700 font-semibold">视频比例:</label>
|
||||||
|
</div>
|
||||||
|
<CustomSelect
|
||||||
|
v-model="jimengStore.textToVideoParams.aspect_ratio"
|
||||||
|
:options="jimengStore.videoAspectRatioOptions"
|
||||||
|
title="选择比例"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CustomTabPane>
|
||||||
|
</CustomTabs>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<div class="bg-white rounded-xl p-4 shadow-sm mb-3">
|
||||||
|
<button
|
||||||
|
class="w-full py-3 bg-gradient-to-r from-blue-500 to-purple-600 text-white rounded-xl disabled:from-gray-400 disabled:to-gray-400 disabled:cursor-not-allowed hover:from-blue-600 hover:to-purple-700 transition-all duration-200 flex items-center justify-center space-x-2 text-base"
|
||||||
|
@click="jimengStore.submitTask"
|
||||||
|
:disabled="jimengStore.submitting"
|
||||||
|
>
|
||||||
|
<i v-if="jimengStore.submitting" class="iconfont icon-loading animate-spin"></i>
|
||||||
|
<i v-else class="iconfont icon-chuangzuo"></i>
|
||||||
|
<span>{{
|
||||||
|
jimengStore.submitting ? '创作中...' : `立即生成 (${jimengStore.currentPowerCost}算力)`
|
||||||
|
}}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -748,17 +484,33 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import ImageUpload from '@/components/ImageUpload.vue'
|
||||||
import CustomSelect from '@/components/mobile/CustomSelect.vue'
|
import CustomSelect from '@/components/mobile/CustomSelect.vue'
|
||||||
import CustomTabPane from '@/components/ui/CustomTabPane.vue'
|
import CustomTabPane from '@/components/ui/CustomTabPane.vue'
|
||||||
import CustomTabs from '@/components/ui/CustomTabs.vue'
|
import CustomTabs from '@/components/ui/CustomTabs.vue'
|
||||||
import { checkSession } from '@/store/cache'
|
import { checkSession } from '@/store/cache'
|
||||||
import { useJimengStore } from '@/store/mobile/jimeng'
|
import { useJimengStore } from '@/store/mobile/jimeng'
|
||||||
import { onMounted, onUnmounted } from 'vue'
|
import { onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const jimengStore = useJimengStore()
|
const jimengStore = useJimengStore()
|
||||||
|
|
||||||
|
// 模板预览相关
|
||||||
|
const templatePreview = ref('')
|
||||||
|
|
||||||
|
// 处理模板变更
|
||||||
|
const handleTemplateChange = (value) => {
|
||||||
|
const selectedTemplate = jimengStore.imageEffectsTemplateOptions.find(
|
||||||
|
(opt) => opt.value === value
|
||||||
|
)
|
||||||
|
if (selectedTemplate) {
|
||||||
|
templatePreview.value = selectedTemplate.preview || ''
|
||||||
|
// 自动设置提示词为模板名称
|
||||||
|
jimengStore.currentPrompt = selectedTemplate.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 生命周期
|
// 生命周期
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
checkSession()
|
checkSession()
|
||||||
|
|||||||
@@ -30,23 +30,25 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 模型选择 -->
|
<!-- 模型选择 -->
|
||||||
<CustomSelect
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
v-model="suno.data.model"
|
<label class="block text-gray-700 font-medium mb-3">模型版本:</label>
|
||||||
:options="suno.models"
|
<CustomSelect
|
||||||
label="模型版本"
|
v-model="suno.data.model"
|
||||||
title="选择模型"
|
:options="suno.models"
|
||||||
@change="suno.onModelSelect"
|
title="选择模型"
|
||||||
>
|
@change="suno.onModelSelect"
|
||||||
<template #option="{ option, selected }">
|
>
|
||||||
<div class="flex items-center w-full">
|
<template #option="{ option, selected }">
|
||||||
<span class="font-bold text-blue-600 mr-2">{{ option.label }}</span>
|
<div class="flex items-center w-full">
|
||||||
<span class="text-xs text-gray-400">({{ option.value }})</span>
|
<span class="font-bold text-blue-600 mr-2">{{ option.label }}</span>
|
||||||
<span v-if="selected" class="ml-auto text-green-500"
|
<span class="text-xs text-gray-400">({{ option.value }})</span>
|
||||||
><i class="iconfont icon-success"></i
|
<span v-if="selected" class="ml-auto text-green-500"
|
||||||
></span>
|
><i class="iconfont icon-success"></i
|
||||||
</div>
|
></span>
|
||||||
</template>
|
</div>
|
||||||
</CustomSelect>
|
</template>
|
||||||
|
</CustomSelect>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 纯音乐开关 -->
|
<!-- 纯音乐开关 -->
|
||||||
<div class="bg-white rounded-xl p-4 shadow-sm">
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
|
|||||||
@@ -200,54 +200,62 @@
|
|||||||
<!-- KeLing 视频参数 -->
|
<!-- KeLing 视频参数 -->
|
||||||
<div v-if="video.activeVideoType === 'keling'" class="space-y-6">
|
<div v-if="video.activeVideoType === 'keling'" class="space-y-6">
|
||||||
<!-- 画面比例 -->
|
<!-- 画面比例 -->
|
||||||
<CustomSelect
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
v-model="video.kelingParams.aspect_ratio"
|
<label class="block text-gray-700 font-medium mb-3">画面比例</label>
|
||||||
:options="video.aspectRatioOptions.map((ratio) => ({ label: ratio, value: ratio }))"
|
<CustomSelect
|
||||||
label="画面比例"
|
v-model="video.kelingParams.aspect_ratio"
|
||||||
title="选择比例"
|
:options="video.aspectRatioOptions.map((ratio) => ({ label: ratio, value: ratio }))"
|
||||||
/>
|
title="选择比例"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 模型选择 -->
|
<!-- 模型选择 -->
|
||||||
<CustomSelect
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
v-model="video.kelingParams.model"
|
<label class="block text-gray-700 font-medium mb-3">模型选择</label>
|
||||||
:options="video.modelOptions"
|
<CustomSelect
|
||||||
label="模型选择"
|
v-model="video.kelingParams.model"
|
||||||
placeholder="请选择模型"
|
:options="video.modelOptions"
|
||||||
title="选择模型"
|
placeholder="请选择模型"
|
||||||
>
|
title="选择模型"
|
||||||
<template #option="{ option, selected }">
|
>
|
||||||
<div class="flex items-center w-full">
|
<template #option="{ option, selected }">
|
||||||
<span class="font-bold text-blue-600 mr-2">{{ option.label }}</span>
|
<div class="flex items-center w-full">
|
||||||
<span class="text-xs text-gray-400">({{ option.value }})</span>
|
<span class="font-bold text-blue-600 mr-2">{{ option.label }}</span>
|
||||||
<span v-if="selected" class="ml-auto text-green-500"
|
<span class="text-xs text-gray-400">({{ option.value }})</span>
|
||||||
><i class="iconfont icon-success"></i
|
<span v-if="selected" class="ml-auto text-green-500"
|
||||||
></span>
|
><i class="iconfont icon-success"></i
|
||||||
</div>
|
></span>
|
||||||
</template>
|
</div>
|
||||||
</CustomSelect>
|
</template>
|
||||||
|
</CustomSelect>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 视频时长 -->
|
<!-- 视频时长 -->
|
||||||
<CustomSelect
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
v-model="video.kelingParams.duration"
|
<label class="block text-gray-700 font-medium mb-3">视频时长</label>
|
||||||
:options="
|
<CustomSelect
|
||||||
video.durationOptions.map((duration) => ({ label: `${duration}秒`, value: duration }))
|
v-model="video.kelingParams.duration"
|
||||||
"
|
:options="
|
||||||
label="视频时长"
|
video.durationOptions.map((duration) => ({ label: `${duration}秒`, value: duration }))
|
||||||
title="选择时长"
|
"
|
||||||
/>
|
title="选择时长"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 生成模式 -->
|
<!-- 生成模式 -->
|
||||||
<CustomSelect
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
v-model="video.kelingParams.mode"
|
<label class="block text-gray-700 font-medium mb-3">生成模式</label>
|
||||||
:options="
|
<CustomSelect
|
||||||
video.modeOptions.map((mode) => ({
|
v-model="video.kelingParams.mode"
|
||||||
label: mode === 'std' ? '标准模式' : '专业模式',
|
:options="
|
||||||
value: mode,
|
video.modeOptions.map((mode) => ({
|
||||||
}))
|
label: mode === 'std' ? '标准模式' : '专业模式',
|
||||||
"
|
value: mode,
|
||||||
label="生成模式"
|
}))
|
||||||
title="选择模式"
|
"
|
||||||
/>
|
title="选择模式"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 创意程度 -->
|
<!-- 创意程度 -->
|
||||||
<div class="bg-white rounded-xl p-4 shadow-sm">
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
@@ -258,17 +266,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 运镜控制 -->
|
<!-- 运镜控制 -->
|
||||||
<CustomSelect
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
v-model="video.kelingParams.camera_control.type"
|
<label class="block text-gray-700 font-medium mb-3">运镜控制</label>
|
||||||
:options="
|
<CustomSelect
|
||||||
video.cameraControlOptions.map((option) => ({
|
v-model="video.kelingParams.camera_control.type"
|
||||||
label: video.getCameraControlLabel(option),
|
:options="
|
||||||
value: option,
|
video.cameraControlOptions.map((option) => ({
|
||||||
}))
|
label: video.getCameraControlLabel(option),
|
||||||
"
|
value: option,
|
||||||
label="运镜控制"
|
}))
|
||||||
title="选择运镜类型"
|
"
|
||||||
/>
|
title="选择运镜类型"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 图片辅助生成开关 -->
|
<!-- 图片辅助生成开关 -->
|
||||||
<div class="bg-white rounded-xl p-4 shadow-sm">
|
<div class="bg-white rounded-xl p-4 shadow-sm">
|
||||||
|
|||||||
Reference in New Issue
Block a user