Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop

This commit is contained in:
momo
2023-08-31 11:56:18 +08:00
25 changed files with 279 additions and 103 deletions

View File

@@ -2,6 +2,7 @@ package logic
import (
"bytes"
"fusenapi/utils/check"
"log"
"net/smtp"
"sync"
@@ -9,8 +10,35 @@ import (
"time"
)
var TimeLimit *check.TimeLimit[string]
var EmailManager *EmailSender
func init() {
TimeLimit = check.NewTimelimit[string](time.Second * 25)
// Initialize the email manager
EmailManager = &EmailSender{
EmailTasks: make(chan *EmailFormat, 10),
Auth: smtp.PlainAuth(
"",
"support@fusenpack.com",
"wfbjpdgvaozjvwah",
"smtp.gmail.com",
),
FromEmail: "support@fusenpack.com",
emailSending: make(map[string]*EmailTask, 10),
ResendTimeLimit: time.Minute * 1,
semaphore: make(chan struct{}, 10), // Initialize semaphore with a capacity of 10
}
// Start processing email tasks
go EmailManager.ProcessEmailTasks()
// Start clearing expired tasks
go EmailManager.ClearExpiredTasks()
}
type EmailFormat struct {
TargetEmail string // 发送的目标email
CompanyName string // fs公司名
@@ -110,30 +138,6 @@ func (m *EmailSender) ClearExpiredTasks() {
}
}
func init() {
// Initialize the email manager
EmailManager = &EmailSender{
EmailTasks: make(chan *EmailFormat, 10),
Auth: smtp.PlainAuth(
"",
"support@fusenpack.com",
"wfbjpdgvaozjvwah",
"smtp.gmail.com",
),
FromEmail: "support@fusenpack.com",
emailSending: make(map[string]*EmailTask, 10),
ResendTimeLimit: time.Minute * 1,
semaphore: make(chan struct{}, 10), // Initialize semaphore with a capacity of 10
}
// Start processing email tasks
go EmailManager.ProcessEmailTasks()
// Start clearing expired tasks
go EmailManager.ClearExpiredTasks()
}
const emailTemplate = `Subject: Your {{.CompanyName}} Account Confirmation
Dear

View File

@@ -47,6 +47,10 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
return resp.SetStatus(basic.CodeOAuthEmailErr)
}
if !TimeLimit.Is(req.Email) {
return resp.SetStatus(basic.CodeEmailTimeShortErr)
}
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.RegisterToken)
if err != nil {
logx.Error(err)

View File

@@ -46,6 +46,10 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf
return resp.SetStatus(basic.CodeEmailExistsErr)
}
if !TimeLimit.Is(req.Email) {
return resp.SetStatus(basic.CodeEmailTimeShortErr)
}
token := &auth.RegisterToken{
OperateType: auth.OpTypeRegister,
GuestId: userinfo.GuestId,

View File

@@ -53,12 +53,12 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get ai recommend product template tag list")
}
// 返回固定模板标签列表
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, "`id` DESC")
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, 0, 1, "`id` DESC")
} else {
//元数据是空的
if userMaterial.Metadata == nil || *userMaterial.Metadata == "" {
// 返回固定模板标签列表
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, "`id` DESC")
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetList(l.ctx, 1, req.Limit, 0, 1, "`id` DESC")
} else {
//解析元数据
var metaData map[string]interface{}
@@ -72,7 +72,7 @@ func (l *GetProductTemplateTagsLogic) GetProductTemplateTags(req *types.GetProdu
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeJsonErr, "invalid format of metadata`s template_tagid")
}
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetListByTagNames(l.ctx, templateTagNameList, req.Limit, "id DESC")
productTemplateTags, err = l.svcCtx.AllModels.FsProductTemplateTags.GetListByTagNames(l.ctx, templateTagNameList, req.Limit, 0, 1, "id DESC")
}
}
if err != nil {

View File

@@ -92,7 +92,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
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.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get user logo", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取用户上传logo素材失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
logx.Error("failed to get user logo")
return
}
@@ -100,10 +100,10 @@ func (w *wsConnectItem) renderImage(data []byte) {
userMaterialDefault, err := w.logic.svcCtx.AllModels.FsUserMaterial.FindOneById(w.logic.ctx, 0)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "default logo is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "默认logo不存在", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
return
}
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get default logo", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取默认logo失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, 0, 0)
logx.Error("default logo is not exists")
return
}
@@ -123,11 +123,11 @@ func (w *wsConnectItem) renderImage(data []byte) {
}
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "product first size is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "找不到产品的第一个尺寸", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0)
logx.Error("product size is not found")
return
}
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get product first size", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取产品的第一个尺寸失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, renderImageData.RenderData.ProductSizeId, 0)
logx.Error("failed to get product size:", err)
return
}
@@ -135,11 +135,11 @@ func (w *wsConnectItem) renderImage(data []byte) {
model3dInfo, err := w.logic.svcCtx.AllModels.FsProductModel3d.GetOneBySizeIdTag(w.logic.ctx, productSize.Id, constants.TAG_MODEL, "id")
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "product model is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "产品第一个尺寸对应的模型不存在", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0)
logx.Error("product model is not found")
return
}
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get product model", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取产品第一个尺寸对应的模型失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, 0, productSize.Id, 0)
logx.Error("failed to get product model:", err)
return
}
@@ -147,23 +147,28 @@ func (w *wsConnectItem) renderImage(data []byte) {
productTemplate, err := w.logic.svcCtx.AllModels.FsProductTemplateV2.FindFirstOneCloudRenderByProductIdModelIdTemplateTag(w.logic.ctx, renderImageData.RenderData.ProductId, model3dInfo.Id, renderImageData.RenderData.TemplateTag)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "product template is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "找不到对应模板", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0)
logx.Error("template info is not found")
return
}
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get product template", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取对应模板失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, 0, model3dInfo.Id, productSize.Id, 0)
logx.Error("failed to get template info:", err)
return
}
//如果未开启云渲染
if *productTemplate.ElementModelId <= 0 {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "模板未开启云渲染", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
return
}
//获取渲染设置信息
element, err := w.logic.svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(w.logic.ctx, *productTemplate.ElementModelId)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "render element is not exists", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "云渲染设置不存在", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("element info is not found,element_model_id = ", 0)
return
}
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to get render element", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "获取云渲染设置失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("failed to get element ,", err)
return
}
@@ -182,7 +187,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
}
res, err := w.logic.svcCtx.Repositories.ImageHandle.LogoCombine(w.logic.ctx, &combineReq)
if err != nil {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "failed to combine image:"+err.Error(), renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "合成刀版图失败:"+err.Error(), renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("合成刀版图失败,合成请求数据:", combineReq, "错误信息:", err)
return
}
@@ -190,19 +195,12 @@ func (w *wsConnectItem) renderImage(data []byte) {
if res != nil && res.ResourceUrl != nil {
combineImage = *res.ResourceUrl
} else {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "combine image is empty", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, "", "合成的刀版图是空的地址", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("合成刀版图失败,合成的刀版图是空指针:", err)
return
}
//发送合图结果消息
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_COMBINE_IMAGE, websocket_data.CombineImageRspMsg{
RenderId: renderImageData.RenderId,
CombineImage: combineImage,
CombineProcessTime: websocket_data.CombineProcessTime{
CombineTakesTime: fmt.Sprintf("%dms", res.DiffTimeLogoCombine),
UploadCombineImageTakesTime: fmt.Sprintf("%dms", res.DiffTimeUploadFile),
},
}))
//发送合图完毕阶段消息
w.sendCombineImageStepResponseMessage(renderImageData.RenderId, combineImage, res.DiffTimeLogoCombine, res.DiffTimeUploadFile)
//如果指定指定只返回刀版图
if renderImageData.OnlyReturnCombineImage {
logx.Info("云渲染传入size id则不走unity云渲染,只返回刀版图render_id:", renderImageData.RenderId)
@@ -214,7 +212,7 @@ func (w *wsConnectItem) renderImage(data []byte) {
resource, err := w.logic.svcCtx.AllModels.FsResource.FindOneById(w.logic.ctx, taskId)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, taskId, "failed to get render cache", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(renderImageData.RenderId, renderImageData.RenderData.TemplateTag, taskId, "获取unity云渲染缓存失败", renderImageData.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("failed to find render resource:", err)
return
}
@@ -265,7 +263,7 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
refletion, err = strconv.Atoi(*element.Refletion)
if err != nil {
logx.Error("err refletion:set default -1")
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "parse element.Refletion from string to number err", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "解析云渲染设置把Refletion字段值从字符串转数字失败", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
return err
}
}
@@ -274,7 +272,7 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
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)
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "parse element.Mode err", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "解析云渲染设置字段 mode 为map对象失败", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
return err
}
}
@@ -321,6 +319,8 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
"data": tempData,
},
}
//发送运行阶段消息(组装数据)
w.sendAssembleRenderDataStepResponseMessage(info.RenderId)
sendData := map[string]interface{}{
"id": taskId,
"order_id": 0,
@@ -347,7 +347,7 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
unityRenderBeginTime := time.Now().UTC().UnixMilli()
_, err = curl.ApiCall(url, "POST", header, bytes.NewReader(postDataBytes), time.Second*10)
if err != nil {
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "request unity api err", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
w.renderErrResponse(info.RenderId, info.RenderData.TemplateTag, taskId, "请求unity接口失败", info.RenderData.ProductId, w.userId, w.guestId, productTemplate.Id, model3dInfo.Id, productSize.Id, *productTemplate.ElementModelId)
logx.Error("failed to send data to unity")
return err
}
@@ -359,12 +359,34 @@ func (w *wsConnectItem) assembleRenderDataToUnity(taskId string, combineImage st
unityRenderBeginTime: unityRenderBeginTime,
},
})
//发送send 到unity 运行阶段
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_SEND_DATA_TO_UNITY, websocket_data.ToUnityRspMsg{RenderId: info.RenderId}))
//发送运行阶段
w.sendRenderDataToUnityStepResponseMessage(info.RenderId)
logx.Info("发送到unity成功,刀版图:", combineImage /*, " 请求unity的数据:", string(postDataBytes)*/)
return nil
}
// 发送合图完毕阶段通知消息
func (w *wsConnectItem) sendCombineImageStepResponseMessage(renderId, combineImage string, combineMsTime, uploadMsTime int64) {
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_COMBINE_IMAGE, websocket_data.CombineImageRspMsg{
RenderId: renderId,
CombineImage: combineImage,
CombineProcessTime: websocket_data.CombineProcessTime{
CombineTakesTime: fmt.Sprintf("%dms", combineMsTime),
UploadCombineImageTakesTime: fmt.Sprintf("%dms", uploadMsTime),
},
}))
}
// 发送组装unity渲染数据完毕阶段通知消息
func (w *wsConnectItem) sendAssembleRenderDataStepResponseMessage(renderId string) {
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_ASSEMBLE_RENDER_DATA, websocket_data.ToUnityRspMsg{RenderId: renderId}))
}
// 发送组装unity渲染数据完毕阶段通知消息
func (w *wsConnectItem) sendRenderDataToUnityStepResponseMessage(renderId string) {
w.sendToOutChan(w.respondDataFormat(constants.WEBSOCKET_SEND_DATA_TO_UNITY, websocket_data.AssembleRenderDataRspMsg{RenderId: renderId}))
}
// 增加渲染任务
func (w *wsConnectItem) createRenderTask(data renderImageControlChanItem) {
if data.taskId == "" {