fix: 参数选择改到参数文件
This commit is contained in:
parent
4bba35a426
commit
5ae8614b1d
|
|
@ -3,41 +3,27 @@
|
|||
<header class="vg-hero">
|
||||
<div class="vg-hero-text">
|
||||
<h1 class="vg-hero-title">视频生成</h1>
|
||||
<p class="vg-hero-desc">文生视频、图生视频,选择模型后生成成片</p>
|
||||
</div>
|
||||
<div class="vg-type-select" @click.stop>
|
||||
<span class="vg-hero-mode-label">生成模式</span>
|
||||
<button
|
||||
type="button"
|
||||
class="vg-type-trigger"
|
||||
:class="{ 'is-open': typeMenuOpen }"
|
||||
@click.stop="typeMenuOpen = !typeMenuOpen"
|
||||
:aria-expanded="typeMenuOpen">
|
||||
<span class="vg-type-label">{{ videoModeLabel }}</span>
|
||||
<svg class="vg-type-chevron" width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.01 7.982A1.2 1.2 0 0 1 21 9.679l-8.156 8.06a1.2 1.2 0 0 1-1.688 0L3 9.68a1.2 1.2 0 0 1 1.687-1.707L12 15.199l7.313-7.227a1.2 1.2 0 0 1 1.697.01Z" fill="currentColor" />
|
||||
</svg>
|
||||
</button>
|
||||
<transition name="vg-fade">
|
||||
<div v-show="typeMenuOpen" class="vg-type-dropdown">
|
||||
<div class="vg-type-dropdown-bg" />
|
||||
<ul class="vg-type-options" role="listbox">
|
||||
<li
|
||||
v-for="opt in videoModeOptions"
|
||||
:key="opt.value"
|
||||
:class="['vg-type-option', { active: videoMode === opt.value }]"
|
||||
role="option"
|
||||
@click="pickVideoMode(opt.value)">
|
||||
{{ opt.label }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</transition>
|
||||
<p class="vg-hero-desc">左侧选择生成模式,编辑描述与参考素材后生成成片</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="vg-body">
|
||||
<!-- 左侧:生成器 -->
|
||||
<!-- 最左:生成模式 -->
|
||||
<aside class="vg-left-rail">
|
||||
<p class="vg-rail-title">生成模式</p>
|
||||
<ul class="vg-mode-list" role="list">
|
||||
<li
|
||||
v-for="opt in videoModeOptions"
|
||||
:key="opt.value"
|
||||
:class="['vg-mode-item', { active: videoMode === opt.value }]"
|
||||
role="listitem"
|
||||
@click="pickVideoMode(opt.value)">
|
||||
{{ opt.label }}
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<!-- 中间:生成器 -->
|
||||
<div class="vg-generator">
|
||||
<div class="vg-generator-inner">
|
||||
<!-- 参考上传区(图生视频);文生视频时显示轻量占位 -->
|
||||
|
|
@ -47,39 +33,41 @@
|
|||
<div v-if="isImageVideoMode" class="vg-ref-content">
|
||||
<div class="vg-ref-tilt">
|
||||
<div class="upload-inner">
|
||||
<div class="upload-title">
|
||||
<div class="upload-title-left">
|
||||
{{ imageUploadPrimaryLabel }}
|
||||
<template v-if="videoMode === 'image-reference'">
|
||||
<div class="upload-title">
|
||||
<div class="upload-title-left">参考图</div>
|
||||
<div class="upload-title-tip">
|
||||
请使用下方编辑器工具栏「插入参考素材」添加图片(此处不再单独上传)
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload-title-tip">
|
||||
{{ $t('common.uploadImageTip') || '支持PNG/JPG,最大10MB' }}
|
||||
</div>
|
||||
</div>
|
||||
<mf-image-upload
|
||||
v-if="videoMode !== 'image-reference'"
|
||||
listType="picture-card"
|
||||
uploadHeight="140px"
|
||||
:show-file-list="false"
|
||||
:content="$t('common.uploadFirstPlaceholder') || '点击上传'"
|
||||
v-model="firstUrl" />
|
||||
<mf-image-upload
|
||||
v-else
|
||||
listType="picture-card"
|
||||
uploadHeight="140px"
|
||||
:show-file-list="false"
|
||||
:content="'上传参考图'"
|
||||
v-model="referenceUrl" />
|
||||
<div class="last-frame" v-if="videoMode === 'image-first-last-frame'">
|
||||
<div class="upload-title-left">
|
||||
{{ $t('common.uploadLastPlaceholder') || '尾帧(可选)' }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="upload-title">
|
||||
<div class="upload-title-left">
|
||||
{{ imageUploadPrimaryLabel }}
|
||||
</div>
|
||||
<div class="upload-title-tip">
|
||||
{{ $t('common.uploadImageTip') || '支持PNG/JPG,最大10MB' }}
|
||||
</div>
|
||||
</div>
|
||||
<mf-image-upload
|
||||
listType="picture-card"
|
||||
uploadHeight="100px"
|
||||
uploadHeight="140px"
|
||||
:show-file-list="false"
|
||||
:content="$t('common.uploadLastPlaceholder') || '上传尾帧'"
|
||||
v-model="lastUrl" />
|
||||
</div>
|
||||
:content="$t('common.uploadFirstPlaceholder') || '点击上传'"
|
||||
v-model="firstUrl" />
|
||||
<div class="last-frame" v-if="videoMode === 'image-first-last-frame'">
|
||||
<div class="upload-title-left">
|
||||
{{ $t('common.uploadLastPlaceholder') || '尾帧(可选)' }}
|
||||
</div>
|
||||
<mf-image-upload
|
||||
listType="picture-card"
|
||||
uploadHeight="100px"
|
||||
:show-file-list="false"
|
||||
:content="$t('common.uploadLastPlaceholder') || '上传尾帧'"
|
||||
v-model="lastUrl" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -96,31 +84,54 @@
|
|||
|
||||
<div class="vg-main-column">
|
||||
<div class="rich-editor-container">
|
||||
<RichTextEditor
|
||||
v-model="editorContent"
|
||||
<VideoRichEditor
|
||||
ref="videoRichEditor"
|
||||
:show-toolbar="videoMode !== 'text-to-video'"
|
||||
@text-change="bumpEditorVisualTick"
|
||||
:placeholder="
|
||||
$t('common.textVideoPlaceholder') ||
|
||||
'描述画面与动态,例如:阳光下的女孩在海边起舞…'
|
||||
"
|
||||
:uploaded-images="uploadedImages"
|
||||
@text-change="handleTextChange"
|
||||
@image-upload="handleImageUpload"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="vg-toolbar">
|
||||
<div class="vg-toolbar-settings">
|
||||
<div class="vg-model-wrap">
|
||||
<span class="vg-model-icon" aria-hidden="true">
|
||||
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" d="M11.805 5.786c1.25-.926 2.193-1.373 2.471-1.096.489.488-1.261 3.03-3.909 5.677-4.33 4.331-6.715 8.968-5.326 10.358.29.29.723.416 1.264.394.421.017.92-.07 1.48-.249-2.117.9-3.859 1.005-4.76.104-1.874-1.874.61-7.402 5.553-12.353l.022-.02c.03-.032.062-.063.093-.094l.065-.064.11-.108c.97-.95 1.96-1.804 2.937-2.549Zm5.55 11.57c1.532-1.531 3.2-2.347 3.725-1.822.525.525-.29 2.192-1.822 3.724-1.532 1.531-3.2 2.347-3.725 1.822-.524-.525.291-2.192 1.822-3.724Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<a-select v-model="selectedModel" class="vg-model-select">
|
||||
<a-option v-for="option in modelOptions" :key="option.value" :value="option.value">
|
||||
{{ option.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
<div class="vg-params-row">
|
||||
<div class="vg-param">
|
||||
<span class="vg-param-label">模型</span>
|
||||
<a-select
|
||||
v-model="selectedModel"
|
||||
class="vg-param-select"
|
||||
placeholder="请选择模型"
|
||||
allow-clear>
|
||||
<a-option v-for="opt in modelOptions" :key="opt.value" :value="opt.value">
|
||||
{{ opt.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div class="vg-param">
|
||||
<span class="vg-param-label">比例</span>
|
||||
<a-select v-model="selectedRatio" class="vg-param-select" placeholder="画幅比例" allow-clear>
|
||||
<a-option v-for="r in ratioOptions" :key="r" :value="r">{{ r }}</a-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div class="vg-param">
|
||||
<span class="vg-param-label">时长</span>
|
||||
<a-select v-model="selectedDuration" class="vg-param-select" placeholder="秒" allow-clear>
|
||||
<a-option v-for="d in durationOptions" :key="d" :value="d">{{ d }} 秒</a-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div class="vg-param">
|
||||
<span class="vg-param-label">分辨率</span>
|
||||
<a-select
|
||||
v-model="selectedResolution"
|
||||
class="vg-param-select"
|
||||
placeholder="分辨率"
|
||||
allow-clear>
|
||||
<a-option v-for="r in resolutionOptions" :key="r" :value="r">{{ r }}</a-option>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vg-toolbar-actions">
|
||||
|
|
@ -210,8 +221,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import RichTextEditor from '@/components/RichTextEditor.vue'
|
||||
import VideoRichEditor from '@/components/VideoRichEditor.vue'
|
||||
|
||||
export default {
|
||||
name: 'VideoGen',
|
||||
|
|
@ -227,8 +237,7 @@ export default {
|
|||
],
|
||||
firstUrl: '',
|
||||
lastUrl: '',
|
||||
referenceUrl: '',
|
||||
editorContent: '',
|
||||
editorVisualTick: 0,
|
||||
interval: null,
|
||||
videoUrl: null,
|
||||
videoLoading: false,
|
||||
|
|
@ -237,29 +246,25 @@ export default {
|
|||
showResult: false,
|
||||
price: null,
|
||||
id: null,
|
||||
modelOptions: [
|
||||
{ label: 'Seedance 2.0', value: 'ep-20260326165811-dlkth' },
|
||||
{ label: 'Seedance 2.0 Fast', value: 'ep-20260326170056-dkj9m' }
|
||||
],
|
||||
selectedModel: 'ep-20260326165811-dlkth',
|
||||
uploadedImages: [],
|
||||
modelOptions: [],
|
||||
ratioOptions: [],
|
||||
durationOptions: [],
|
||||
resolutionOptions: [],
|
||||
selectedModel: '',
|
||||
selectedRatio: '',
|
||||
selectedDuration: null,
|
||||
selectedResolution: '',
|
||||
maxPollAttempts: 40,
|
||||
typeMenuOpen: false,
|
||||
taskRows: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
RichTextEditor
|
||||
VideoRichEditor
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['lang']),
|
||||
canCancel() {
|
||||
return !!this.videoId && !this.videoUrl
|
||||
},
|
||||
videoModeLabel() {
|
||||
const o = this.videoModeOptions.find((x) => x.value === this.videoMode)
|
||||
return o ? o.label : '文生视频'
|
||||
},
|
||||
isImageVideoMode() {
|
||||
return this.videoMode !== 'text-to-video'
|
||||
},
|
||||
|
|
@ -269,7 +274,12 @@ export default {
|
|||
return this.$t('common.uploadFirstImage') || '上传首帧'
|
||||
},
|
||||
posterUrl() {
|
||||
const f = this.videoMode === 'image-reference' ? this.referenceUrl : this.firstUrl
|
||||
void this.editorVisualTick
|
||||
if (this.videoMode === 'image-reference') {
|
||||
const url = this.firstReferenceImageUrlFromEditor()
|
||||
return url || ''
|
||||
}
|
||||
const f = this.firstUrl
|
||||
if (!f) return ''
|
||||
return typeof f === 'object' ? (f.url || '') : f
|
||||
}
|
||||
|
|
@ -277,33 +287,39 @@ export default {
|
|||
mounted() {
|
||||
this.loadPriceInfo()
|
||||
this.loadTaskList()
|
||||
document.addEventListener('click', this.onDocClick)
|
||||
this.loadVideoParams()
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.destroyInterval()
|
||||
document.removeEventListener('click', this.onDocClick)
|
||||
},
|
||||
methods: {
|
||||
onDocClick() {
|
||||
this.typeMenuOpen = false
|
||||
plainPromptText() {
|
||||
return this.$refs.videoRichEditor?.getPlainText?.() || ''
|
||||
},
|
||||
|
||||
bumpEditorVisualTick() {
|
||||
this.editorVisualTick++
|
||||
},
|
||||
|
||||
/** 编辑器内插入的参考图 URL(与 getContentItems 一致) */
|
||||
firstReferenceImageUrlFromEditor() {
|
||||
const items = this.$refs.videoRichEditor?.getContentItems?.() || []
|
||||
for (const i of items) {
|
||||
if (i.type === 'image_url' && i.image_url?.url) {
|
||||
if (!i.role || i.role === 'reference_image') return i.image_url.url
|
||||
}
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
pickVideoMode(m) {
|
||||
this.videoMode = m
|
||||
this.firstUrl = ''
|
||||
this.lastUrl = ''
|
||||
this.referenceUrl = ''
|
||||
this.editorContent = ''
|
||||
this.uploadedImages = []
|
||||
this.typeMenuOpen = false
|
||||
},
|
||||
|
||||
plainPromptText() {
|
||||
if (!this.editorContent || !String(this.editorContent).trim()) return ''
|
||||
const s = String(this.editorContent)
|
||||
if (s.indexOf('<') < 0) return s.trim()
|
||||
const d = document.createElement('div')
|
||||
d.innerHTML = s
|
||||
return (d.textContent || d.innerText || '').trim()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.videoRichEditor?.clear?.()
|
||||
this.bumpEditorVisualTick()
|
||||
})
|
||||
},
|
||||
|
||||
async loadTaskList() {
|
||||
|
|
@ -343,27 +359,53 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
handleTextChange(content) {
|
||||
this.editorContent = content
|
||||
},
|
||||
|
||||
handleImageUpload(imageInfo) {
|
||||
if (imageInfo && imageInfo.url) {
|
||||
this.uploadedImages.push({
|
||||
url: imageInfo.url,
|
||||
name: imageInfo.name || 'image'
|
||||
async loadVideoParams() {
|
||||
try {
|
||||
const res = await this.$axios({
|
||||
url: 'api/portal/video/options',
|
||||
method: 'GET'
|
||||
})
|
||||
if (res.code !== 200 || !res.data) return
|
||||
const { defaults, models, ratios, durations, resolutions } = res.data
|
||||
this.modelOptions = Array.isArray(models) ? models : []
|
||||
this.ratioOptions = Array.isArray(ratios) ? ratios : []
|
||||
this.durationOptions = Array.isArray(durations) ? durations.map((n) => Number(n)) : []
|
||||
this.resolutionOptions = Array.isArray(resolutions) ? resolutions : []
|
||||
const d = defaults || {}
|
||||
if (d.model) {
|
||||
this.selectedModel = d.model
|
||||
} else if (this.modelOptions.length) {
|
||||
this.selectedModel = this.modelOptions[0].value
|
||||
}
|
||||
if (d.ratio && this.ratioOptions.includes(d.ratio)) {
|
||||
this.selectedRatio = d.ratio
|
||||
} else if (this.ratioOptions.length) {
|
||||
this.selectedRatio = this.ratioOptions[0]
|
||||
}
|
||||
const durNum = d.duration != null ? Number(d.duration) : null
|
||||
if (durNum != null && this.durationOptions.includes(durNum)) {
|
||||
this.selectedDuration = durNum
|
||||
} else if (this.durationOptions.length) {
|
||||
this.selectedDuration = this.durationOptions[0]
|
||||
}
|
||||
if (d.resolution && this.resolutionOptions.includes(d.resolution)) {
|
||||
this.selectedResolution = d.resolution
|
||||
} else if (this.resolutionOptions.length) {
|
||||
this.selectedResolution = this.resolutionOptions[0]
|
||||
}
|
||||
} catch (_) {
|
||||
this.$message?.warning?.('加载视频参数配置失败')
|
||||
}
|
||||
},
|
||||
|
||||
generateVideo() {
|
||||
const text = this.plainPromptText() || '一个优雅的女孩在阳光下跳舞'
|
||||
const plain = this.plainPromptText()
|
||||
const text = plain || '一个优雅的女孩在阳光下跳舞'
|
||||
|
||||
if (this.isImageVideoMode) {
|
||||
if (this.videoMode === 'image-reference') {
|
||||
const ref = typeof this.referenceUrl === 'object' ? this.referenceUrl?.url : this.referenceUrl
|
||||
if (!ref) {
|
||||
this.$message.error('请上传参考图')
|
||||
if (!this.firstReferenceImageUrlFromEditor()) {
|
||||
this.$message.error('请通过编辑器工具栏「插入参考素材」添加参考图')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
|
@ -380,8 +422,16 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (!this.plainPromptText()) {
|
||||
this.$message.error('请输入视频描述文本')
|
||||
} else {
|
||||
const contentItems = this.$refs.videoRichEditor?.getContentItems?.() || []
|
||||
if (!plain && (!contentItems.length || !contentItems.some((i) => i.type === 'image_url'))) {
|
||||
this.$message.error('请输入视频描述文本或插入参考素材')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.selectedModel || !this.selectedRatio || this.selectedDuration == null || !this.selectedResolution) {
|
||||
this.$message.error('请选择模型、比例、时长与分辨率')
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -390,7 +440,17 @@ export default {
|
|||
const params = {
|
||||
text,
|
||||
functionType: '21',
|
||||
model: this.selectedModel
|
||||
model: this.selectedModel,
|
||||
ratio: this.selectedRatio,
|
||||
duration: this.selectedDuration,
|
||||
resolution: this.selectedResolution
|
||||
}
|
||||
|
||||
if (this.videoMode === 'text-to-video') {
|
||||
const contentItems = this.$refs.videoRichEditor?.getContentItems?.() || []
|
||||
if (contentItems.length) {
|
||||
params.content = contentItems
|
||||
}
|
||||
}
|
||||
|
||||
const urlMap = {
|
||||
|
|
@ -407,7 +467,7 @@ export default {
|
|||
params.lastUrl = typeof this.lastUrl === 'object' ? this.lastUrl.url : this.lastUrl
|
||||
}
|
||||
if (this.videoMode === 'image-reference') {
|
||||
params.referenceUrl = typeof this.referenceUrl === 'object' ? this.referenceUrl.url : this.referenceUrl
|
||||
params.referenceUrl = this.firstReferenceImageUrlFromEditor()
|
||||
}
|
||||
|
||||
this.$axios({
|
||||
|
|
@ -573,130 +633,71 @@ export default {
|
|||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.vg-type-select {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px 12px;
|
||||
}
|
||||
|
||||
.vg-hero-mode-label {
|
||||
font-size: 13px;
|
||||
color: var(--vg-muted);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.vg-type-trigger {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 14px;
|
||||
margin: 0;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.03));
|
||||
border: 1px solid var(--vg-border);
|
||||
border-radius: 12px;
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
box-shadow: 0 0 0 1px rgba(0, 202, 224, 0.15);
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(0, 202, 224, 0.45);
|
||||
}
|
||||
|
||||
&.is-open .vg-type-chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.vg-type-label {
|
||||
background: linear-gradient(90deg, #fff, rgba(0, 202, 224, 0.95));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.vg-type-chevron {
|
||||
width: 0.85em;
|
||||
height: 0.85em;
|
||||
opacity: 0.75;
|
||||
transition: transform 0.2s cubic-bezier(0.15, 0.75, 0.3, 1);
|
||||
}
|
||||
|
||||
.vg-type-dropdown {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: calc(100% + 8px);
|
||||
min-width: 100%;
|
||||
z-index: 50;
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.vg-type-dropdown-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(18, 20, 26, 0.98);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--vg-border);
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.vg-type-options {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 6px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.vg-type-option {
|
||||
padding: 12px 16px;
|
||||
border-radius: 10px;
|
||||
color: var(--vg-muted);
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
color: var(--vg-text);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--vg-cyan);
|
||||
background: rgba(0, 202, 224, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.vg-fade-enter-active,
|
||||
.vg-fade-leave-active {
|
||||
transition: opacity 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
.vg-fade-enter-from,
|
||||
.vg-fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-6px);
|
||||
}
|
||||
|
||||
/* —— Body —— */
|
||||
.vg-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 20px;
|
||||
gap: 16px;
|
||||
align-items: stretch;
|
||||
min-height: 420px;
|
||||
}
|
||||
|
||||
.vg-left-rail {
|
||||
flex: 0 0 200px;
|
||||
min-width: 176px;
|
||||
padding: 18px 14px;
|
||||
background: var(--vg-panel);
|
||||
border: 1px solid var(--vg-border);
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.vg-rail-title {
|
||||
margin: 0 0 14px;
|
||||
font-size: 12px;
|
||||
color: var(--vg-muted);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.vg-mode-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.vg-mode-item {
|
||||
padding: 11px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 1.35;
|
||||
color: var(--vg-muted);
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
background: rgba(0, 0, 0, 0.22);
|
||||
transition: color 0.15s, border-color 0.15s, background 0.15s;
|
||||
|
||||
&:hover {
|
||||
color: var(--vg-text);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--vg-cyan);
|
||||
border-color: rgba(0, 202, 224, 0.35);
|
||||
background: rgba(0, 202, 224, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.vg-generator {
|
||||
flex: 0 0 min(520px, 44vw);
|
||||
min-width: 300px;
|
||||
flex: 1;
|
||||
min-width: 280px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
|
@ -809,21 +810,11 @@ export default {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.rich-editor-root) {
|
||||
:deep(.video-editor-root) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
:deep(.rich-editor) {
|
||||
flex: 1;
|
||||
min-height: 220px !important;
|
||||
font-size: 15px;
|
||||
line-height: 1.7;
|
||||
padding: 16px 18px;
|
||||
border-radius: 14px !important;
|
||||
background: rgba(0, 0, 0, 0.25) !important;
|
||||
border: 1px solid var(--vg-border) !important;
|
||||
min-height: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -842,29 +833,38 @@ export default {
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
.vg-model-wrap {
|
||||
.vg-params-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 4px 12px;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
gap: 12px 14px;
|
||||
padding: 10px 12px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--vg-border);
|
||||
}
|
||||
|
||||
.vg-model-icon {
|
||||
.vg-param {
|
||||
display: flex;
|
||||
color: var(--vg-cyan);
|
||||
opacity: 0.85;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
flex: 1 1 140px;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.vg-model-select {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
.vg-param-label {
|
||||
font-size: 12px;
|
||||
color: var(--vg-muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.vg-param-select {
|
||||
width: 100%;
|
||||
|
||||
:deep(.arco-select-view-single) {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
background: rgba(0, 0, 0, 0.2) !important;
|
||||
border: 1px solid var(--vg-border) !important;
|
||||
border-radius: 10px !important;
|
||||
color: var(--vg-text) !important;
|
||||
}
|
||||
:deep(.arco-select-view-value) {
|
||||
|
|
@ -999,6 +999,20 @@ export default {
|
|||
.vg-body {
|
||||
flex-direction: column;
|
||||
}
|
||||
.vg-left-rail {
|
||||
flex: none;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
.vg-mode-list {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.vg-mode-item {
|
||||
flex: 1 1 calc(50% - 4px);
|
||||
min-width: 140px;
|
||||
text-align: center;
|
||||
}
|
||||
.vg-generator {
|
||||
flex: none;
|
||||
width: 100%;
|
||||
|
|
@ -1007,10 +1021,6 @@ export default {
|
|||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
.vg-type-select {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.vg-task-empty {
|
||||
|
|
|
|||
Loading…
Reference in New Issue