- {{ task.params ? getPromptFromParams(task.params) : '' }}
+ {{ task.params?.prompt }}
@@ -124,7 +253,7 @@
预览
- 下载
+ 下载
@@ -141,8 +270,8 @@
:page-sizes="[10, 20, 50]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
+ @size-change="handlePageSizeChange"
+ @current-change="handleCurrentPageChange"
/>
@@ -179,83 +308,101 @@ import CustomTabs from '@/components/ui/CustomTabs.vue'
import { httpGet, httpPost } from '@/utils/http'
import { ElMessage, ElMessageBox } from 'element-plus'
import { computed, onMounted, ref } from 'vue'
+import { checkSession } from '@/store/cache'
// 响应式数据
const activePlatform = ref('gitee')
-const currentImage = ref([])
-const currentPrompt = ref('')
-const selectedModel = ref('obj')
-const generating = ref(false)
+const loading = ref(false)
const previewVisible = ref(false)
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const taskList = ref([])
const currentPreviewTask = ref(null)
+const giteeAdvancedVisible = ref(false) // 控制Gitee高级参数显示状态
+const tencentForm = ref({
+ prompt: '',
+ image_url: '',
+ model: '',
+ power: 0,
+ file_format: '', // 输出文件格式
+ enable_pbr: false, // 是否开启PBR材质
+})
+const giteeForm = ref({
+ prompt: '',
+ image_url: '',
+ model: '',
+ power: 0,
+ file_format: '', // 输出文件格式
+ texture: false, // 是否开启纹理
+ seed: 1234, // 随机种子
+ num_inference_steps: 5, //迭代次数
+ guidance_scale: 7.5, //引导系数
+ octree_resolution: 128, // 3D 渲染精度,越高3D 细节越丰富
+})
+const currentPower = ref(0)
-// 平台配置
-const platformConfig = {
- gitee: {
- name: '魔力方舟',
- models: {
- obj: { name: 'OBJ格式', power: 45 },
- glb: { name: 'GLB格式', power: 55 },
- stl: { name: 'STL格式', power: 35 },
- usdz: { name: 'USDZ格式', power: 65 },
- fbx: { name: 'FBX格式', power: 75 },
- mp4: { name: 'MP4格式', power: 85 },
- },
- },
- tencent: {
- name: '腾讯混元',
- models: {
- obj: { name: 'OBJ格式', power: 50 },
- glb: { name: 'GLB格式', power: 60 },
- stl: { name: 'STL格式', power: 40 },
- usdz: { name: 'USDZ格式', power: 70 },
- fbx: { name: 'FBX格式', power: 80 },
- mp4: { name: 'MP4格式', power: 90 },
- },
- },
+// 计算属性:获取当前活跃平台的表单数据
+const currentForm = computed(() => {
+ return activePlatform.value === 'tencent' ? tencentForm.value : giteeForm.value
+})
+
+const selectedModel = computed(() => {
+ return currentForm.value.model
+})
+
+const currentPrompt = computed(() => {
+ return currentForm.value.prompt
+})
+
+const currentImage = computed(() => {
+ return currentForm.value.image_url ? [{ url: currentForm.value.image_url }] : []
+})
+
+const configs = ref({
+ gitee: { models: [] },
+ tencent: { models: [] },
+})
+
+const loadConfigs = async () => {
+ const response = await httpGet('/api/ai3d/configs')
+ configs.value = response.data
}
-// 计算属性
-const availableModels = computed(() => {
- return platformConfig[activePlatform.value]?.models || {}
-})
-
-const currentPower = computed(() => {
- return availableModels.value[selectedModel.value]?.power || 0
-})
-
-const canGenerate = computed(() => {
- return currentPrompt.value.trim() && currentImage.value.length > 0 && selectedModel.value
-})
-
-// 方法
-const handlePlatformChange = (platform) => {
- // 切换平台时重置模型选择
- if (!availableModels.value[selectedModel.value]) {
- selectedModel.value = Object.keys(availableModels.value)[0]
+const handleModelChange = (value) => {
+ if (activePlatform.value === 'tencent') {
+ const model = configs.value.tencent.models.find((model) => model.name === value)
+ currentPower.value = model.power
+ tencentForm.value.power = model.power
+ } else {
+ const model = configs.value.gitee.models.find((model) => model.name === value)
+ currentPower.value = model.power
+ giteeForm.value.power = model.power
}
}
-const handleImageChange = (files) => {
- currentImage.value = files
-}
-
-const handleModelChange = () => {
- // 模型改变时的处理逻辑
+const handlePlatformChange = (value) => {
+ currentPower.value = value === 'tencent' ? tencentForm.value.power : giteeForm.value.power
}
const generate3D = async () => {
- if (!canGenerate.value) {
+ if (currentPower.value === 0) {
ElMessage.warning('请完善生成参数')
return
}
+ if (!currentPrompt.value.trim()) {
+ ElMessage.warning('请输入提示词')
+ return
+ }
+
+ if (!selectedModel.value) {
+ ElMessage.warning('请选择输出格式')
+ return
+ }
+
try {
- generating.value = true
+ loading.value = true
const requestData = {
type: activePlatform.value,
@@ -263,15 +410,35 @@ const generate3D = async () => {
prompt: currentPrompt.value,
image_url: currentImage.value[0]?.url || '',
power: currentPower.value,
+ ...currentForm.value, // 包含所有表单参数
}
- const response = await httpPost('/api/3d/generate', requestData)
+ const response = await httpPost('/api/ai3d/generate', requestData)
if (response.code === 0) {
ElMessage.success('任务创建成功')
// 清空表单
- currentImage.value = []
- currentPrompt.value = ''
+ tencentForm.value = {
+ prompt: '',
+ image_url: '',
+ model: '',
+ power: 0,
+ file_format: '',
+ enable_pbr: false,
+ }
+ giteeForm.value = {
+ prompt: '',
+ image_url: '',
+ model: '',
+ power: 0,
+ file_format: '',
+ texture: false,
+ seed: 1234,
+ num_inference_steps: 5,
+ guidance_scale: 7.5,
+ octree_resolution: 128,
+ }
+ currentPower.value = 0
// 刷新任务列表
loadTasks()
} else {
@@ -280,13 +447,13 @@ const generate3D = async () => {
} catch (error) {
ElMessage.error('创建任务失败:' + error.message)
} finally {
- generating.value = false
+ loading.value = false
}
}
const loadTasks = async () => {
try {
- const response = await httpGet('/api/3d/jobs', {
+ const response = await httpGet('/api/ai3d/jobs', {
page: currentPage.value,
page_size: pageSize.value,
})
@@ -304,13 +471,13 @@ const refreshTasks = () => {
loadTasks()
}
-const handleSizeChange = (size) => {
+const handlePageSizeChange = (size) => {
pageSize.value = size
currentPage.value = 1
loadTasks()
}
-const handleCurrentChange = (page) => {
+const handleCurrentPageChange = (page) => {
currentPage.value = page
loadTasks()
}
@@ -323,7 +490,7 @@ const deleteTask = async (taskId) => {
type: 'warning',
})
- const response = await httpGet(`/api/3d/job/${taskId}/delete`)
+ const response = await httpGet(`/api/ai3d/job/${taskId}/delete`)
if (response.code === 0) {
ElMessage.success('删除成功')
loadTasks()
@@ -347,7 +514,7 @@ const closePreview = () => {
currentPreviewTask.value = null
}
-const download3D = async (task) => {
+const download = async (task) => {
if (!task.img_url) {
ElMessage.warning('模型文件不存在')
return
@@ -372,7 +539,7 @@ const download3D = async (task) => {
const downloadCurrentModel = () => {
if (currentPreviewTask.value) {
- download3D(currentPreviewTask.value)
+ download(currentPreviewTask.value)
}
}
@@ -386,18 +553,14 @@ const getStatusText = (status) => {
return statusMap[status] || status
}
-const getPromptFromParams = (paramsStr) => {
- try {
- const params = JSON.parse(paramsStr)
- return params.prompt || ''
- } catch {
- return ''
- }
-}
-
// 生命周期
onMounted(() => {
- loadTasks()
+ loadConfigs()
+ checkSession()
+ .then(() => {
+ loadTasks()
+ })
+ .catch(() => {})
})
@@ -446,6 +609,37 @@ onMounted(() => {
color: #333;
}
}
+
+ .advanced-toggle-btn {
+ padding: 0;
+ font-size: 14px;
+ color: #409eff;
+ border: none;
+ background: none;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ transition: all 0.3s ease;
+
+ &:hover {
+ color: #66b1ff;
+ background: #f0f9ff;
+ border-radius: 4px;
+ padding: 4px 8px;
+ }
+
+ i {
+ font-size: 12px;
+ transition: transform 0.3s ease;
+ }
+ }
+
+ .advanced-params {
+ margin-left: 16px;
+ padding: 10px 16px;
+ border-left: 3px solid #e4e7ed;
+ margin-top: 8px;
+ }
}
.power-display {