Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into feature/auth
This commit is contained in:
@@ -66,7 +66,7 @@ func (l *GetMapLibraryListLogic) GetMapLibraryList(req *types.Request, userinfo
|
||||
if tagIndex, ok := mapTag[*v.TagId]; ok {
|
||||
data.Tag = &types.MapLibraryListTag{
|
||||
Id: templateTagList[tagIndex].Id,
|
||||
Title: *templateTagList[tagIndex].Title,
|
||||
Title: *templateTagList[tagIndex].TemplateTag,
|
||||
}
|
||||
}
|
||||
//解析info
|
||||
|
||||
@@ -83,7 +83,7 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
|
||||
for _, v := range productTemplateTags {
|
||||
list = append(list, types.GetProductTemplateTagsRsp{
|
||||
Id: v.Id,
|
||||
TemplateTag: *v.Title,
|
||||
TemplateTag: *v.TemplateTag,
|
||||
Cover: *v.Cover,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/format"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"context"
|
||||
@@ -62,13 +61,7 @@ func (l *GetTemplatevDetailLogic) GetTemplatevDetail(req *types.GetTemplatevDeta
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product template info")
|
||||
}
|
||||
//获取模板标签
|
||||
templateTagModel := gmodel.NewFsProductTemplateTagsModel(l.svcCtx.MysqlConn)
|
||||
tagId, err := strconv.ParseInt(*templatev2Info.Tag, 10, 64)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "parse int tag id err")
|
||||
}
|
||||
templateTagInfo, err := templateTagModel.FindOne(l.ctx, tagId, "id,title")
|
||||
templateTagInfo, err := l.svcCtx.AllModels.FsProductTemplateTags.FindOneByTagName(l.ctx, *templatev2Info.TemplateTag, "id,title")
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "template tag info is not exists")
|
||||
@@ -125,7 +118,7 @@ func (l *GetTemplatevDetailLogic) GetTemplatevDetail(req *types.GetTemplatevDeta
|
||||
}
|
||||
templateInfoRsp["tag"] = map[string]interface{}{
|
||||
"id": templateTagInfo.Id,
|
||||
"title": *templateTagInfo.Title,
|
||||
"title": *templateTagInfo.TemplateTag,
|
||||
}
|
||||
response := types.GetTemplatevDetailRsp{
|
||||
ProductModelInfo: productModelInfoRsp,
|
||||
|
||||
@@ -109,8 +109,8 @@ func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, useri
|
||||
tagIds := make([]int64, 0, len(productTemplateList))
|
||||
for _, v := range productTemplateList {
|
||||
mapTemplateModelId[*v.ModelId] = struct{}{}
|
||||
if v.Tag != nil && *v.Tag != "" {
|
||||
tagId, err := strconv.ParseInt(*v.Tag, 10, 64)
|
||||
if v.TemplateTag != nil && *v.TemplateTag != "" {
|
||||
tagId, err := strconv.ParseInt(*v.TemplateTag, 10, 64)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "tag is not a number")
|
||||
@@ -296,7 +296,7 @@ func (l *GetProductInfoLogic) GetProductInfo(req *types.GetProductInfoReq, useri
|
||||
partListRsp = append(partListRsp, thisInfo)
|
||||
}
|
||||
tagName := ""
|
||||
if tagData, ok := mapTag[*tmp.Tag]; ok {
|
||||
if tagData, ok := mapTag[*tmp.TemplateTag]; ok {
|
||||
tagName = *tagData.Title
|
||||
}
|
||||
//按照材质和尺寸来存放模板信息
|
||||
|
||||
@@ -127,7 +127,7 @@ func (l *GetRecommandProductListLogic) GetRecommandProductList(req *types.GetRec
|
||||
mapTagProp := make(map[int64][]types.CoverDefaultItem)
|
||||
for _, v := range productTagPropList {
|
||||
mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{
|
||||
Tag: v.Title,
|
||||
Tag: v.TemplateTag,
|
||||
Cover: *v.Cover,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR
|
||||
}
|
||||
for _, v := range productTagPropList {
|
||||
mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{
|
||||
Tag: v.Title,
|
||||
Tag: v.TemplateTag,
|
||||
Cover: *v.Cover,
|
||||
})
|
||||
}
|
||||
@@ -312,6 +312,10 @@ func (l *GetTagProductListLogic) organizationLevelRelation(minLevel int, mapTagL
|
||||
//最终值提取最高级别那一层出来
|
||||
rspList := make([]types.TagItem, 0, len(mapTagLevel))
|
||||
for prefix, _ := range mapTop {
|
||||
//大类下没有任何产品则不显示
|
||||
if len(mapTagLevel[prefix].TagProductList) == 0 {
|
||||
continue
|
||||
}
|
||||
rspList = append(rspList, *mapTagLevel[prefix])
|
||||
}
|
||||
//排序
|
||||
|
||||
@@ -67,6 +67,15 @@ func (l *GetTemplateByPidLogic) GetTemplateByPid(req *types.GetTemplateByPidReq,
|
||||
} else { //指定物料
|
||||
sizeIds = append(sizeIds, req.ProductSizeId)
|
||||
}
|
||||
//获取templatetag信息
|
||||
templateTagInfo, err := l.svcCtx.AllModels.FsProductTemplateTags.FindOne(l.ctx, req.ProductTemplateTagId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "template tag is not exists")
|
||||
}
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "failed to get template tag")
|
||||
}
|
||||
//根据尺寸id获取模型
|
||||
modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllBySizeIdsTag(l.ctx, sizeIds, constants.TAG_MODEL)
|
||||
if err != nil {
|
||||
@@ -83,7 +92,7 @@ func (l *GetTemplateByPidLogic) GetTemplateByPid(req *types.GetTemplateByPidReq,
|
||||
mapModel[v.Id] = k
|
||||
}
|
||||
//查询模型ids下对应tag标签的模板
|
||||
templateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByModelIdsTemplateTag(l.ctx, modelIds, fmt.Sprintf("%d", req.ProductTemplateTagId), "")
|
||||
templateList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByModelIdsTemplateTag(l.ctx, modelIds, *templateTagInfo.TemplateTag, "")
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get template list")
|
||||
|
||||
@@ -156,7 +156,7 @@ func (l *HomePageRecommendProductListLogic) HomePageRecommendProductList(req *ty
|
||||
mapTagProp := make(map[int64][]types.CoverDefaultItem)
|
||||
for _, v := range productTagPropList {
|
||||
mapTagProp[*v.ProductId] = append(mapTagProp[*v.ProductId], types.CoverDefaultItem{
|
||||
Tag: v.Title,
|
||||
Tag: v.TemplateTag,
|
||||
Cover: *v.Cover,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
package consumer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/initalize"
|
||||
"fusenapi/server/render/internal/svc"
|
||||
"fusenapi/service/repositories"
|
||||
"fusenapi/utils/websocket_data"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 这里请求的py接口返回数据
|
||||
type pythonApiRsp struct {
|
||||
Id string `json:"id"` //物料模板的id
|
||||
LogoUrl string `json:"logo_url"` //logo地址
|
||||
Result string `json:"result"` //图片base64
|
||||
}
|
||||
|
||||
// 消费渲染需要组装的数据
|
||||
type MqConsumerRenderAssemble struct {
|
||||
}
|
||||
|
||||
func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logx.Error("MqConsumerRenderAssemble panic:", err)
|
||||
}
|
||||
}()
|
||||
logx.Info("收到需要组装的消息:", string(data))
|
||||
var parseInfo websocket_data.AssembleRenderData
|
||||
if err := json.Unmarshal(data, &parseInfo); err != nil {
|
||||
logx.Error("MqConsumerRenderAssemble数据格式错误:", err)
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
val := ctx.Value("svcctx")
|
||||
if val == nil {
|
||||
logx.Error("svcctx is nil")
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
svcCtx, ok := val.(*svc.ServiceContext)
|
||||
if !ok {
|
||||
logx.Error("svcctx is nil!!")
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
rabbitmq := initalize.RabbitMqHandle{}
|
||||
//根据templateTag获取templateTagId(后续模板表的tag改成template_tag后可能就不需要这个步骤了)
|
||||
templateTag, err := svcCtx.AllModels.FsProductTemplateTags.FindOneByTagName(ctx, parseInfo.RenderData.TemplateTag)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
logx.Error("can`t find template tag info by template tag:", parseInfo.RenderData.TemplateTag)
|
||||
return nil
|
||||
}
|
||||
logx.Error("failed to get template tag info")
|
||||
return nil
|
||||
}
|
||||
//获取模板(模板标签下的对一个物料的的模板)
|
||||
productTemplate, err := svcCtx.AllModels.FsProductTemplateV2.FindOneByProductIdTagIdWithSizeTable(ctx, parseInfo.RenderData.ProductId, fmt.Sprintf("%d", templateTag.Id))
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
logx.Error("template info is not found")
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
logx.Error("failed to get template info:", err)
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
//获取刀版图
|
||||
res, err := svcCtx.Repositories.ImageHandle.LogoCombine(ctx, &repositories.LogoCombineReq{
|
||||
UserId: parseInfo.RenderData.UserId,
|
||||
GuestId: parseInfo.RenderData.GuestId,
|
||||
TemplateId: productTemplate.Id,
|
||||
TemplateTag: parseInfo.RenderData.TemplateTag,
|
||||
Website: parseInfo.RenderData.Website,
|
||||
Slogan: parseInfo.RenderData.Slogan,
|
||||
Address: parseInfo.RenderData.Address,
|
||||
Phone: parseInfo.RenderData.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Error("合成刀版图失败:", err)
|
||||
return nil
|
||||
}
|
||||
combineImage := "" //刀版图
|
||||
if res != nil && res.ResourceUrl != nil {
|
||||
combineImage = *res.ResourceUrl
|
||||
} else {
|
||||
logx.Error("合成刀版图失败,合成的刀版图是空指针:", err)
|
||||
return nil
|
||||
}
|
||||
logx.Info("合成刀版图成功:", *res.ResourceUrl)
|
||||
//获取渲染设置信息
|
||||
element, err := svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(ctx, *productTemplate.ModelId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
logx.Error("element info is not found,model_id = ?", *productTemplate.ModelId)
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
logx.Error("failed to get element list,", err)
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
//组装数据
|
||||
refletion := -1
|
||||
if element.Refletion != nil && *element.Refletion != "" {
|
||||
refletion, err = strconv.Atoi(*element.Refletion)
|
||||
}
|
||||
//组装data数据
|
||||
var mode map[string]interface{}
|
||||
if element.Mode != nil && *element.Mode != "" {
|
||||
if err = json.Unmarshal([]byte(*element.Mode), &mode); err != nil {
|
||||
logx.Error("faile to parse element mode json:", err)
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
}
|
||||
tempData := make([]map[string]interface{}, 0, 3)
|
||||
if element.Base != nil && *element.Base != "" {
|
||||
tempData = append(tempData, map[string]interface{}{
|
||||
"name": "model",
|
||||
"data": "0," + combineImage + "," + *element.Base,
|
||||
"type": "other",
|
||||
"layer": "0",
|
||||
"is_update": 1,
|
||||
"mode": mode["model"],
|
||||
})
|
||||
}
|
||||
if element.Shadow != nil && *element.Shadow != "" {
|
||||
tempData = append(tempData, map[string]interface{}{
|
||||
"name": "shadow",
|
||||
"data": *element.Shadow,
|
||||
"type": "other",
|
||||
"layer": "0",
|
||||
"is_update": 0,
|
||||
"mode": mode["shadow"],
|
||||
})
|
||||
}
|
||||
if element.ModelP != nil && *element.ModelP != "" {
|
||||
tempData = append(tempData, map[string]interface{}{
|
||||
"name": "model_P",
|
||||
"data": "0," + *element.ModelP,
|
||||
"type": "other",
|
||||
"layer": "0",
|
||||
"is_update": 0,
|
||||
"mode": mode["model_P"],
|
||||
})
|
||||
}
|
||||
result := []interface{}{
|
||||
map[string]interface{}{
|
||||
"light": *element.Light,
|
||||
"refletion": refletion,
|
||||
"scale": *element.Scale,
|
||||
"sku_id": parseInfo.RenderData.ProductId,
|
||||
"tid": *element.Title,
|
||||
"rotation": *element.Rotation,
|
||||
"filePath": "", //todo 文件路径,针对千人千面
|
||||
"data": tempData,
|
||||
},
|
||||
}
|
||||
sendData := map[string]interface{}{
|
||||
"id": parseInfo.TaskId,
|
||||
"order_id": 0,
|
||||
"user_id": parseInfo.RenderData.UserId,
|
||||
"guest_id": parseInfo.RenderData.GuestId,
|
||||
"sku_ids": []int64{parseInfo.RenderData.ProductId},
|
||||
"tids": []string{*element.Title},
|
||||
"data": result,
|
||||
"is_thousand_face": 0,
|
||||
"folder": "", //todo 千人千面需要使用
|
||||
}
|
||||
b, _ := json.Marshal(sendData)
|
||||
if err = rabbitmq.SendMsg(constants.RABBIT_MQ_TO_UNITY, b); err != nil {
|
||||
logx.Error("发送渲染组装数据到rabbitmq失败:", err)
|
||||
return nil //不返回错误就删除消息
|
||||
}
|
||||
logx.Info("发送渲染组装数据到unity成功")
|
||||
return nil
|
||||
}
|
||||
@@ -12,11 +12,6 @@ import (
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/render/render_notify",
|
||||
Handler: RenderNotifyHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/render/get_face_slice",
|
||||
|
||||
@@ -5,19 +5,6 @@ import (
|
||||
"fusenapi/utils/basic"
|
||||
)
|
||||
|
||||
type RequestToUnity struct {
|
||||
}
|
||||
|
||||
type RequestReadImages struct {
|
||||
}
|
||||
|
||||
type RenderNotifyReq struct {
|
||||
TaskId string `json:"task_id"` //任务id
|
||||
UserId int64 `json:"user_id"`
|
||||
GuestId int64 `json:"guest_id"`
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/server/render/consumer"
|
||||
"net/http"
|
||||
|
||||
"fusenapi/utils/auth"
|
||||
@@ -30,12 +27,6 @@ func main() {
|
||||
defer server.Stop()
|
||||
|
||||
ctx := svc.NewServiceContext(c)
|
||||
//消费渲染前组装数据队列
|
||||
ctx1 := context.Background()
|
||||
ctx2, cancel := context.WithCancel(ctx1)
|
||||
ctx2 = context.WithValue(ctx2, "svcctx", ctx)
|
||||
defer cancel()
|
||||
go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, &consumer.MqConsumerRenderAssemble{})
|
||||
handler.RegisterHandlers(server, ctx)
|
||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||
server.Start()
|
||||
|
||||
@@ -65,7 +65,8 @@ func (l *LogoCombineLogic) LogoCombine(req *types.LogoCombineReq, userinfo *auth
|
||||
Slogan: req.Slogan,
|
||||
Phone: req.Phone,
|
||||
Address: req.Address,
|
||||
Qrcode: req.Qrcode,
|
||||
|
||||
Qrcode: req.Qrcode,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -4,9 +4,6 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// var configFile = flag.String("f", "etc/home-user-auth.yaml", "the config file")
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
// log.Println(model.RawFieldNames[FsCanteenType]())
|
||||
main()
|
||||
}
|
||||
|
||||
@@ -83,8 +83,10 @@ func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, useri
|
||||
fsResource.ResourceUrl = &req.ResourceUrl
|
||||
fsResource.Metadata = &req.Metadata
|
||||
fsResource.ApiType = &req.ApiType
|
||||
fsResource.Source = &req.Source
|
||||
fsResource.BucketName = bucketName
|
||||
fsResource.Version = &version
|
||||
|
||||
if resourceInfo.ResourceId == "" {
|
||||
_, err = resourceModelTS.BuilderCreate(ctx, transBuilder, fsResource)
|
||||
} else {
|
||||
|
||||
@@ -90,6 +90,7 @@ func (l *UploadFileBackendLogic) UploadFileBackend(req *types.UploadFileBackendR
|
||||
ApiType: req.ApiType,
|
||||
UserId: userId,
|
||||
GuestId: guestId,
|
||||
Source: req.Source,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -77,6 +77,7 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri
|
||||
ApiType: req.ApiType,
|
||||
UserId: userId,
|
||||
GuestId: guestId,
|
||||
Source: req.Source,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -123,6 +123,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq,
|
||||
ApiType: req.ApiType,
|
||||
Bucket: bucketName,
|
||||
HashKey: hashKey,
|
||||
Source: req.Source,
|
||||
}
|
||||
}
|
||||
}, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) {
|
||||
@@ -148,6 +149,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq,
|
||||
ApiType: req.ApiType,
|
||||
UserId: userId,
|
||||
GuestId: guestId,
|
||||
Source: uploadDataInfo.Source,
|
||||
})
|
||||
if err == nil {
|
||||
uploadUrl.Status = 1
|
||||
@@ -201,6 +203,7 @@ type UploadData struct {
|
||||
Bucket *string `json:"bucket"`
|
||||
HashKey string `json:"hash_key"`
|
||||
FileData []byte `fsfile:"data"`
|
||||
Source string `json:"source"`
|
||||
}
|
||||
|
||||
type UploadUrl struct {
|
||||
|
||||
@@ -88,6 +88,7 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us
|
||||
imageTypes["image/tiff"] = struct{}{}
|
||||
imageTypes["image/webp"] = struct{}{}
|
||||
imageTypes["image/svg+xml"] = struct{}{}
|
||||
|
||||
// 判断文件类型是否为图片
|
||||
_, ok := imageTypes[fileType]
|
||||
if !ok {
|
||||
@@ -115,6 +116,7 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us
|
||||
ApiType: 2,
|
||||
UserId: userId,
|
||||
GuestId: guestId,
|
||||
Source: "upload-logo",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -13,6 +13,7 @@ type UploadFileBaseReq struct {
|
||||
UserId int64 `form:"user_id,optional"` // 上传文件额外信息
|
||||
GuestId int64 `form:"guest_id,optional"` // 上传文件额外信息
|
||||
UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久
|
||||
Source string `form:"source"` // 上传来源
|
||||
}
|
||||
|
||||
type UploadLogoReq struct {
|
||||
@@ -28,12 +29,14 @@ type UploadFileBackendReq struct {
|
||||
FileKey string `form:"file_key"` // 上传唯一标识信息
|
||||
FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息
|
||||
Metadata string `form:"meta_data,optional"` // 上传文件额外信息
|
||||
Source string `form:"source"` // 上传来源
|
||||
}
|
||||
|
||||
type UploadFilesReq struct {
|
||||
ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内
|
||||
UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久
|
||||
UploadInfo string `form:"upload_info"` // 上传信息 json
|
||||
Source string `form:"source"` // 上传来源
|
||||
}
|
||||
|
||||
type UploadCallbackReq struct {
|
||||
@@ -43,6 +46,7 @@ type UploadCallbackReq struct {
|
||||
ResourceUrl string `form:"resource_url"` // 资源URL
|
||||
Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率
|
||||
ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内
|
||||
Source string `form:"source"` // 上传来源
|
||||
}
|
||||
|
||||
type RequestUpFile struct {
|
||||
|
||||
@@ -8,4 +8,17 @@ Auth:
|
||||
AccessSecret: fusen2023
|
||||
AccessExpire: 2592000
|
||||
RefreshAfter: 1592000
|
||||
SourceRabbitMq: amqp://rabbit001:rabbit001129@110.41.19.98:5672
|
||||
SourceRabbitMq: amqp://rabbit001:rabbit001129@110.41.19.98:5672
|
||||
AWS:
|
||||
S3:
|
||||
Credentials:
|
||||
AccessKeyID: AKIAZB2JKUXDPNRP4YT2
|
||||
Secret: sjCEv0JxATnPCxno2KNLm0X8oDc7srUR+4vkYhvm
|
||||
Token:
|
||||
BLMService:
|
||||
Url: "http://18.119.109.254:8999"
|
||||
LogoCombine:
|
||||
#Url: "http://192.168.1.7:8999/LogoCombine"
|
||||
Url: "http://18.119.109.254:8999/LogoCombine"
|
||||
Unity:
|
||||
Host: http://api.fusen.3718.cn:4050
|
||||
@@ -12,4 +12,22 @@ type Config struct {
|
||||
Auth types.Auth
|
||||
ReplicaId uint64
|
||||
SourceRabbitMq string
|
||||
AWS struct {
|
||||
S3 struct {
|
||||
Credentials struct {
|
||||
AccessKeyID string
|
||||
Secret string
|
||||
Token string
|
||||
}
|
||||
}
|
||||
}
|
||||
BLMService struct {
|
||||
Url string
|
||||
LogoCombine struct {
|
||||
Url string
|
||||
}
|
||||
}
|
||||
Unity struct {
|
||||
Host string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@ func DataTransferHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewDataTransferLogic(r.Context(), svcCtx)
|
||||
l.DataTransfer(svcCtx, w, r)
|
||||
l.DataTransfer(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
|
||||
"fusenapi/utils/basic"
|
||||
|
||||
"fusenapi/server/render/internal/logic"
|
||||
"fusenapi/server/render/internal/svc"
|
||||
"fusenapi/server/render/internal/types"
|
||||
"fusenapi/server/websocket/internal/logic"
|
||||
"fusenapi/server/websocket/internal/svc"
|
||||
"fusenapi/server/websocket/internal/types"
|
||||
)
|
||||
|
||||
func RenderNotifyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
@@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
Path: "/api/websocket/data_transfer",
|
||||
Handler: DataTransferHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/api/websocket/render_notify",
|
||||
Handler: RenderNotifyHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/initalize"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/id_generator"
|
||||
"fusenapi/utils/websocket_data"
|
||||
@@ -70,22 +68,20 @@ var (
|
||||
|
||||
// 每个连接的连接基本属性
|
||||
type wsConnectItem struct {
|
||||
conn *websocket.Conn //websocket的连接
|
||||
ctx context.Context
|
||||
rabbitMq *initalize.RabbitMqHandle
|
||||
allModels *gmodel.AllModelsGen
|
||||
closeChan chan struct{} //ws连接关闭chan
|
||||
isClose bool //是否已经关闭
|
||||
uniqueId string //ws连接唯一标识
|
||||
inChan chan []byte //接受消息缓冲通道
|
||||
outChan chan []byte //发送回客户端的消息
|
||||
mutex sync.Mutex //互斥锁
|
||||
userId int64 //用户id
|
||||
guestId int64 //游客id
|
||||
renderProperty renderProperty //扩展云渲染属性
|
||||
conn *websocket.Conn //websocket的连接
|
||||
logic *DataTransferLogic //logic
|
||||
closeChan chan struct{} //ws连接关闭chan
|
||||
isClose bool //是否已经关闭
|
||||
uniqueId string //ws连接唯一标识
|
||||
inChan chan []byte //接受消息缓冲通道
|
||||
outChan chan []byte //发送回客户端的消息
|
||||
mutex sync.Mutex //互斥锁
|
||||
userId int64 //用户id
|
||||
guestId int64 //游客id
|
||||
renderProperty renderProperty //扩展云渲染属性
|
||||
}
|
||||
|
||||
func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.ResponseWriter, r *http.Request) {
|
||||
func (l *DataTransferLogic) DataTransfer(w http.ResponseWriter, r *http.Request) {
|
||||
//升级websocket
|
||||
conn, err := upgrade.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
@@ -98,7 +94,7 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp
|
||||
userInfo *auth.UserInfo
|
||||
isAuth bool
|
||||
)
|
||||
isAuth, userInfo = l.checkAuth(svcCtx, r)
|
||||
isAuth, userInfo = l.checkAuth(r)
|
||||
if !isAuth {
|
||||
time.Sleep(time.Second * 1) //兼容下火狐
|
||||
rsp := websocket_data.DataTransferData{
|
||||
@@ -126,6 +122,8 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp
|
||||
go ws.sendLoop()
|
||||
//操作连接中渲染任务的增加/删除
|
||||
go ws.operationRenderTask()
|
||||
//消费渲染缓冲队列
|
||||
go ws.renderImage()
|
||||
//心跳
|
||||
ws.heartbeat()
|
||||
}
|
||||
@@ -138,18 +136,17 @@ func (l *DataTransferLogic) setConnPool(conn *websocket.Conn, userInfo auth.User
|
||||
uniqueId := l.getUniqueId(userInfo)
|
||||
ws := wsConnectItem{
|
||||
conn: conn,
|
||||
ctx: l.ctx,
|
||||
rabbitMq: l.svcCtx.RabbitMq,
|
||||
allModels: l.svcCtx.AllModels,
|
||||
logic: l,
|
||||
uniqueId: uniqueId,
|
||||
closeChan: make(chan struct{}, 1),
|
||||
inChan: make(chan []byte, 1000),
|
||||
outChan: make(chan []byte, 1000),
|
||||
inChan: make(chan []byte, 100),
|
||||
outChan: make(chan []byte, 100),
|
||||
userId: userInfo.UserId,
|
||||
guestId: userInfo.GuestId,
|
||||
renderProperty: renderProperty{
|
||||
renderImageTask: make(map[string]string),
|
||||
renderImageTaskCtlChan: make(chan renderImageControlChanItem, 100),
|
||||
renderChan: make(chan []byte, 100),
|
||||
},
|
||||
}
|
||||
//保存连接
|
||||
@@ -178,9 +175,9 @@ func getUserPart(userId, guestId int64) string {
|
||||
}
|
||||
|
||||
// 鉴权
|
||||
func (l *DataTransferLogic) checkAuth(svcCtx *svc.ServiceContext, r *http.Request) (isAuth bool, userInfo *auth.UserInfo) {
|
||||
func (l *DataTransferLogic) checkAuth(r *http.Request) (isAuth bool, userInfo *auth.UserInfo) {
|
||||
// 解析JWT token,并对空用户进行判断
|
||||
claims, err := svcCtx.ParseJwtToken(r)
|
||||
claims, err := l.svcCtx.ParseJwtToken(r)
|
||||
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
|
||||
if err != nil {
|
||||
return false, nil
|
||||
@@ -321,7 +318,7 @@ func (w *wsConnectItem) dealwithReciveData(data []byte) {
|
||||
switch parseInfo.T {
|
||||
//图片渲染
|
||||
case constants.WEBSOCKET_RENDER_IMAGE:
|
||||
w.renderImage(d)
|
||||
w.sendToRenderChan(d)
|
||||
//刷新重连请求恢复上次连接的标识
|
||||
case constants.WEBSOCKET_REQUEST_REUSE_LAST_CONNECT:
|
||||
w.reuseLastConnect(d)
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/utils/websocket_data"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
// 消费渲染结果数据
|
||||
type MqConsumerRenderResult struct {
|
||||
}
|
||||
|
||||
func (m *MqConsumerRenderResult) Run(ctx context.Context, data []byte) error {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logx.Error("MqConsumerRenderResult panic:", err)
|
||||
}
|
||||
}()
|
||||
logx.Info("接收到MqConsumerRenderResult数据:", string(data))
|
||||
var parseInfo websocket_data.RenderImageNotify
|
||||
if err := json.Unmarshal(data, &parseInfo); err != nil {
|
||||
logx.Error("MqConsumerRenderResult data format err:", err)
|
||||
return nil //不返回错误则就删掉该消息
|
||||
}
|
||||
//遍历websocket链接把数据传进去
|
||||
mapConnPool.Range(func(key, value any) bool {
|
||||
//断言连接
|
||||
ws, ok := value.(wsConnectItem)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
//关闭标识
|
||||
if ws.isClose {
|
||||
return true
|
||||
}
|
||||
//查询有无该渲染任务
|
||||
renderId, ok := ws.renderProperty.renderImageTask[parseInfo.TaskId]
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{
|
||||
RenderId: renderId,
|
||||
Image: parseInfo.Image,
|
||||
})
|
||||
//删除对应的需要渲染的图片map
|
||||
ws.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{
|
||||
Option: 0, //0删除 1添加
|
||||
TaskId: parseInfo.TaskId,
|
||||
RenderId: renderId,
|
||||
}
|
||||
//发送数据到out chan
|
||||
ws.sendToOutChan(b)
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/file"
|
||||
"fusenapi/utils/websocket_data"
|
||||
"time"
|
||||
|
||||
"fusenapi/server/render/internal/svc"
|
||||
"fusenapi/server/render/internal/types"
|
||||
"context"
|
||||
|
||||
"fusenapi/server/websocket/internal/svc"
|
||||
"fusenapi/server/websocket/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
@@ -55,26 +56,56 @@ func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq, userinfo *a
|
||||
AwsSession: l.svcCtx.AwsSession,
|
||||
}
|
||||
uploadRes, err := upload.UploadFileByBase64(&file.UploadBaseReq{
|
||||
Source: "unity cloud render",
|
||||
FileHash: req.TaskId,
|
||||
FileData: req.Image,
|
||||
Metadata: "",
|
||||
UploadBucket: 1,
|
||||
ApiType: 2,
|
||||
UserId: req.UserId,
|
||||
GuestId: req.GuestId,
|
||||
FileByte: nil,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeFileUploadErr, "failed to upload render resource image")
|
||||
}
|
||||
//发送消息到对应的rabbitmq
|
||||
data := websocket_data.RenderImageNotify{
|
||||
TaskId: req.TaskId,
|
||||
Image: uploadRes.ResourceUrl,
|
||||
}
|
||||
d, _ := json.Marshal(data)
|
||||
if err = l.svcCtx.RabbitMq.SendMsg(constants.RABBIT_MQ_RENDER_RESULT_DATA, d); err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to send data")
|
||||
}
|
||||
//遍历websocket链接把数据传进去
|
||||
mapConnPool.Range(func(key, value any) bool {
|
||||
//断言连接
|
||||
ws, ok := value.(wsConnectItem)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
//关闭标识
|
||||
if ws.isClose {
|
||||
return true
|
||||
}
|
||||
//查询有无该渲染任务
|
||||
renderId, ok := ws.renderProperty.renderImageTask[req.TaskId]
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{
|
||||
RenderId: renderId,
|
||||
Image: uploadRes.ResourceUrl,
|
||||
})
|
||||
deleteTask := renderImageControlChanItem{
|
||||
Option: 0, //0删除 1添加
|
||||
TaskId: req.TaskId,
|
||||
RenderId: renderId,
|
||||
}
|
||||
select {
|
||||
case <-ws.closeChan: //关闭了
|
||||
return true
|
||||
case ws.renderProperty.renderImageTaskCtlChan <- deleteTask: //删除对应的需要渲染的图片map
|
||||
//发送数据到out chan
|
||||
ws.sendToOutChan(b)
|
||||
case <-time.After(time.Second * 3): //超时丢弃
|
||||
return true
|
||||
}
|
||||
return true
|
||||
})
|
||||
logx.Info("渲染回调成功######################")
|
||||
return resp.SetStatusWithMessage(basic.CodeOK, "success")
|
||||
}
|
||||
@@ -1,20 +1,26 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/service/repositories"
|
||||
"fusenapi/utils/curl"
|
||||
"fusenapi/utils/hash"
|
||||
"fusenapi/utils/websocket_data"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 云渲染属性
|
||||
type renderProperty struct {
|
||||
renderImageTask map[string]string //需要渲染的图片任务 key是taskId val 是renderId
|
||||
renderImageTaskCtlChan chan renderImageControlChanItem //渲染任务新增移除的控制通道
|
||||
renderChan chan []byte //渲染的缓冲队列
|
||||
}
|
||||
|
||||
// 渲染任务新增移除的控制通道的数据
|
||||
@@ -24,8 +30,39 @@ type renderImageControlChanItem struct {
|
||||
RenderId string // map的val
|
||||
}
|
||||
|
||||
// 发送到渲染缓冲池
|
||||
func (w *wsConnectItem) sendToRenderChan(data []byte) {
|
||||
select {
|
||||
case <-w.closeChan: //已经关闭
|
||||
return
|
||||
case w.renderProperty.renderChan <- data:
|
||||
return
|
||||
case <-time.After(time.Second * 3):
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染发送到组装数据组装数据
|
||||
func (w *wsConnectItem) renderImage(data []byte) {
|
||||
func (w *wsConnectItem) renderImage() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logx.Error("renderImage panic:", err)
|
||||
}
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case <-w.closeChan: //已关闭
|
||||
return
|
||||
case data := <-w.renderProperty.renderChan:
|
||||
w.consumeRenderCache(data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 消费渲染缓冲数据
|
||||
func (w *wsConnectItem) consumeRenderCache(data []byte) {
|
||||
logx.Info("消费渲染数据:", string(data))
|
||||
var renderImageData websocket_data.RenderImageReqMsg
|
||||
if err := json.Unmarshal(data, &renderImageData); err != nil {
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "invalid format of websocket render image message:"+string(data)))
|
||||
@@ -49,7 +86,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
|
||||
return
|
||||
}
|
||||
//获取上传最近的logo
|
||||
userMaterial, err := w.allModels.FsUserMaterial.FindLatestOne(w.ctx, w.userId, w.guestId)
|
||||
userMaterial, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindLatestOne(w.logic.ctx, w.userId, w.guestId)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "failed to get user logo"))
|
||||
@@ -57,7 +94,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
|
||||
return
|
||||
}
|
||||
//使用默认logo(id=0)
|
||||
userMaterialDefault, err := w.allModels.FsUserMaterial.FindOneById(w.ctx, 0)
|
||||
userMaterialDefault, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindOneById(w.logic.ctx, 0)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "default logo is not exists"))
|
||||
@@ -75,10 +112,13 @@ func (w *wsConnectItem) renderImage(data []byte) {
|
||||
renderImageData.RenderData.UserId = w.userId
|
||||
renderImageData.RenderData.GuestId = w.guestId
|
||||
|
||||
//生成任务id
|
||||
taskId := hash.JsonHashKey(renderImageData.RenderData)
|
||||
//生成任务id(需要把user_id,guest_id设为0)
|
||||
hashVal := renderImageData.RenderData
|
||||
hashVal.UserId = 0
|
||||
hashVal.GuestId = 0
|
||||
taskId := hash.JsonHashKey(hashVal)
|
||||
//查询有没有缓存的资源,有就返回######################
|
||||
resource, err := w.allModels.FsResource.FindOneById(w.ctx, taskId)
|
||||
resource, err := w.logic.svcCtx.AllModels.FsResource.FindOneById(w.logic.ctx, taskId)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
logx.Error("failed to find render resource:", err)
|
||||
@@ -101,18 +141,156 @@ func (w *wsConnectItem) renderImage(data []byte) {
|
||||
TaskId: taskId,
|
||||
RenderId: renderImageData.RenderId,
|
||||
}
|
||||
tmpData := websocket_data.AssembleRenderData{
|
||||
TaskId: taskId,
|
||||
RenderId: renderImageData.RenderId,
|
||||
RenderData: renderImageData.RenderData,
|
||||
}
|
||||
d, _ := json.Marshal(tmpData)
|
||||
//发送给对应的流水线组装数据
|
||||
if err = w.rabbitMq.SendMsg(constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, d); err != nil {
|
||||
logx.Error("发送渲染任务数据到MQ失败:", string(d), "err:", err)
|
||||
//组装数据
|
||||
if err = w.assembleRenderData(taskId, renderImageData); err != nil {
|
||||
logx.Error("组装数据失败:", err)
|
||||
return
|
||||
}
|
||||
logx.Info("发送渲染数据到rabbitmq成功:", string(d))
|
||||
}
|
||||
|
||||
// 组装数据发送给unity
|
||||
func (w *wsConnectItem) assembleRenderData(taskId string, info websocket_data.RenderImageReqMsg) error {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
logx.Error("assembleRenderData panic:", err)
|
||||
}
|
||||
}()
|
||||
//获取模板
|
||||
productTemplate, err := w.logic.svcCtx.AllModels.FsProductTemplateV2.FindOneByProductIdTagIdWithSizeTable(w.logic.ctx, info.RenderData.ProductId, info.RenderData.TemplateTag)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
logx.Error("template info is not found")
|
||||
return err
|
||||
}
|
||||
logx.Error("failed to get template info:", err)
|
||||
return err
|
||||
}
|
||||
//获取刀版图
|
||||
res, err := w.logic.svcCtx.Repositories.ImageHandle.LogoCombine(w.logic.ctx, &repositories.LogoCombineReq{
|
||||
UserId: info.RenderData.UserId,
|
||||
GuestId: info.RenderData.GuestId,
|
||||
TemplateId: productTemplate.Id,
|
||||
TemplateTag: info.RenderData.TemplateTag,
|
||||
Website: info.RenderData.Website,
|
||||
Slogan: info.RenderData.Slogan,
|
||||
Address: info.RenderData.Address,
|
||||
Phone: info.RenderData.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Error("合成刀版图失败:", err)
|
||||
return err
|
||||
}
|
||||
combineImage := "" //刀版图
|
||||
if res != nil && res.ResourceUrl != nil {
|
||||
combineImage = *res.ResourceUrl
|
||||
} else {
|
||||
logx.Error("合成刀版图失败,合成的刀版图是空指针:", err)
|
||||
return err
|
||||
}
|
||||
logx.Info("合成刀版图成功:", *res.ResourceUrl)
|
||||
//获取渲染设置信息
|
||||
element, err := w.logic.svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(w.logic.ctx, *productTemplate.ModelId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// todo 没有图就给他返回一张默认(后面要删除)
|
||||
defaultImg := w.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{
|
||||
RenderId: info.RenderId,
|
||||
Image: "https://s3.us-west-1.amazonaws.com/storage.fusenpack.com/695463af6e9b93c003db39ddf728241f9523efc55b20dc37f30fe5d96ed54fb5",
|
||||
})
|
||||
w.sendToOutChan(defaultImg)
|
||||
logx.Error("element info is not found,model_id = ", *productTemplate.ModelId)
|
||||
return err
|
||||
}
|
||||
logx.Error("failed to get element list,", err)
|
||||
return err
|
||||
}
|
||||
//组装数据
|
||||
refletion := -1
|
||||
if element.Refletion != nil && *element.Refletion != "" {
|
||||
refletion, err = strconv.Atoi(*element.Refletion)
|
||||
}
|
||||
//组装data数据
|
||||
var mode map[string]interface{}
|
||||
if element.Mode != nil && *element.Mode != "" {
|
||||
if err = json.Unmarshal([]byte(*element.Mode), &mode); err != nil {
|
||||
logx.Error("faile to parse element mode json:", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
tempData := make([]map[string]interface{}, 0, 3)
|
||||
if element.Base != nil && *element.Base != "" {
|
||||
tempData = append(tempData, map[string]interface{}{
|
||||
"name": "model",
|
||||
"data": "0," + combineImage + "," + *element.Base,
|
||||
"type": "other",
|
||||
"layer": "0",
|
||||
"is_update": 1,
|
||||
"mode": mode["model"],
|
||||
})
|
||||
}
|
||||
if element.Shadow != nil && *element.Shadow != "" {
|
||||
tempData = append(tempData, map[string]interface{}{
|
||||
"name": "shadow",
|
||||
"data": *element.Shadow,
|
||||
"type": "other",
|
||||
"layer": "0",
|
||||
"is_update": 0,
|
||||
"mode": mode["shadow"],
|
||||
})
|
||||
}
|
||||
if element.ModelP != nil && *element.ModelP != "" {
|
||||
tempData = append(tempData, map[string]interface{}{
|
||||
"name": "model_P",
|
||||
"data": "0," + *element.ModelP,
|
||||
"type": "other",
|
||||
"layer": "0",
|
||||
"is_update": 0,
|
||||
"mode": mode["model_P"],
|
||||
})
|
||||
}
|
||||
result := []interface{}{
|
||||
map[string]interface{}{
|
||||
"light": *element.Light,
|
||||
"refletion": refletion,
|
||||
"scale": *element.Scale,
|
||||
"sku_id": info.RenderData.ProductId,
|
||||
"tid": *element.Title,
|
||||
"rotation": *element.Rotation,
|
||||
"filePath": "", //todo 文件路径,针对千人千面
|
||||
"data": tempData,
|
||||
},
|
||||
}
|
||||
sendData := map[string]interface{}{
|
||||
"id": taskId,
|
||||
"order_id": 0,
|
||||
"user_id": info.RenderData.UserId,
|
||||
"guest_id": info.RenderData.GuestId,
|
||||
"sku_ids": []int64{info.RenderData.ProductId},
|
||||
"tids": []string{*element.Title},
|
||||
"data": result,
|
||||
"is_thousand_face": 0,
|
||||
"folder": "", //todo 千人千面需要使用
|
||||
}
|
||||
//请求unity接口
|
||||
url := "http://api.fusen.3718.cn:4050/api/render/queue/push"
|
||||
header := make(map[string]string)
|
||||
header["content-type"] = "application/json"
|
||||
t := time.Now().UTC()
|
||||
postData := map[string]interface{}{
|
||||
"group": "unity3d",
|
||||
"source": "home page",
|
||||
"priority": 1,
|
||||
"create_at": t,
|
||||
"render_data": sendData,
|
||||
}
|
||||
p, _ := json.Marshal(postData)
|
||||
_, err = curl.ApiCall(url, "POST", header, bytes.NewReader(p), time.Second*10)
|
||||
if err != nil {
|
||||
logx.Error("failed to send data to unity")
|
||||
return err
|
||||
}
|
||||
logx.Info("发送到unity成功################")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 操作连接中渲染任务的增加/删除
|
||||
|
||||
@@ -7,6 +7,10 @@ import (
|
||||
"fusenapi/shared"
|
||||
"net/http"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
|
||||
"fusenapi/initalize"
|
||||
"fusenapi/model/gmodel"
|
||||
|
||||
@@ -18,21 +22,29 @@ type ServiceContext struct {
|
||||
Config config.Config
|
||||
SharedState *shared.SharedState
|
||||
|
||||
MysqlConn *gorm.DB
|
||||
AllModels *gmodel.AllModelsGen
|
||||
RabbitMq *initalize.RabbitMqHandle
|
||||
MysqlConn *gorm.DB
|
||||
AllModels *gmodel.AllModelsGen
|
||||
RabbitMq *initalize.RabbitMqHandle
|
||||
AwsSession *session.Session
|
||||
Repositories *initalize.Repositories
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
conn := initalize.InitMysql(c.SourceMysql)
|
||||
// StateServer := shared.StartNode(c.ReplicaId, autoconfig.AutoGetAllServerConfig(), conn)
|
||||
|
||||
config := aws.Config{
|
||||
Credentials: credentials.NewStaticCredentials(c.AWS.S3.Credentials.AccessKeyID, c.AWS.S3.Credentials.Secret, c.AWS.S3.Credentials.Token),
|
||||
}
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
SharedState: nil,
|
||||
MysqlConn: conn,
|
||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
||||
Config: c,
|
||||
MysqlConn: conn,
|
||||
AllModels: gmodel.NewAllModels(conn),
|
||||
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
||||
AwsSession: session.Must(session.NewSession(&config)),
|
||||
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
||||
GormDB: conn,
|
||||
BLMServiceUrl: &c.BLMService.Url,
|
||||
AwsSession: session.Must(session.NewSession(&config)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,21 +5,11 @@ import (
|
||||
"fusenapi/utils/basic"
|
||||
)
|
||||
|
||||
type RequestToUnity struct {
|
||||
}
|
||||
|
||||
type RequestReadImages struct {
|
||||
}
|
||||
|
||||
type RenderNotifyReq struct {
|
||||
Sign string `json:"sign"`
|
||||
Time int64 `json:"time"`
|
||||
Info NotifyInfo `json:"info"`
|
||||
}
|
||||
|
||||
type NotifyInfo struct {
|
||||
TaskId string `json:"task_id"` //任务id
|
||||
Image string `json:"image"`
|
||||
TaskId string `json:"task_id"` //任务id
|
||||
UserId int64 `json:"user_id"`
|
||||
GuestId int64 `json:"guest_id"`
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/server/websocket/internal/logic"
|
||||
"net/http"
|
||||
|
||||
"fusenapi/utils/auth"
|
||||
@@ -30,12 +27,6 @@ func main() {
|
||||
defer server.Stop()
|
||||
|
||||
ctx := svc.NewServiceContext(c)
|
||||
//消费渲染结果队列
|
||||
ctx1 := context.Background()
|
||||
ctx2, cancel := context.WithCancel(ctx1)
|
||||
ctx2 = context.WithValue(ctx2, "allmodels", ctx.AllModels)
|
||||
defer cancel()
|
||||
go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_RENDER_RESULT_DATA, &logic.MqConsumerRenderResult{})
|
||||
handler.RegisterHandlers(server, ctx)
|
||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||
server.Start()
|
||||
|
||||
Reference in New Issue
Block a user