AI3D 页面功能完成

This commit is contained in:
GeekMaster
2025-09-03 16:00:28 +08:00
parent ead30c8779
commit 54c8856adf
21 changed files with 1795 additions and 1319 deletions

237
web/src/views/test/Test.vue Normal file
View File

@@ -0,0 +1,237 @@
<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>
</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>
</template>
<script setup>
const connect = () => {}
</script>
<style scoped lang="scss">
.audio-chat-page {
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
}
canvas {
background-color: transparent;
}
</style>

View File

@@ -0,0 +1,66 @@
<template>
<div class="test-3d">
<h1>3D预览功能测试</h1>
<div class="test-container">
<h2>测试1: 默认立方体无模型URL</h2>
<div class="preview-wrapper">
<ThreeDPreview />
</div>
</div>
<div class="test-container">
<h2>测试2: 带模型URL如果有的话</h2>
<div class="preview-wrapper">
<ThreeDPreview v-if="testModelUrl" :model-url="testModelUrl" :model-type="testModelType" />
<div v-else class="no-model">
<p>没有测试模型URL</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
import ThreeDPreview from '@/components/ThreeDPreview.vue'
import { ref } from 'vue'
// 测试用的模型URL可以替换为实际的模型文件
const testModelUrl = ref('https://img.r9it.com/R03TQZ7PZ386RGL7PTMNGFOHAJW15WYF.glb')
const testModelType = ref('glb')
</script>
<style lang="scss" scoped>
.test-3d {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}
.test-container {
margin-bottom: 40px;
h2 {
margin-bottom: 16px;
color: #333;
}
}
.preview-wrapper {
width: 100%;
height: 500px;
border: 2px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.no-model {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
color: #666;
}
</style>