mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-04-12 06:04:26 +08:00
19 KiB
19 KiB
开发 3D 图片生成功能
对接 3D 图片生成接口,为当前系统添加 3D 模型生成功能,默认支持腾讯云和 Gitee 的图生 3D API 接口。
要求
- 完成数据库设计,后端 API 设计,前端页面设计。
- 完成前端功能页面以及后台管理页面,具体设计结构可以参考即梦 AI,在对应的模块建立独立的模块 。
- 页面设计要精美,但是整体风格要跟整站风格一致。
- 支持前端 3D 模型预览,支持 3D 模型下载。
腾讯云图生 3D API 接口文档
- 提交任务: https://cloud.tencent.com/document/product/1804/120826
- 查询任务: https://cloud.tencent.com/document/product/1804/120827
- Golang SDK: https://gitee.com/TencentCloud/tencentcloud-sdk-go/blob/master/tencentcloud/ai3d/v20250513/client.go 依赖已经安装到本地了,如果你无法读取远程文件,下面是文件主要内容:
client.go
// Copyright (c) 2017-2025 Tencent. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v20250513
import (
"context"
"errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
)
const APIVersion = "2025-05-13"
type Client struct {
common.Client
}
// Deprecated
func NewClientWithSecretId(secretId, secretKey, region string) (client *Client, err error) {
cpf := profile.NewClientProfile()
client = &Client{}
client.Init(region).WithSecretId(secretId, secretKey).WithProfile(cpf)
return
}
func NewClient(credential common.CredentialIface, region string, clientProfile *profile.ClientProfile) (client *Client, err error) {
client = &Client{}
client.Init(region).
WithCredential(credential).
WithProfile(clientProfile)
return
}
func NewQueryHunyuanTo3DJobRequest() (request *QueryHunyuanTo3DJobRequest) {
request = &QueryHunyuanTo3DJobRequest{
BaseRequest: &tchttp.BaseRequest{},
}
request.Init().WithApiInfo("ai3d", APIVersion, "QueryHunyuanTo3DJob")
return
}
func NewQueryHunyuanTo3DJobResponse() (response *QueryHunyuanTo3DJobResponse) {
response = &QueryHunyuanTo3DJobResponse{
BaseResponse: &tchttp.BaseResponse{},
}
return
}
// QueryHunyuanTo3DJob
// 混元生3D接口,基于混元大模型,根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后,才能开始处理下一个任务。
func (c *Client) QueryHunyuanTo3DJob(request *QueryHunyuanTo3DJobRequest) (response *QueryHunyuanTo3DJobResponse, err error) {
return c.QueryHunyuanTo3DJobWithContext(context.Background(), request)
}
// QueryHunyuanTo3DJob
// 混元生3D接口,基于混元大模型,根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后,才能开始处理下一个任务。
func (c *Client) QueryHunyuanTo3DJobWithContext(ctx context.Context, request *QueryHunyuanTo3DJobRequest) (response *QueryHunyuanTo3DJobResponse, err error) {
if request == nil {
request = NewQueryHunyuanTo3DJobRequest()
}
c.InitBaseRequest(&request.BaseRequest, "ai3d", APIVersion, "QueryHunyuanTo3DJob")
if c.GetCredential() == nil {
return nil, errors.New("QueryHunyuanTo3DJob require credential")
}
request.SetContext(ctx)
response = NewQueryHunyuanTo3DJobResponse()
err = c.Send(request, response)
return
}
func NewSubmitHunyuanTo3DJobRequest() (request *SubmitHunyuanTo3DJobRequest) {
request = &SubmitHunyuanTo3DJobRequest{
BaseRequest: &tchttp.BaseRequest{},
}
request.Init().WithApiInfo("ai3d", APIVersion, "SubmitHunyuanTo3DJob")
return
}
func NewSubmitHunyuanTo3DJobResponse() (response *SubmitHunyuanTo3DJobResponse) {
response = &SubmitHunyuanTo3DJobResponse{
BaseResponse: &tchttp.BaseResponse{},
}
return
}
// SubmitHunyuanTo3DJob
// 混元生3D接口,基于混元大模型,根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后,才能开始处理下一个任务。
func (c *Client) SubmitHunyuanTo3DJob(request *SubmitHunyuanTo3DJobRequest) (response *SubmitHunyuanTo3DJobResponse, err error) {
return c.SubmitHunyuanTo3DJobWithContext(context.Background(), request)
}
// SubmitHunyuanTo3DJob
// 混元生3D接口,基于混元大模型,根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发,代表最多能同时处理1个已提交的任务,上一个任务处理完毕后,才能开始处理下一个任务。
func (c *Client) SubmitHunyuanTo3DJobWithContext(ctx context.Context, request *SubmitHunyuanTo3DJobRequest) (response *SubmitHunyuanTo3DJobResponse, err error) {
if request == nil {
request = NewSubmitHunyuanTo3DJobRequest()
}
c.InitBaseRequest(&request.BaseRequest, "ai3d", APIVersion, "SubmitHunyuanTo3DJob")
if c.GetCredential() == nil {
return nil, errors.New("SubmitHunyuanTo3DJob require credential")
}
request.SetContext(ctx)
response = NewSubmitHunyuanTo3DJobResponse()
err = c.Send(request, response)
return
}
model.go
// Copyright (c) 2017-2025 Tencent. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v20250513
import (
tcerr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json"
)
type File3D struct {
// 文件格式
Type *string `json:"Type,omitnil,omitempty" name:"Type"`
// 文件的Url(有效期24小时)
Url *string `json:"Url,omitnil,omitempty" name:"Url"`
// 预览图片Url
PreviewImageUrl *string `json:"PreviewImageUrl,omitnil,omitempty" name:"PreviewImageUrl"`
}
// Predefined struct for user
type QueryHunyuanTo3DJobRequestParams struct {
// 任务ID。
JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
}
type QueryHunyuanTo3DJobRequest struct {
*tchttp.BaseRequest
// 任务ID。
JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
}
func (r *QueryHunyuanTo3DJobRequest) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *QueryHunyuanTo3DJobRequest) FromJsonString(s string) error {
f := make(map[string]interface{})
if err := json.Unmarshal([]byte(s), &f); err != nil {
return err
}
delete(f, "JobId")
if len(f) > 0 {
return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "QueryHunyuanTo3DJobRequest has unknown keys!", "")
}
return json.Unmarshal([]byte(s), &r)
}
// Predefined struct for user
type QueryHunyuanTo3DJobResponseParams struct {
// 任务状态。WAIT:等待中,RUN:执行中,FAIL:任务失败,DONE:任务成功
Status *string `json:"Status,omitnil,omitempty" name:"Status"`
// 错误码
ErrorCode *string `json:"ErrorCode,omitnil,omitempty" name:"ErrorCode"`
// 错误信息
ErrorMessage *string `json:"ErrorMessage,omitnil,omitempty" name:"ErrorMessage"`
// 生成的3D文件数组。
ResultFile3Ds []*File3D `json:"ResultFile3Ds,omitnil,omitempty" name:"ResultFile3Ds"`
// 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。
RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
}
type QueryHunyuanTo3DJobResponse struct {
*tchttp.BaseResponse
Response *QueryHunyuanTo3DJobResponseParams `json:"Response"`
}
func (r *QueryHunyuanTo3DJobResponse) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *QueryHunyuanTo3DJobResponse) FromJsonString(s string) error {
return json.Unmarshal([]byte(s), &r)
}
// Predefined struct for user
type SubmitHunyuanTo3DJobRequestParams struct {
// 文生3D,3D内容的描述,中文正向提示词。
// 最多支持1024个 utf-8 字符。
// 文生3D, image、image_url和 prompt必填其一,且prompt和image/image_url不能同时存在。
Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
// 输入图 Base64 数据。
// 大小:单边分辨率要求不小于128,不大于5000。大小不超过8m(base64编码后会大30%左右,建议实际输入图片不超过6m)
// 格式:jpg,png,jpeg,webp。
// ImageBase64、ImageUrl和 Prompt必填其一,且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageBase64 *string `json:"ImageBase64,omitnil,omitempty" name:"ImageBase64"`
// 输入图Url。
// 大小:单边分辨率要求不小于128,不大于5000。大小不超过8m(base64编码后会大30%左右,建议实际输入图片不超过6m)
// 格式:jpg,png,jpeg,webp。
// ImageBase64/ImageUrl和 Prompt必填其一,且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageUrl *string `json:"ImageUrl,omitnil,omitempty" name:"ImageUrl"`
// 多视角的模型图片,视角参考值:
// left:左视图;
// right:右视图;
// back:后视图;
//
// 每个视角仅限制一张图片。
// ●图片大小限制:编码后大小不可超过8M。
// ●图片分辨率限制:单边分辨率小于5000且大于128。
// ●支持图片格式:支持jpg或png
MultiViewImages []*ViewImage `json:"MultiViewImages,omitnil,omitempty" name:"MultiViewImages"`
// 生成模型的格式,仅限制生成一种格式。
// 生成模型文件组默认返回obj格式。
// 可选值:OBJ,GLB,STL,USDZ,FBX,MP4。
ResultFormat *string `json:"ResultFormat,omitnil,omitempty" name:"ResultFormat"`
// 是否开启 PBR材质生成,默认 false。
EnablePBR *bool `json:"EnablePBR,omitnil,omitempty" name:"EnablePBR"`
}
type SubmitHunyuanTo3DJobRequest struct {
*tchttp.BaseRequest
// 文生3D,3D内容的描述,中文正向提示词。
// 最多支持1024个 utf-8 字符。
// 文生3D, image、image_url和 prompt必填其一,且prompt和image/image_url不能同时存在。
Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
// 输入图 Base64 数据。
// 大小:单边分辨率要求不小于128,不大于5000。大小不超过8m(base64编码后会大30%左右,建议实际输入图片不超过6m)
// 格式:jpg,png,jpeg,webp。
// ImageBase64、ImageUrl和 Prompt必填其一,且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageBase64 *string `json:"ImageBase64,omitnil,omitempty" name:"ImageBase64"`
// 输入图Url。
// 大小:单边分辨率要求不小于128,不大于5000。大小不超过8m(base64编码后会大30%左右,建议实际输入图片不超过6m)
// 格式:jpg,png,jpeg,webp。
// ImageBase64/ImageUrl和 Prompt必填其一,且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageUrl *string `json:"ImageUrl,omitnil,omitempty" name:"ImageUrl"`
// 多视角的模型图片,视角参考值:
// left:左视图;
// right:右视图;
// back:后视图;
//
// 每个视角仅限制一张图片。
// ●图片大小限制:编码后大小不可超过8M。
// ●图片分辨率限制:单边分辨率小于5000且大于128。
// ●支持图片格式:支持jpg或png
MultiViewImages []*ViewImage `json:"MultiViewImages,omitnil,omitempty" name:"MultiViewImages"`
// 生成模型的格式,仅限制生成一种格式。
// 生成模型文件组默认返回obj格式。
// 可选值:OBJ,GLB,STL,USDZ,FBX,MP4。
ResultFormat *string `json:"ResultFormat,omitnil,omitempty" name:"ResultFormat"`
// 是否开启 PBR材质生成,默认 false。
EnablePBR *bool `json:"EnablePBR,omitnil,omitempty" name:"EnablePBR"`
}
func (r *SubmitHunyuanTo3DJobRequest) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *SubmitHunyuanTo3DJobRequest) FromJsonString(s string) error {
f := make(map[string]interface{})
if err := json.Unmarshal([]byte(s), &f); err != nil {
return err
}
delete(f, "Prompt")
delete(f, "ImageBase64")
delete(f, "ImageUrl")
delete(f, "MultiViewImages")
delete(f, "ResultFormat")
delete(f, "EnablePBR")
if len(f) > 0 {
return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "SubmitHunyuanTo3DJobRequest has unknown keys!", "")
}
return json.Unmarshal([]byte(s), &r)
}
// Predefined struct for user
type SubmitHunyuanTo3DJobResponseParams struct {
// 任务ID(有效期24小时)
JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
// 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。
RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
}
type SubmitHunyuanTo3DJobResponse struct {
*tchttp.BaseResponse
Response *SubmitHunyuanTo3DJobResponseParams `json:"Response"`
}
func (r *SubmitHunyuanTo3DJobResponse) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *SubmitHunyuanTo3DJobResponse) FromJsonString(s string) error {
return json.Unmarshal([]byte(s), &r)
}
type ViewImage struct {
// 视角类型。
// 取值:back、left、right
ViewType *string `json:"ViewType,omitnil,omitempty" name:"ViewType"`
// 图片Url地址
ViewImageUrl *string `json:"ViewImageUrl,omitnil,omitempty" name:"ViewImageUrl"`
}
Gitee 图生 3D API 接口文档
- 提交任务: https://ai.gitee.com/docs/openapi/v1#tag/3d-%E7%94%9F%E6%88%90/post/async/image-to-3d
- 查询任务:https://ai.gitee.com/docs/openapi/v1#tag/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1/get/task/{task_id}/get
首先,你需要认真阅读上述接口文档,然后按照接口文档的示例代码实现腾讯云和 Gitee 的图生 3D API 接口,并且将接口集成到现有的系统中。
📋 功能概述
为现有的GeekAI-Plus系统添加3D图片生成功能,集成腾讯云和Gitee的图生3D API接口,包含完整的前后端功能和管理界面。
🗄️ 数据库设计
新增数据表:geekai_3d_jobs
- id (uint): 主键
- type (string): API类型 (tencent/gitee)
- user_id (uint): 用户ID
- power (int): 消耗算力
- task_id (string): 第三方任务ID
- img_url (string): 生成的3D模型文件地址
- model (string): 使用的3D模型类型
- status (string): 任务状态
- err_msg (string): 错误信息
- params (JSON): 任务参数(包含输入图片、提示词等所有参数)
- created_at (int64): 创建时间
🔧 后端API实现
路由结构:/api/3d/*
- POST /api/3d/generate - 创建3D生成任务
- GET /api/3d/jobs - 获取任务列表
- GET /api/3d/job/{id} - 获取任务详情
- GET /api/3d/download/{id} - 下载3D模型
- DELETE /api/3d/job/{id} - 删除任务
核心服务:
- service/3d/tencent_client.go - 腾讯云3D API客户端
- service/3d/gitee_client.go - Gitee 3D API客户端
- service/3d/service.go - 3D生成服务统一接口
- handler/3d_handler.go - HTTP处理器
- store/vo/3d_job.go - 数据模型
🎨 前端界面设计
用户端页面:/3d - 3D生成主页面
- 参考JiMeng.vue的设计风格和布局
- 使用CustomTab组件分离平台参数:
- Tab 1: "魔力方舟" (Gitee平台参数)
- Tab 2: "腾讯混元" (腾讯云平台参数)
- 每个Tab内包含:
- 图片上传区域
- 模型选择下拉框
- 算力消耗实时显示
- 平台特定的参数配置
- 生成按钮
- 任务列表和状态显示
- 集成3D模型预览器 (three.js)
- 模型下载功能
移动端适配:
- mobile/3dCreate.vue - 移动端3D生成页面
- 保持Tab切换功能
- 响应式设计,触控优化
🛠️ 管理后台
管理功能:
- admin/3d/3dJobs.vue - 任务管理列表
- admin/3d/3dSetting.vue - API配置页面
- 模型配置管理:
- 分平台配置API秘钥和模型列表
- 设置每个模型的算力消耗值
- API密钥和端点配置
🔌 API集成方案
腾讯云集成:
- 使用官方Golang SDK
- 支持异步任务提交和状态查询
Gitee集成:
- HTTP客户端实现
- 标准化响应处理
🎯 核心功能特性
- 平台切换:通过CustomTab在魔力方舟和腾讯混元间切换
- 模型选择:每个平台支持不同的3D模型
- 动态算力:切换模型时实时更新算力消耗显示
- 参数隔离:不同平台的参数配置完全分离
- 3D预览:集成Three.js实现模型预览
- 统一体验:保持与JiMeng.vue相似的交互风格
📱 用户体验
- JiMeng.vue风格的简洁界面
- Tab切换流畅的平台选择
- 模型选择时算力消耗实时更新
- 支持拖拽上传图片
- 实时任务状态显示
- 3D模型交互式预览
这个设计将创建一个与现有JiMeng功能风格一致的3D生成模块,通过Tab分离实现平台参数的清晰管理。
整个实现严格按照现有系统的代码规范和架构模式,与 JiMeng 等模块保持一致的用户体验!