param builder component is ready
10
api/test/test_test.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
fmt.Println("test")
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4125778 */
|
||||
src: url('iconfont.woff2?t=1756954977612') format('woff2'),
|
||||
url('iconfont.woff?t=1756954977612') format('woff'),
|
||||
url('iconfont.ttf?t=1756954977612') format('truetype');
|
||||
src: url('iconfont.woff2?t=1757465848673') format('woff2'),
|
||||
url('iconfont.woff?t=1757465848673') format('woff'),
|
||||
url('iconfont.ttf?t=1757465848673') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@@ -13,6 +13,22 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-action:before {
|
||||
content: "\e658";
|
||||
}
|
||||
|
||||
.icon-dancing:before {
|
||||
content: "\e659";
|
||||
}
|
||||
|
||||
.icon-running:before {
|
||||
content: "\e65e";
|
||||
}
|
||||
|
||||
.icon-shuziren:before {
|
||||
content: "\e6df";
|
||||
}
|
||||
|
||||
.icon-cube:before {
|
||||
content: "\e72c";
|
||||
}
|
||||
|
||||
@@ -5,6 +5,34 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "5215282",
|
||||
"name": "动作",
|
||||
"font_class": "action",
|
||||
"unicode": "e658",
|
||||
"unicode_decimal": 58968
|
||||
},
|
||||
{
|
||||
"icon_id": "7250581",
|
||||
"name": "跳舞",
|
||||
"font_class": "dancing",
|
||||
"unicode": "e659",
|
||||
"unicode_decimal": 58969
|
||||
},
|
||||
{
|
||||
"icon_id": "8153037",
|
||||
"name": "动作",
|
||||
"font_class": "running",
|
||||
"unicode": "e65e",
|
||||
"unicode_decimal": 58974
|
||||
},
|
||||
{
|
||||
"icon_id": "42680536",
|
||||
"name": "数字人",
|
||||
"font_class": "shuziren",
|
||||
"unicode": "e6df",
|
||||
"unicode_decimal": 59103
|
||||
},
|
||||
{
|
||||
"icon_id": "544492",
|
||||
"name": "cube",
|
||||
|
||||
BIN
web/src/assets/img/jimeng/central_orbit.webp
Normal file
|
After Width: | Height: | Size: 1022 KiB |
BIN
web/src/assets/img/jimeng/clockwise_swivel.webp
Normal file
|
After Width: | Height: | Size: 1016 KiB |
BIN
web/src/assets/img/jimeng/counterclockwise_swivel.webp
Normal file
|
After Width: | Height: | Size: 1002 KiB |
BIN
web/src/assets/img/jimeng/crane_push.webp
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
web/src/assets/img/jimeng/dynamic_orbit.webp
Normal file
|
After Width: | Height: | Size: 856 KiB |
BIN
web/src/assets/img/jimeng/handheld.webp
Normal file
|
After Width: | Height: | Size: 877 KiB |
BIN
web/src/assets/img/jimeng/hitchcock_dolly_in.webp
Normal file
|
After Width: | Height: | Size: 698 KiB |
BIN
web/src/assets/img/jimeng/hitchcock_dolly_out.webp
Normal file
|
After Width: | Height: | Size: 948 KiB |
BIN
web/src/assets/img/jimeng/quick_pull_back.webp
Normal file
|
After Width: | Height: | Size: 1021 KiB |
BIN
web/src/assets/img/jimeng/rapid_push_pull.webp
Normal file
|
After Width: | Height: | Size: 874 KiB |
BIN
web/src/assets/img/jimeng/robo_arm.webp
Normal file
|
After Width: | Height: | Size: 809 KiB |
BIN
web/src/assets/img/model-version.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<div class="right flex-center">
|
||||
<div class="logo">
|
||||
<el-image
|
||||
:src="logo"
|
||||
alt=""
|
||||
style="max-width: 300px; max-height: 300px"
|
||||
class="rounded-full"
|
||||
/>
|
||||
</div>
|
||||
<div>welcome</div>
|
||||
<footer-bar />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import FooterBar from '@/components/FooterBar.vue'
|
||||
import { getSystemInfo } from '@/store/cache'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const logo = ref('')
|
||||
const title = ref('')
|
||||
|
||||
getSystemInfo()
|
||||
.then((res) => {
|
||||
logo.value = res.data.logo
|
||||
title.value = res.data.title
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
logo.value = '/images/logo.png'
|
||||
title.value = 'Geek-AI'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.right {
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
flex-direction: column;
|
||||
background-image: url('~@/assets/img/login-bg.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
width: 50%;
|
||||
min-height: 100vh;
|
||||
max-height: 100vh;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
z-index: 1;
|
||||
|
||||
:deep(.foot-container) {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
width: 100%;
|
||||
background: none;
|
||||
color: var(--sm-txt);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
|
||||
.footer {
|
||||
a,
|
||||
span {
|
||||
color: var(--text-fff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin-bottom: 26px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,102 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<ThemeChange />
|
||||
<div @click="goBack" class="flex back animate__animated animate__pulse animate__infinite">
|
||||
<el-icon><ArrowLeftBold /></el-icon>{{ title === '注册' ? '首页' : '返回' }}
|
||||
</div>
|
||||
<div class="title">{{ title }}</div>
|
||||
<div class="smTitle" v-if="title !== '重置密码'">
|
||||
{{ title === '登录' ? '没有账号?' : '已有账号?'
|
||||
}}<span @click="goPageFun" class="text-color-primary sign"
|
||||
>赶紧{{ title === '登录' ? '注册' : '登录' }}</span
|
||||
>
|
||||
</div>
|
||||
<slot></slot>
|
||||
<div class="flex orline" v-if="title !== '重置密码'">
|
||||
<div class="lineor"></div>
|
||||
<span>或</span>
|
||||
<div class="lineor"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ThemeChange from '@/components/ThemeChange.vue'
|
||||
import { ArrowLeftBold } from '@element-plus/icons-vue'
|
||||
import { defineProps } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '登录',
|
||||
},
|
||||
smTitle: { type: String, default: '没有账号?' },
|
||||
goPage: {
|
||||
type: String,
|
||||
default: '/register',
|
||||
},
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
const goBack = () => {
|
||||
if (props.title === '注册') {
|
||||
router.push('/')
|
||||
} else {
|
||||
router.go(-1)
|
||||
}
|
||||
}
|
||||
const goPageFun = () => {
|
||||
if (props.title === '登录') {
|
||||
router.push('/register')
|
||||
} else {
|
||||
router.push('/login')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.back {
|
||||
color: var(--sm-txt);
|
||||
font-size: 14px;
|
||||
margin-bottom: 140px;
|
||||
margin-top: 18px;
|
||||
cursor: pointer;
|
||||
|
||||
.el-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
margin-bottom: 16px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.smTitle {
|
||||
color: var(--text-color);
|
||||
font-size: 14px;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.sign {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.orline {
|
||||
color: var(--text-secondary);
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.lineor {
|
||||
width: 182px;
|
||||
height: 1px;
|
||||
background: var(--text-secondary);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -145,7 +145,7 @@ const imageList = computed({
|
||||
if (props.multiple || props.maxCount > 1) {
|
||||
return Array.isArray(props.modelValue) ? props.modelValue : []
|
||||
} else {
|
||||
return props.modelValue ? [props.modelValue] : []
|
||||
return props.modelValue && props.modelValue.length > 0 ? [props.modelValue] : []
|
||||
}
|
||||
},
|
||||
set(value) {
|
||||
|
||||
258
web/src/components/ParamBuilder.vue
Normal file
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<div class="param-builder flex flex-col">
|
||||
<ParamEmpty
|
||||
v-if="items.length === 0"
|
||||
:progress="progress"
|
||||
:title="title"
|
||||
:status-text="statusText"
|
||||
:description="description"
|
||||
/>
|
||||
<div v-else class="flex flex-col w-full space-y-5">
|
||||
<el-select
|
||||
v-model="selectedModel"
|
||||
placeholder="请选择模型"
|
||||
@change="changeModel"
|
||||
popper-class="model-select"
|
||||
value-key="name"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="iconfont icon-model"></i>
|
||||
</template>
|
||||
|
||||
<el-option v-for="item in items" :key="item.name" :label="item.name" :value="item">
|
||||
<div class="flex justify-start">
|
||||
<span
|
||||
class="flex items-center justify-center text-white !text-xl model-version mr-2 w-[40px] h-[40px] rounded-lg"
|
||||
>{{ item.version }}</span
|
||||
>
|
||||
<div class="flex !items-start flex-col py-2 space-y-1">
|
||||
<span class="label text-sm">{{ item.name }}</span>
|
||||
<div class="whitespace-pre-line">
|
||||
<span
|
||||
class="text-xs text-gray-500 break-words whitespace-pre-line line-clamp-1"
|
||||
:title="item.label"
|
||||
>{{ item.label }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<div v-for="param in selectedModel.params" :key="param.name" class="w-full">
|
||||
<div class="w-full flex flex-col !items-start space-y-2" v-if="param.type === 'switch'">
|
||||
<div class="w-full flex justify-between">
|
||||
<label class="label font-bold">{{ param.label }}</label>
|
||||
<el-switch v-model="modelValue[param.name]" size="large" />
|
||||
</div>
|
||||
<p v-if="param.info" class="text-xs text-gray-500 mb-1">{{ param.info }}</p>
|
||||
</div>
|
||||
<div class="w-full flex flex-col !items-start space-y-2" v-else>
|
||||
<label class="label font-bold">
|
||||
{{ param.label }}
|
||||
<span v-if="param.required" class="text-red-500 ml-1">*</span>
|
||||
</label>
|
||||
<p v-if="param.info" class="text-xs text-gray-500 mb-1">{{ param.info }}</p>
|
||||
<div class="flex w-full">
|
||||
<el-input
|
||||
v-if="param.type === 'text'"
|
||||
v-model="modelValue[param.name]"
|
||||
:placeholder="param.placeholder"
|
||||
/>
|
||||
<el-input-number
|
||||
v-if="param.type === 'number'"
|
||||
v-model="modelValue[param.name]"
|
||||
class="!w-full"
|
||||
:placeholder="param.placeholder"
|
||||
:min="param.min"
|
||||
:max="param.max"
|
||||
:step="param.step"
|
||||
/>
|
||||
<el-slider
|
||||
v-if="param.type === 'slider'"
|
||||
v-model="modelValue[param.name]"
|
||||
:min="param.min"
|
||||
:max="param.max"
|
||||
:step="param.step"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-if="param.type === 'date'"
|
||||
v-model="modelValue[param.name]"
|
||||
:placeholder="param.placeholder"
|
||||
/>
|
||||
<el-time-picker
|
||||
v-if="param.type === 'time'"
|
||||
v-model="modelValue[param.name]"
|
||||
:placeholder="param.placeholder"
|
||||
/>
|
||||
<el-select
|
||||
v-if="param.type === 'select'"
|
||||
v-model="modelValue[param.name]"
|
||||
:placeholder="param.placeholder"
|
||||
:popper-class="param.popperClass"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in param.options"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
>
|
||||
<div class="flex justify-start" v-if="option.image">
|
||||
<span class="flex py-3 mr-2">
|
||||
<img :src="option.image" class="w-[54px] h-[54px] rounded-lg"
|
||||
/></span>
|
||||
<div class="flex !items-start flex-col py-2 space-y-1">
|
||||
<span class="label text-sm">{{ option.label }}</span>
|
||||
<span class="text-xs text-gray-500">{{ option.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-start items-center h-full" v-else>
|
||||
<span class="label text-sm">{{ option.label }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-if="param.type === 'textarea'"
|
||||
v-model="modelValue[param.name]"
|
||||
:autosize="param.autosize"
|
||||
:maxlength="param.maxlength"
|
||||
:show-word-limit="param.showWordLimit"
|
||||
:placeholder="param.placeholder"
|
||||
/>
|
||||
<ImageUpload
|
||||
v-if="param.type === 'image'"
|
||||
v-model="modelValue[param.name]"
|
||||
:max-count="param.maxCount"
|
||||
:multiple="param.multiple"
|
||||
:max-size="param.maxSize"
|
||||
:accept="param.accept"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ImageUpload from './ImageUpload.vue'
|
||||
import ParamEmpty from './ui/ParamEmpty.vue'
|
||||
|
||||
const title = ref('参数构建器')
|
||||
const statusText = ref('功能正在开发中')
|
||||
const description = ref('我们正在努力完善当前功能,敬请期待!')
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
progress: {
|
||||
type: Number,
|
||||
default: 65,
|
||||
validator: (value) => value >= 0 && value <= 100,
|
||||
},
|
||||
})
|
||||
|
||||
const selectedModel = ref({ label: '请选择模型' })
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
// 初始化 modelValue 默认值
|
||||
const initModelValue = (model) => {
|
||||
const defaultValues = {}
|
||||
if (model && model.params) {
|
||||
model.params.forEach((param) => {
|
||||
// 根据参数类型设置默认值
|
||||
switch (param.type) {
|
||||
case 'text':
|
||||
case 'textarea':
|
||||
defaultValues[param.name] = param.value || ''
|
||||
break
|
||||
case 'number':
|
||||
defaultValues[param.name] = param.value || 0
|
||||
break
|
||||
case 'slider':
|
||||
defaultValues[param.name] = param.value || param.min || 0
|
||||
break
|
||||
case 'select':
|
||||
// 如果有选项,选择第一个选项作为默认值
|
||||
defaultValues[param.name] =
|
||||
param.value || (param.options && param.options[0] ? param.options[0].value : '')
|
||||
break
|
||||
case 'checkbox':
|
||||
case 'switch':
|
||||
defaultValues[param.name] = param.value || false
|
||||
break
|
||||
case 'date':
|
||||
case 'time':
|
||||
defaultValues[param.name] = param.value || null
|
||||
break
|
||||
case 'image':
|
||||
defaultValues[param.name] = param.value || []
|
||||
break
|
||||
default:
|
||||
defaultValues[param.name] = param.value || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
return defaultValues
|
||||
}
|
||||
|
||||
// 初始化默认值
|
||||
const modelValue = ref(initModelValue(selectedModel.value))
|
||||
|
||||
// 监听 modelValue 变化,通知父组件
|
||||
watch(
|
||||
modelValue,
|
||||
(newValue) => {
|
||||
emit('update:modelValue', newValue)
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
// 组件挂载时初始化
|
||||
onMounted(() => {
|
||||
// 确保初始值被正确设置
|
||||
if (props.modelValue && Object.keys(props.modelValue).length > 0) {
|
||||
modelValue.value = { ...props.modelValue }
|
||||
} else {
|
||||
modelValue.value = initModelValue(selectedModel.value)
|
||||
}
|
||||
})
|
||||
|
||||
const changeModel = (item) => {
|
||||
if (item) {
|
||||
selectedModel.value = item
|
||||
// 更新 modelValue 为选中模型的默认值
|
||||
modelValue.value = initModelValue(item)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.param-builder {
|
||||
.model-version {
|
||||
background: url('@/assets/img/model-version.png') no-repeat center center;
|
||||
background-size: cover;
|
||||
}
|
||||
.el-select__wrapper {
|
||||
min-height: 34px;
|
||||
line-height: 25px;
|
||||
}
|
||||
}
|
||||
.model-select {
|
||||
.el-select-dropdown__item {
|
||||
height: auto !important;
|
||||
}
|
||||
.model-version {
|
||||
background: url('@/assets/img/model-version.png') no-repeat center center;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -279,7 +279,7 @@ const items = [
|
||||
{
|
||||
icon: 'xmind',
|
||||
index: '/admin/config/markmap',
|
||||
title: '思维导图配置',
|
||||
title: '思维导图',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
148
web/src/components/ui/ParamEmpty.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div class="flex flex-col justify-center items-center py-8 px-4">
|
||||
<!-- 开发中图标和动画 -->
|
||||
<div class="relative mb-4">
|
||||
<div
|
||||
class="w-16 h-16 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center shadow-lg animate-float animate-glow"
|
||||
>
|
||||
<svg
|
||||
class="w-8 h-8 text-white animate-pulse"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
|
||||
></path>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- 旋转的装饰环 -->
|
||||
<div
|
||||
class="absolute inset-0 w-16 h-16 border-2 border-blue-200 rounded-full animate-spin"
|
||||
style="animation-duration: 3s"
|
||||
></div>
|
||||
<div
|
||||
class="absolute inset-1 w-14 h-14 border border-purple-200 rounded-full animate-spin"
|
||||
style="animation-duration: 2s; animation-direction: reverse"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<!-- 主标题 -->
|
||||
<h3 class="text-lg font-semibold text-gray-700 mb-2">{{ title }}</h3>
|
||||
|
||||
<!-- 开发中提示 -->
|
||||
<div class="text-center space-y-2">
|
||||
<p class="text-gray-500 text-sm">🚀 {{ statusText }}</p>
|
||||
<p class="text-xs text-gray-400 max-w-xs leading-relaxed">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 进度条 -->
|
||||
<div class="w-48 mt-4">
|
||||
<div class="bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div
|
||||
class="bg-gradient-to-r from-blue-500 to-purple-600 h-full rounded-full progress-bar"
|
||||
:style="{ width: progress + '%' }"
|
||||
></div>
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 text-center mt-1">开发进度 {{ progress }}%</p>
|
||||
</div>
|
||||
|
||||
<!-- 装饰性元素 -->
|
||||
<div class="flex space-x-1 mt-4">
|
||||
<div
|
||||
class="w-2 h-2 bg-blue-400 rounded-full animate-bounce"
|
||||
style="animation-delay: 0s"
|
||||
></div>
|
||||
<div
|
||||
class="w-2 h-2 bg-purple-400 rounded-full animate-bounce"
|
||||
style="animation-delay: 0.1s"
|
||||
></div>
|
||||
<div
|
||||
class="w-2 h-2 bg-pink-400 rounded-full animate-bounce"
|
||||
style="animation-delay: 0.2s"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
// 进度百分比 (0-100)
|
||||
progress: {
|
||||
type: Number,
|
||||
default: 65,
|
||||
validator: (value) => value >= 0 && value <= 100,
|
||||
},
|
||||
// 主标题
|
||||
title: {
|
||||
type: String,
|
||||
default: '参数构建器',
|
||||
},
|
||||
// 状态文本
|
||||
statusText: {
|
||||
type: String,
|
||||
default: '功能正在开发中',
|
||||
},
|
||||
// 描述文本
|
||||
description: {
|
||||
type: String,
|
||||
default: '我们正在努力完善当前功能,敬请期待!',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* 自定义动画效果 */
|
||||
@keyframes float {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glow {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 0 5px rgba(59, 130, 246, 0.5);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 20px rgba(59, 130, 246, 0.8), 0 0 30px rgba(147, 51, 234, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-float {
|
||||
animation: float 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-glow {
|
||||
animation: glow 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 进度条动画 */
|
||||
@keyframes progress {
|
||||
0% {
|
||||
width: 0%;
|
||||
}
|
||||
100% {
|
||||
width: v-bind(progress + '%');
|
||||
}
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
animation: progress 2s ease-out forwards;
|
||||
}
|
||||
</style>
|
||||
@@ -1,4 +1,16 @@
|
||||
export const paramsMap = {
|
||||
import central_orbit from '@/assets/img/jimeng/central_orbit.webp'
|
||||
import clockwise_swivel from '@/assets/img/jimeng/clockwise_swivel.webp'
|
||||
import counterclockwise_swivel from '@/assets/img/jimeng/counterclockwise_swivel.webp'
|
||||
import crane_push from '@/assets/img/jimeng/crane_push.webp'
|
||||
import dynamic_orbit from '@/assets/img/jimeng/dynamic_orbit.webp'
|
||||
import handheld from '@/assets/img/jimeng/handheld.webp'
|
||||
import hitchcock_dolly_in from '@/assets/img/jimeng/hitchcock_dolly_in.webp'
|
||||
import hitchcock_dolly_out from '@/assets/img/jimeng/hitchcock_dolly_out.webp'
|
||||
import quick_pull_back from '@/assets/img/jimeng/quick_pull_back.webp'
|
||||
import rapid_push_pull from '@/assets/img/jimeng/rapid_push_pull.webp'
|
||||
import robo_arm from '@/assets/img/jimeng/robo_arm.webp'
|
||||
|
||||
export const JimengParams = {
|
||||
image: [
|
||||
{
|
||||
name: '图片 2.1 文生图',
|
||||
@@ -9,11 +21,15 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成图像的提示词 ,中英文均可输入',
|
||||
},
|
||||
|
||||
{
|
||||
name: 'size',
|
||||
type: 'select',
|
||||
@@ -57,8 +73,8 @@ export const paramsMap = {
|
||||
},
|
||||
{
|
||||
name: 'use_pre_llm',
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
type: 'switch',
|
||||
required: false,
|
||||
label: '开启文本扩写',
|
||||
info: '开启后,系统会自动扩写提示词,提高生成质量',
|
||||
value: true,
|
||||
@@ -74,7 +90,10 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成图像的提示词 ,中英文均可输入',
|
||||
@@ -131,10 +150,11 @@ export const paramsMap = {
|
||||
},
|
||||
{
|
||||
name: 'use_pre_llm',
|
||||
type: 'boolean',
|
||||
type: 'switch',
|
||||
required: true,
|
||||
label: '开启文本扩写',
|
||||
info: '开启后,系统会自动扩写提示词,提高生成质量',
|
||||
value: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -147,7 +167,10 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成图像的提示词 ,中英文均可输入',
|
||||
@@ -204,10 +227,11 @@ export const paramsMap = {
|
||||
},
|
||||
{
|
||||
name: 'use_pre_llm',
|
||||
type: 'boolean',
|
||||
type: 'switch',
|
||||
required: true,
|
||||
label: '开启文本扩写',
|
||||
info: '开启后,系统会自动扩写提示词,提高生成质量',
|
||||
value: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -221,8 +245,81 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
placeholder: '请输入用于编辑图像的提示词,如:把xxx改成xxx,删除xxx,添加xxx等',
|
||||
info: '建议长度<=120字符,最长不超过800字符',
|
||||
},
|
||||
{
|
||||
name: 'image_urls',
|
||||
label: '参考图片',
|
||||
type: 'image',
|
||||
required: true,
|
||||
placeholder: '请上传图片',
|
||||
maxSize: 5,
|
||||
accept: '.png,.jpg,.jpeg',
|
||||
info: '长边与短边比例在3以内,超出此比例或比例相对极端,会导致报错。',
|
||||
},
|
||||
{
|
||||
name: 'scale',
|
||||
label: '文本描述影响的程度',
|
||||
type: 'slider',
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.1,
|
||||
value: 0.5,
|
||||
info: '该值越大代表文本描述影响程度越大,且输入图片影响程度越小',
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
type: 'select',
|
||||
required: true,
|
||||
placeholder: '请选择尺寸',
|
||||
label: '图片尺寸',
|
||||
|
||||
options: [
|
||||
{
|
||||
label: '1:1 (1328 * 1328)',
|
||||
value: '1328x1328',
|
||||
},
|
||||
{
|
||||
label: '4:3 (1472 * 1104)',
|
||||
value: '1472x1104',
|
||||
},
|
||||
{
|
||||
label: '3:2 (1584 * 1056)',
|
||||
value: '1584x1056',
|
||||
},
|
||||
{
|
||||
label: '16:9 (1664 * 936)',
|
||||
value: '1664x936',
|
||||
},
|
||||
{
|
||||
label: '21:9 (2016 * 864)',
|
||||
value: '2016x864',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '图片 4.0 文/图生图',
|
||||
version: '4.0',
|
||||
label:
|
||||
'支持文本、单图和多图输入,实现基于主体一致性的多图融合创作、图像编辑、组图生成等多样玩法',
|
||||
key: 'jimeng_i2i_v30',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
placeholder: '请输入用于编辑图像的提示词,如:把xxx改成xxx,删除xxx,添加xxx等',
|
||||
info: '建议长度<=120字符,最长不超过800字符',
|
||||
},
|
||||
@@ -289,7 +386,10 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
@@ -354,7 +454,10 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
@@ -364,7 +467,6 @@ export const paramsMap = {
|
||||
label: '首帧图片',
|
||||
type: 'image',
|
||||
required: false,
|
||||
placeholder: '请上传图片',
|
||||
multiple: false,
|
||||
maxCount: 1,
|
||||
maxSize: 5,
|
||||
@@ -397,21 +499,24 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
},
|
||||
{
|
||||
name: 'image_urls',
|
||||
label: '首帧图片',
|
||||
label: '首尾帧图片',
|
||||
type: 'image',
|
||||
required: false,
|
||||
placeholder: '请上传图片',
|
||||
multiple: true,
|
||||
maxCount: 2,
|
||||
maxSize: 5,
|
||||
accept: '.png,.jpg,.jpeg',
|
||||
info: '请上传两张图片,第一张为起始帧,第二张为尾帧',
|
||||
},
|
||||
{
|
||||
name: 'duration',
|
||||
@@ -440,7 +545,10 @@ export const paramsMap = {
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
@@ -452,7 +560,7 @@ export const paramsMap = {
|
||||
required: false,
|
||||
placeholder: '请上传图片',
|
||||
maxSize: 5,
|
||||
multiple: false,
|
||||
multiple: true,
|
||||
maxCount: 1,
|
||||
accept: '.png,.jpg,.jpeg',
|
||||
},
|
||||
@@ -460,60 +568,73 @@ export const paramsMap = {
|
||||
name: 'template_id',
|
||||
label: '运镜控制',
|
||||
type: 'select',
|
||||
required: false,
|
||||
required: true,
|
||||
placeholder: '请选择运镜控制',
|
||||
popperClass: 'model-select',
|
||||
options: [
|
||||
{
|
||||
label: '希区柯克推进',
|
||||
value: 'hitchcock_dolly_in',
|
||||
image: hitchcock_dolly_in,
|
||||
},
|
||||
{
|
||||
label: '希区柯克拉远',
|
||||
value: 'hitchcock_dolly_out',
|
||||
image: hitchcock_dolly_out,
|
||||
},
|
||||
{
|
||||
label: '机械臂',
|
||||
value: 'robo_arm',
|
||||
image: robo_arm,
|
||||
},
|
||||
{
|
||||
label: '动感环绕',
|
||||
value: 'dynamic_orbit',
|
||||
image: dynamic_orbit,
|
||||
},
|
||||
{
|
||||
label: '中心环绕',
|
||||
value: 'central_orbit',
|
||||
image: central_orbit,
|
||||
},
|
||||
{
|
||||
label: '起重机',
|
||||
value: 'crane_push',
|
||||
image: crane_push,
|
||||
},
|
||||
{
|
||||
label: '超级拉远',
|
||||
value: 'quick_pull_back',
|
||||
image: quick_pull_back,
|
||||
},
|
||||
{
|
||||
label: '逆时针回旋',
|
||||
value: 'counterclockwise_swivel',
|
||||
image: counterclockwise_swivel,
|
||||
},
|
||||
{
|
||||
label: '顺时针回旋',
|
||||
value: 'clockwise_swivel',
|
||||
image: clockwise_swivel,
|
||||
},
|
||||
{
|
||||
label: '手持运镜',
|
||||
value: 'handheld',
|
||||
image: handheld,
|
||||
},
|
||||
{
|
||||
label: '快速推拉',
|
||||
value: 'rapid_push_pull',
|
||||
image: rapid_push_pull,
|
||||
},
|
||||
],
|
||||
value: 'hitchcock_dolly_in',
|
||||
},
|
||||
{
|
||||
name: 'camera_strength',
|
||||
label: '运镜强度',
|
||||
type: 'select',
|
||||
required: false,
|
||||
required: true,
|
||||
placeholder: '请选择运镜强度',
|
||||
options: [
|
||||
{
|
||||
@@ -529,6 +650,76 @@ export const paramsMap = {
|
||||
value: 'strong',
|
||||
},
|
||||
],
|
||||
value: 'medium',
|
||||
},
|
||||
{
|
||||
name: 'duration',
|
||||
type: 'select',
|
||||
label: '视频时长',
|
||||
options: [
|
||||
{
|
||||
label: '5秒',
|
||||
value: '5',
|
||||
},
|
||||
{
|
||||
label: '10秒',
|
||||
value: '10',
|
||||
},
|
||||
],
|
||||
value: '5',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: '视频 3.0 1080P-文生视频',
|
||||
version: '3.0',
|
||||
label: '视觉表达流畅一致,支持1080P高清渲染',
|
||||
key: 'jimeng_t2v_v30_1080p',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
},
|
||||
{
|
||||
name: 'aspect_ratio',
|
||||
label: '视频比例',
|
||||
type: 'select',
|
||||
required: false,
|
||||
placeholder: '请选择视频比例',
|
||||
options: [
|
||||
{
|
||||
label: '16:9 (横版)',
|
||||
value: '16:9',
|
||||
},
|
||||
{
|
||||
label: '4:3 (标准)',
|
||||
value: '4:3',
|
||||
},
|
||||
{
|
||||
label: '1:1 (正方形)',
|
||||
value: '1:1',
|
||||
},
|
||||
{
|
||||
label: '3:4 (竖版)',
|
||||
value: '3:4',
|
||||
},
|
||||
{
|
||||
label: '9:16 (竖屏)',
|
||||
value: '9:16',
|
||||
},
|
||||
{
|
||||
label: '21:9 (超宽)',
|
||||
value: '21:9',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'duration',
|
||||
@@ -549,15 +740,109 @@ export const paramsMap = {
|
||||
},
|
||||
|
||||
{
|
||||
name: '视频 3.0Pro 图生视频',
|
||||
name: '视频 3.0 1080P-图生视频-首帧',
|
||||
version: '3.0',
|
||||
label: '根据提示词 + 首帧图片生成视频',
|
||||
key: 'jimeng_ti2v_v30_pro',
|
||||
label: '根据提示词 + 首帧图片生成1080P视频',
|
||||
key: 'jimeng_i2v_first_v30_1080',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
},
|
||||
{
|
||||
name: 'image_urls',
|
||||
label: '首帧图片',
|
||||
type: 'image',
|
||||
required: false,
|
||||
multiple: false,
|
||||
maxCount: 1,
|
||||
maxSize: 5,
|
||||
accept: '.png,.jpg,.jpeg',
|
||||
},
|
||||
{
|
||||
name: 'duration',
|
||||
type: 'select',
|
||||
label: '视频时长',
|
||||
options: [
|
||||
{
|
||||
label: '5秒',
|
||||
value: '5',
|
||||
},
|
||||
{
|
||||
label: '10秒',
|
||||
value: '10',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: '视频 3.0 1080P-图生视频-首尾帧',
|
||||
version: '3.0',
|
||||
label: '根据提示词 + 首尾帧图片生成1080P视频',
|
||||
key: 'jimeng_i2v_first_tail_v30_1080',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
},
|
||||
{
|
||||
name: 'image_urls',
|
||||
label: '首尾帧图片',
|
||||
type: 'image',
|
||||
required: false,
|
||||
multiple: true,
|
||||
maxCount: 2,
|
||||
maxSize: 5,
|
||||
accept: '.png,.jpg,.jpeg',
|
||||
info: '请上传两张图片,第一张为起始帧,第二张为尾帧',
|
||||
},
|
||||
{
|
||||
name: 'duration',
|
||||
type: 'select',
|
||||
label: '视频时长',
|
||||
options: [
|
||||
{
|
||||
label: '5秒',
|
||||
value: '5',
|
||||
},
|
||||
{
|
||||
label: '10秒',
|
||||
value: '10',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: '视频 3.0Pro 1080P-图生视频',
|
||||
version: '3.0',
|
||||
label: '根据提示词 + 首帧图片生成1080P视频',
|
||||
key: 'jimeng_ti2v_v30_pro',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'textarea',
|
||||
showWordLimit: true,
|
||||
maxlength: 800,
|
||||
autosize: { minRows: 3, maxRows: 5 },
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成视频的提示词 ,中英文均可输入',
|
||||
@@ -567,7 +852,6 @@ export const paramsMap = {
|
||||
label: '首帧图片',
|
||||
type: 'image',
|
||||
required: false,
|
||||
placeholder: '请上传图片',
|
||||
info: '只支持上传首帧图片',
|
||||
multiple: false,
|
||||
maxCount: 1,
|
||||
@@ -623,6 +907,7 @@ export const paramsMap = {
|
||||
value: '10',
|
||||
},
|
||||
],
|
||||
value: '5',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -630,3 +915,26 @@ export const paramsMap = {
|
||||
virtualHuman: [],
|
||||
actionTransfer: [],
|
||||
}
|
||||
|
||||
export const JimengFunctions = [
|
||||
{
|
||||
key: 'image',
|
||||
icon: 'iconfont icon-image',
|
||||
name: '图片生成',
|
||||
},
|
||||
{
|
||||
key: 'video',
|
||||
icon: 'icon-video',
|
||||
name: '视频生成',
|
||||
},
|
||||
{
|
||||
key: 'virtualHuman',
|
||||
icon: 'icon-shuziren',
|
||||
name: '数字人',
|
||||
},
|
||||
{
|
||||
key: 'actionTransfer',
|
||||
icon: 'icon-action',
|
||||
name: '动作模仿',
|
||||
},
|
||||
]
|
||||
@@ -6,6 +6,7 @@
|
||||
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
import { checkSession } from '@/store/cache'
|
||||
import { JimengParams } from '@/store/data'
|
||||
import { useSharedStore } from '@/store/sharedata'
|
||||
import { showMessageError, showMessageOK } from '@/utils/dialog'
|
||||
import { httpDownload, httpGet, httpPost } from '@/utils/http'
|
||||
@@ -44,224 +45,7 @@ export const useJimengStore = defineStore('jimeng', () => {
|
||||
// 登录弹窗
|
||||
const shareStore = useSharedStore()
|
||||
|
||||
const paramsMap = {
|
||||
image: [
|
||||
{
|
||||
name: '图片 2.1',
|
||||
version: '2.1',
|
||||
label: '平面绘感强,可生成文字海报',
|
||||
key: 'jimeng_high_aes_general_v21_L',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成图像的提示词 ,中英文均可输入',
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
type: 'select',
|
||||
required: true,
|
||||
placeholder: '请选择尺寸',
|
||||
label: '图片尺寸',
|
||||
options: [
|
||||
{
|
||||
label: '21:9 (1195x512)',
|
||||
value: '1195x512',
|
||||
},
|
||||
{
|
||||
label: '16:9 (1024x576)',
|
||||
value: '1024x576',
|
||||
},
|
||||
{
|
||||
label: '3:2 (1024x682)',
|
||||
value: '1024x682',
|
||||
},
|
||||
{
|
||||
label: '4:3 (1024x768)',
|
||||
value: '1024x768',
|
||||
},
|
||||
{
|
||||
label: '1:1 (1024x1024)',
|
||||
value: '1024x1024',
|
||||
},
|
||||
{
|
||||
label: '3:4 (768x1024)',
|
||||
value: '768x1024',
|
||||
},
|
||||
{
|
||||
label: '2:3 (682x1024)',
|
||||
value: '682x1024',
|
||||
},
|
||||
{
|
||||
label: '9:16 (576x1024)',
|
||||
value: '576x1024',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'use_pre_llm',
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
label: '开启文本扩写',
|
||||
info: '开启后,系统会自动扩写提示词,提高生成质量',
|
||||
value: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '图片 3.0 文生图',
|
||||
version: '3.0',
|
||||
label: '影视质感,文字更准,直出2k高清图',
|
||||
key: 'jimeng_t2i_v30',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成图像的提示词 ,中英文均可输入',
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
type: 'select',
|
||||
required: true,
|
||||
placeholder: '请选择尺寸',
|
||||
label: '图片尺寸',
|
||||
|
||||
options: [
|
||||
{
|
||||
label: '1:1 (1328x1328)',
|
||||
value: '1328x1328',
|
||||
},
|
||||
{
|
||||
label: '4:3 (1472x1104)',
|
||||
value: '1472x1104',
|
||||
},
|
||||
{
|
||||
label: '3:2 (1584x1056)',
|
||||
value: '1584x1056',
|
||||
},
|
||||
{
|
||||
label: '16:9 (1664x936)',
|
||||
value: '1664x936',
|
||||
},
|
||||
{
|
||||
label: '21:9 (2016x864)',
|
||||
value: '2016x864',
|
||||
},
|
||||
{
|
||||
label: '1:1 高清2K (2048x2048)',
|
||||
value: '2048x2048',
|
||||
},
|
||||
{
|
||||
label: '4:3 高清2K (2304x1728)',
|
||||
value: '2304x1728',
|
||||
},
|
||||
{
|
||||
label: '3:2 高清2K (2496x1664)',
|
||||
value: '2496x1664',
|
||||
},
|
||||
{
|
||||
label: '16:9 高清2K (2560x1440)',
|
||||
value: '2560x1440',
|
||||
},
|
||||
{
|
||||
label: '21:9 高清2K (3024x1296)',
|
||||
value: '3024x1296',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'use_pre_llm',
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
label: '开启文本扩写',
|
||||
info: '开启后,系统会自动扩写提示词,提高生成质量',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '图片 3.1',
|
||||
version: '3.1',
|
||||
label: '文生图3.0',
|
||||
key: 'jimeng_t2i_v31',
|
||||
params: [
|
||||
{
|
||||
name: 'prompt',
|
||||
label: '提示词',
|
||||
type: 'text',
|
||||
required: true,
|
||||
placeholder: '请输入提示词',
|
||||
info: '用于生成图像的提示词 ,中英文均可输入',
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
type: 'select',
|
||||
required: true,
|
||||
placeholder: '请选择尺寸',
|
||||
label: '图片尺寸',
|
||||
|
||||
options: [
|
||||
{
|
||||
label: '1:1 (1328x1328)',
|
||||
value: '1328x1328',
|
||||
},
|
||||
{
|
||||
label: '4:3 (1472x1104)',
|
||||
value: '1472x1104',
|
||||
},
|
||||
{
|
||||
label: '3:2 (1584x1056)',
|
||||
value: '1584x1056',
|
||||
},
|
||||
{
|
||||
label: '16:9 (1664x936)',
|
||||
value: '1664x936',
|
||||
},
|
||||
{
|
||||
label: '21:9 (2016x864)',
|
||||
value: '2016x864',
|
||||
},
|
||||
{
|
||||
label: '1:1 高清2K (2048x2048)',
|
||||
value: '2048x2048',
|
||||
},
|
||||
{
|
||||
label: '4:3 高清2K (2304x1728)',
|
||||
value: '2304x1728',
|
||||
},
|
||||
{
|
||||
label: '3:2 高清2K (2496x1664)',
|
||||
value: '2496x1664',
|
||||
},
|
||||
{
|
||||
label: '16:9 高清2K (2560x1440)',
|
||||
value: '2560x1440',
|
||||
},
|
||||
{
|
||||
label: '21:9 高清2K (3024x1296)',
|
||||
value: '3024x1296',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'use_pre_llm',
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
label: '开启文本扩写',
|
||||
info: '开启后,系统会自动扩写提示词,提高生成质量',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
video: [],
|
||||
virtualHuman: [],
|
||||
actionTransfer: [],
|
||||
}
|
||||
const paramsMap = JimengParams
|
||||
|
||||
// 功能分类配置
|
||||
const categories = [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="privacy-config container" v-loading="loading">
|
||||
<div class="container">
|
||||
<div class="privacy-config container w-full" v-loading="loading">
|
||||
<div class="w-full">
|
||||
<md-editor
|
||||
class="mgb20"
|
||||
v-model="privacy"
|
||||
|
||||
@@ -1,237 +1,65 @@
|
||||
<template>
|
||||
<div class="audio-chat-page">
|
||||
<!-- 图像特效 -->
|
||||
<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 class="flex m-3">
|
||||
<el-select v-model="currentFunction" placeholder="请选择功能" popper-class="custom-select">
|
||||
<template #prefix>
|
||||
<i
|
||||
class="iconfont !text-xl"
|
||||
:class="functions.find((f) => f.key === currentFunction).icon"
|
||||
></i>
|
||||
</template>
|
||||
<el-option v-for="f in functions" :value="f.key" :key="f.key" :label="f.name">
|
||||
<div class="flex items-center space-x-2">
|
||||
<i class="iconfont !text-xl" :class="f.icon"></i>
|
||||
<span>{{ f.name }}</span>
|
||||
</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>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</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 class="p-3">
|
||||
<param-builder
|
||||
v-model="formData"
|
||||
:items="params[currentFunction]"
|
||||
:progress="progress[currentFunction]"
|
||||
/>
|
||||
|
||||
<!-- 调试信息 -->
|
||||
<div class="mt-6 p-4 bg-gray-100 rounded-lg">
|
||||
<h3 class="text-lg font-bold mb-2">调试信息</h3>
|
||||
<div class="text-sm">
|
||||
<p><strong>当前功能:</strong> {{ currentFunction }}</p>
|
||||
<p><strong>表单数据:</strong></p>
|
||||
<pre class="bg-white p-2 rounded mt-1 overflow-auto">{{
|
||||
JSON.stringify(formData, null, 2)
|
||||
}}</pre>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const connect = () => {}
|
||||
import ParamBuilder from '@/components/ParamBuilder.vue'
|
||||
import { JimengFunctions, JimengParams } from '@/store/data'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const functions = JimengFunctions
|
||||
const params = JimengParams
|
||||
const formData = ref({})
|
||||
const currentFunction = ref('image')
|
||||
const progress = ref({
|
||||
image: 100,
|
||||
video: 100,
|
||||
virtualHuman: 38,
|
||||
actionTransfer: 65,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.audio-chat-page {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
canvas {
|
||||
background-color: transparent;
|
||||
.custom-select {
|
||||
.el-select-dropdown__item.is-selected {
|
||||
background-color: var(--el-fill-color-light);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||