diff --git a/model/gmodel/fs_resource_logic.go b/model/gmodel/fs_resource_logic.go index 19db19ad..19e095db 100644 --- a/model/gmodel/fs_resource_logic.go +++ b/model/gmodel/fs_resource_logic.go @@ -52,23 +52,36 @@ func (m *FsResourceModel) RowSelectBuilder(selectData []string) *gorm.DB { // 事务 func (m *FsResourceModel) Trans(ctx context.Context, fn func(ctx context.Context, connGorm *gorm.DB) error) error { - tx := m.db.Table(m.name).WithContext(ctx).Begin() - defer func() { - if r := recover(); r != nil { - tx.Rollback() - } - }() - if err := tx.Error; err != nil { + return m.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + err := fn(ctx, tx) return err - } + }) - if err := fn(ctx, tx); err != nil { - tx.Rollback() - return err - } + // tx := m.db.Table(m.name).WithContext(ctx) + // defer func() { + // if r := recover(); r != nil { + // tx.Rollback() + // } + // }() - return tx.Commit().Error + // if err := tx.Error; err != nil { + // tx.Rollback() + // return err + // } + + // if err := fn(ctx, tx); err != nil { + // tx.Rollback() + // return err + // } + + // err := tx.Commit().Error + // if err != nil { + // tx.Rollback() + // return err + // } + + // return err } func (m *FsResourceModel) TableName() string { diff --git a/model/gmodel/fs_user_material_logic.go b/model/gmodel/fs_user_material_logic.go index 134ced4b..98c0bb08 100644 --- a/model/gmodel/fs_user_material_logic.go +++ b/model/gmodel/fs_user_material_logic.go @@ -70,3 +70,8 @@ func (m *FsUserMaterialModel) FindLatestOne(ctx context.Context, userId int64, g err = db.Take(&resp).Error return resp, err } + +func (m *FsUserMaterialModel) FindOneById(ctx context.Context, id int64) (resp *FsUserMaterial, err error) { + err = m.db.WithContext(ctx).Model(&FsUserMaterial{}).Where("id = ?", id).Take(&resp).Error + return resp, err +} diff --git a/server/home-user-auth/internal/logic/userordercancellogic.go b/server/home-user-auth/internal/logic/userordercancellogic.go index 3fad53bb..13211fcf 100644 --- a/server/home-user-auth/internal/logic/userordercancellogic.go +++ b/server/home-user-auth/internal/logic/userordercancellogic.go @@ -76,16 +76,17 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us var nowTime = time.Now().Unix() var payList []handlers.PayInfo // 事务处理 - err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { + ctx := l.ctx + err = l.svcCtx.MysqlConn.Transaction(func(tx *gorm.DB) error { // 修改订单信息 - orderModelTS := gmodel.NewFsOrderModel(connGorm) + orderModelTS := gmodel.NewFsOrderModel(tx) err = orderModelTS.Update(ctx, orderInfo) if err != nil { return err } // 新增退款记录 var isRefund int64 = 0 - refundReasonModelTS := gmodel.NewFsRefundReasonModel(connGorm) + refundReasonModelTS := gmodel.NewFsRefundReasonModel(tx) refundReasonModelTS.CreateOrUpdate(ctx, &gmodel.FsRefundReason{ IsRefund: &isRefund, RefundReasonId: &req.RefundReasonId, @@ -95,7 +96,7 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us }) // 退款申请 // 退款申请--查询支付信息 - fsPayModelTS := gmodel.NewFsPayModel(connGorm) + fsPayModelTS := gmodel.NewFsPayModel(tx) rbFsPay := fsPayModelTS.RowSelectBuilder(nil).Where("order_number = ?", orderInfo.Sn).Where("pay_status =?", constants.PAYSTATUS_SUCCESS).Where("is_refund =?", 0) payInfoList, err := fsPayModelTS.FindAll(ctx, rbFsPay, nil, "") if err != nil { diff --git a/server/pay/internal/logic/orderpaymentintentlogic.go b/server/pay/internal/logic/orderpaymentintentlogic.go index a5cb71bc..fdc608ad 100644 --- a/server/pay/internal/logic/orderpaymentintentlogic.go +++ b/server/pay/internal/logic/orderpaymentintentlogic.go @@ -107,7 +107,8 @@ func (l *OrderPaymentIntentLogic) OrderPaymentIntent(req *types.OrderPaymentInte var resData types.OrderPaymentIntentRes // 事务处理 - err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) error { + ctx := l.ctx + err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error { // 支付记录--处理 //支付记录改为一条订单多条,分首款尾款 var payStatus int64 = 0 var orderSource int64 = 1 diff --git a/server/pay/internal/logic/stripewebhooklogic.go b/server/pay/internal/logic/stripewebhooklogic.go index 038c2bce..5f327ab5 100644 --- a/server/pay/internal/logic/stripewebhooklogic.go +++ b/server/pay/internal/logic/stripewebhooklogic.go @@ -153,13 +153,13 @@ func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent) func (l *StripeWebhookLogic) HandleChargeRefunded(chargeRefunded *stripe.Charge) (err error) { // 退款成功 if chargeRefunded.Status == "succeeded" { - orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) - err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { + ctx := l.ctx + err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error { // 查询支付记录 payModelT := gmodel.NewFsPayModel(connGorm) payModelTRSB := payModelT.RowSelectBuilder(nil) payModelTRSB1 := payModelTRSB.Where("trade_no = ?", chargeRefunded.PaymentIntent.ID).Where("pay_status = ?", constants.PAYSTATUS_SUCCESS).Where("is_refund = ?", 0) - payInfo, err := payModelT.FindOneByQuery(l.ctx, payModelTRSB1, nil) + payInfo, err := payModelT.FindOneByQuery(ctx, payModelTRSB1, nil) if err != nil { return err } @@ -295,7 +295,8 @@ func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe. } } - err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { + ctx := l.ctx + err = l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error { // 更新支付信息 payModelT := gmodel.NewFsPayModel(connGorm) *payInfo.PayStatus = 1 diff --git a/server/product/internal/logic/getpricebypidlogic.go b/server/product/internal/logic/getpricebypidlogic.go index ea18202f..4848af9b 100644 --- a/server/product/internal/logic/getpricebypidlogic.go +++ b/server/product/internal/logic/getpricebypidlogic.go @@ -101,9 +101,39 @@ func (l *GetPriceByPidLogic) GetPriceByPid(req *types.GetPriceByPidReq, userinfo // 组装阶梯价格范围 func (l *GetPriceByPidLogic) dealWithStepRange(stepNumSlice, stepPriceSlice []int, priceInfo gmodel.FsProductPrice) []types.StepRange { + //要求写死不影响前端展示 + return []types.StepRange{ + { + Begin: 1000, + End: 2999, + Price: 0.23, + }, + { + Begin: 3000, + End: 4999, + Price: 0.2, + }, + { + Begin: 5000, + End: -1, + Price: 0.1, + }, + } + //下面是正常的 lenStepNum := len(stepNumSlice) lenStepPrice := len(stepPriceSlice) stepListRsp := make([]types.StepRange, 0, lenStepNum) + //只有一个阶梯价格 + if lenStepPrice == 1 { + stepListRsp = append(stepListRsp, types.StepRange{ + Begin: *priceInfo.MinBuyNum * (*priceInfo.EachBoxNum), + End: -1, + Price: float64(stepPriceSlice[0]) / 100, + }) + return stepListRsp + } + begin := int64(0) + end := int64(0) for numKey, stepNum := range stepNumSlice { //先取最后一个 tmpPrice := float64(stepPriceSlice[lenStepPrice-1]) / 100 @@ -111,23 +141,12 @@ func (l *GetPriceByPidLogic) dealWithStepRange(stepNumSlice, stepPriceSlice []in if numKey < lenStepPrice { tmpPrice = float64(stepPriceSlice[numKey]) / 100 } - num := int64(stepNum) * (*priceInfo.EachBoxNum) - begin := int64(0) - end := int64(0) - if numKey == 0 { //第一个 - begin = *priceInfo.MinBuyNum * (*priceInfo.EachBoxNum) - //只有一阶价格 - if lenStepPrice == 1 { - end = -1 - } else { - end = num - 1 - } - } else if numKey < lenStepNum-1 { //中间的 - nextNum := int64(stepNumSlice[numKey+1]) * (*priceInfo.EachBoxNum) - begin = num - end = nextNum - 1 - } else { //最后的 - begin = num + begin = int64(stepNum) * (*priceInfo.EachBoxNum) + //不是最后一个 + if numKey < lenStepNum-1 { + nextBegin := int64(stepNumSlice[numKey+1]) * (*priceInfo.EachBoxNum) + end = nextBegin - 1 + } else { end = -1 } stepListRsp = append(stepListRsp, types.StepRange{ diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go index a3fc6ef0..8fb6f82b 100644 --- a/server/render/consumer/assemble_render_data.go +++ b/server/render/consumer/assemble_render_data.go @@ -1,12 +1,14 @@ package consumer import ( + "bytes" "context" "encoding/json" "errors" "fmt" "fusenapi/constants" "fusenapi/initalize" + "fusenapi/model/gmodel" "fusenapi/server/render/internal/svc" "fusenapi/utils/curl" "fusenapi/utils/file" @@ -16,7 +18,6 @@ import ( "gorm.io/gorm" "io/ioutil" "strconv" - "strings" ) // 这里请求的py接口返回数据 @@ -47,7 +48,7 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { } rabbitmq := initalize.RabbitMqHandle{} //获取模板(产品第一个sku的模板) - templateInfo, err := svcCtx.AllModels.FsProductTemplateV2.FindOneByProductIdTagIdWithSizeTable(ctx, parseInfo.RenderData.ProductId, fmt.Sprintf("%d", parseInfo.RenderData.TemplateTagId)) + productTemplate, err := svcCtx.AllModels.FsProductTemplateV2.FindOneByProductIdTagIdWithSizeTable(ctx, parseInfo.RenderData.ProductId, fmt.Sprintf("%d", parseInfo.RenderData.TemplateTagId)) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { logx.Error("template info is not found") @@ -56,6 +57,7 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { logx.Error("failed to get template info:", err) return err } + combineImage := "" //刀版图 combineHash := hash.JsonHashKey(parseInfo) //区别于云渲染的taskid,这个用获取刀版图缓存 //获取该hash值下有没有对应的资源 resource, err := svcCtx.AllModels.FsResource.FindOneById(ctx, combineHash) @@ -63,10 +65,9 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { logx.Error("failed to get resource :", err) return err } - combineImage := "" //刀版图 //如果不存在,则请求生成刀版图 if errors.Is(err, gorm.ErrRecordNotFound) { - combineImage, err = getCombineImage(ctx, svcCtx, parseInfo, combineHash) + combineImage, err = getCombineImage(ctx, svcCtx, parseInfo, productTemplate, combineHash) if err != nil { return err } @@ -74,10 +75,10 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { combineImage = *resource.ResourceUrl } //获取渲染设置信息 - element, err := svcCtx.AllModels.FsProductTemplateElement.FindOneByModelId(ctx, *templateInfo.ModelId) + 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 = ?", *templateInfo.ModelId) + logx.Error("element info is not found,model_id = ?", *productTemplate.ModelId) return nil } logx.Error("failed to get element list,", err) @@ -132,7 +133,7 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { "light": *element.Light, "refletion": refletion, "scale": *element.Scale, - "sku_id": *templateInfo.ProductId, + "sku_id": parseInfo.RenderData.ProductId, "tid": *element.Title, "rotation": *element.Rotation, "filePath": "", //todo 文件路径,针对千人千面 @@ -160,14 +161,68 @@ func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { } // 获取刀版图 -func getCombineImage(ctx context.Context, svcCtx *svc.ServiceContext, parseInfo websocket_data.AssembleRenderData, combineHash string) (image string, err error) { - // todo 获取sku对应用来合成刀版图的json数据 - - url := "http://192.168.1.7:45678/LogoCombine" +func getCombineImage(ctx context.Context, svcCtx *svc.ServiceContext, parseInfo websocket_data.AssembleRenderData, productTemplate *gmodel.FsProductTemplateV2, combineHash string) (image string, err error) { + if productTemplate.TemplateInfo == nil || *productTemplate.TemplateInfo == "" { + logx.Error("product template info`template_info is empty") + return "", errors.New("product template info`template_info is empty") + } + //反序列化替换其中一些参数 + var combineInfo map[string]interface{} + if err = json.Unmarshal([]byte(*productTemplate.TemplateInfo), &combineInfo); err != nil { + logx.Error("failed to parse json:template_info:", err) + return "", err + } + //需要替换的参数 + replaceData := map[string]interface{}{ + "logo_url": parseInfo.RenderData.Logo, + "website": "", + "slogan": "", + "address": "", + "phone": "", + "colors": []string{}, + "template_tagid": []string{}, + "is_crop": false, + "shape": "", + "ratio": 0, + "line": "", + "other": "", + "other1": "", + } + //获取用户素材信息 + if parseInfo.RenderData.UserMaterialId > 0 { + userMaterial, err := svcCtx.AllModels.FsUserMaterial.FindOneById(ctx, parseInfo.RenderData.UserMaterialId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + logx.Error("user material not exists:", parseInfo.RenderData.UserMaterialId) + return "", errors.New("user material not exists") + } + logx.Error("err failed to get user material info") + } + if userMaterial.Metadata != nil && *userMaterial.Metadata != "" { + //解析元数据 + var materialMetaData map[string]interface{} + if err = json.Unmarshal([]byte(*userMaterial.Metadata), &materialMetaData); err != nil { + logx.Error("failed to parse user material`matadata: ", err) + return "", err + } + //赋值 + replaceData["colors"] = materialMetaData["colors"] + replaceData["logo_url"] = materialMetaData["logo_url"] + replaceData["shape"] = materialMetaData["shape"] + replaceData["is_crop"] = materialMetaData["is_crop"] + replaceData["ratio"] = materialMetaData["ratio"] + replaceData["line"] = materialMetaData["line"] + replaceData["other"] = materialMetaData["other"] + replaceData["other1"] = materialMetaData["other1"] + } + } + combineInfo["param_data"] = replaceData + postData, _ := json.Marshal(combineInfo) + //请求合成图片 + url := svcCtx.Config.PythonApi.CombineImageUrl header := make(map[string]string) header["content-type"] = "application/json" - postData := "" // todo 请求数据要查出来 - httpRsp, err := curl.ApiCall(url, "POST", header, strings.NewReader(postData), 20) + httpRsp, err := curl.ApiCall(url, "POST", header, bytes.NewReader(postData), 20) if err != nil { logx.Error("failed to combine logo:", err) return "", err diff --git a/server/render/etc/render.yaml b/server/render/etc/render.yaml index 2964916f..17ac21af 100644 --- a/server/render/etc/render.yaml +++ b/server/render/etc/render.yaml @@ -13,4 +13,6 @@ AWS: Credentials: AccessKeyID: AKIAZB2JKUXDPNRP4YT2 Secret: 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 - Token: \ No newline at end of file + Token: +PythonApi: #python接口 + CombineImageUrl: http://192.168.1.7:45678/LogoCombine #合成刀版图接口 \ No newline at end of file diff --git a/server/render/internal/config/config.go b/server/render/internal/config/config.go index 87739010..77d1be3d 100644 --- a/server/render/internal/config/config.go +++ b/server/render/internal/config/config.go @@ -21,4 +21,7 @@ type Config struct { } } } + PythonApi struct { + CombineImageUrl string //合图url + } } diff --git a/server/upload/internal/handler/uploadfilebackendhandler.go b/server/upload/internal/handler/uploadfilebackendhandler.go index a3f72895..75b0b081 100644 --- a/server/upload/internal/handler/uploadfilebackendhandler.go +++ b/server/upload/internal/handler/uploadfilebackendhandler.go @@ -1,13 +1,9 @@ package handler import ( - "errors" "net/http" + "reflect" - "github.com/zeromicro/go-zero/core/logx" - "github.com/zeromicro/go-zero/rest/httpx" - - "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/server/upload/internal/logic" @@ -18,72 +14,22 @@ import ( func UploadFileBackendHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var ( - // 定义错误变量 - err error - // 定义用户信息变量 - userinfo *auth.UserInfo - ) - // 解析JWT token,并对空用户进行判断 - claims, err := svcCtx.ParseJwtToken(r) - // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 + var req types.UploadFileBackendReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) if err != nil { - httpx.OkJsonCtx(r.Context(), w, &basic.Response{ - Code: 401, // 返回401状态码,表示未授权 - Message: "unauthorized", // 返回未授权信息 - }) - logx.Info("unauthorized:", err.Error()) // 记录错误日志 - return - } - - if claims != nil { - // 从token中获取对应的用户信息 - userinfo, err = auth.GetUserInfoFormMapClaims(claims) - // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 - if err != nil { - httpx.OkJsonCtx(r.Context(), w, &basic.Response{ - Code: 401, - Message: "unauthorized", - }) - logx.Info("unauthorized:", err.Error()) - return - } - } else { - // 如果claims为nil,则认为用户身份为白板用户 - userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} - } - - var req types.RequestUploadFileBackend - // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 - if err := httpx.Parse(r, &req); err != nil { - httpx.OkJsonCtx(r.Context(), w, &basic.Response{ - Code: 510, - Message: "parameter error", - }) - logx.Info(err) - return - } - - // 解析upload文件类型 - err = basic.RequestFileParse(r, &req) - if err != nil { - httpx.OkJsonCtx(r.Context(), w, &basic.Response{ - Code: 510, - Message: err.Error(), - }) return } // 创建一个业务逻辑层实例 - l := logic.NewUploadFileBackendLogic(r.Context(), svcCtx) + l := logic.NewUploadFileBackendLogic(r, svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + resp := l.UploadFileBackend(&req, userinfo) - // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; - if resp != nil { - httpx.OkJsonCtx(r.Context(), w, resp) - } else { - err := errors.New("server logic is error, resp must not be nil") - httpx.ErrorCtx(r.Context(), w, err) - logx.Error(err) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) } } } diff --git a/server/upload/internal/logic/uploadcallbacklogic.go b/server/upload/internal/logic/uploadcallbacklogic.go index a8b93eaf..4c67de50 100644 --- a/server/upload/internal/logic/uploadcallbacklogic.go +++ b/server/upload/internal/logic/uploadcallbacklogic.go @@ -64,8 +64,8 @@ func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, useri bucketName = basic.StorageBucketName } - resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) - err := resourceModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { + ctx := l.ctx + err := l.svcCtx.MysqlConn.Transaction(func(connGorm *gorm.DB) error { resourceModelTS := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) resourceInfo, err := resourceModelTS.FindOneById(ctx, req.ResourceId) if err != nil { diff --git a/server/upload/internal/logic/uploadfilebackendlogic.go b/server/upload/internal/logic/uploadfilebackendlogic.go index 77de1f5f..32a577c8 100644 --- a/server/upload/internal/logic/uploadfilebackendlogic.go +++ b/server/upload/internal/logic/uploadfilebackendlogic.go @@ -3,18 +3,16 @@ package logic import ( "fusenapi/utils/auth" "fusenapi/utils/basic" - "fusenapi/utils/check" - "fusenapi/utils/format" - "time" + "fusenapi/utils/file" + "fusenapi/utils/hash" + "io" + "net/http" "context" "fusenapi/server/upload/internal/svc" "fusenapi/server/upload/internal/types" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/s3" "github.com/zeromicro/go-zero/core/logx" ) @@ -22,109 +20,91 @@ type UploadFileBackendLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext + r *http.Request } -func NewUploadFileBackendLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadFileBackendLogic { +func NewUploadFileBackendLogic(r *http.Request, svcCtx *svc.ServiceContext) *UploadFileBackendLogic { return &UploadFileBackendLogic{ - Logger: logx.WithContext(ctx), - ctx: ctx, + Logger: logx.WithContext(r.Context()), + ctx: r.Context(), svcCtx: svcCtx, + r: r, } } -// UploadFileBackend 这个函数接收一个文件上传请求和用户信息,处理文件上传,并返回响应 -func (l *UploadFileBackendLogic) UploadFileBackend(req *types.RequestUploadFileBackend, userinfo *auth.UserInfo) (resp *basic.Response) { +// 处理进入前逻辑w,r +// func (l *UploadFileBackendLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UploadFileBackendLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UploadFileBackendLogic) UploadFileBackend(req *types.UploadFileBackendReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null - - // 检查用户是否是旁观者,旁观者没有文件上传权限 if userinfo.IsOnlooker() { // 如果是,返回未授权的错误码 return resp.SetStatus(basic.CodeUnAuth) } // 定义用户ID和S3键名格式 - var uid int64 - var keytype format.TypeFormatS3KeyName + var userId int64 + var guestId int64 // 检查用户是否是游客 if userinfo.IsGuest() { // 如果是,使用游客ID和游客键名格式 - uid = userinfo.GuestId - keytype = format.TypeS3KeyGuest + guestId = userinfo.GuestId } else { // 否则,使用用户ID和用户键名格式 - uid = userinfo.UserId - keytype = format.TypeS3KeyUser + userId = userinfo.UserId } - // 设置AWS会话的区域 - l.svcCtx.AwsSession.Config.Region = aws.String("us-west-1") + //设置内存大小 + l.r.ParseMultipartForm(32 << 20) - // 创建新的S3服务实例 - svc := s3.New(l.svcCtx.AwsSession) - - // 检查类别是否合法 - if !check.CheckCategory(req.Category) { - // 如果不合法,返回类别错误的错误码 - return resp.SetStatus(basic.CodeS3CategoryErr) - } - - // 定义S3请求和当前时间 - var s3req *request.Request - now := time.Now() - - // 格式化类别 - category := format.TypeCategory(req.Category) - - // 格式化S3对象键名 - ObjectKey := aws.String(format.FormatS3KeyName( - keytype, - uid, - now, - l.svcCtx.Config.Env, - category, - req.File.Filename, - )) - - // 定义存储桶名称 - var bucketName *string - - // 根据类别选择存储桶 - switch category { - case format.TCategoryRenderMegre: - bucketName = basic.TempfileBucketName - default: - bucketName = basic.StorageBucketName - } - - // 创建S3对象存储请求 - s3req, _ = svc.PutObjectRequest( - &s3.PutObjectInput{ - Bucket: bucketName, - Key: ObjectKey, - }, - ) - - // 设置请求体为文件数据 - s3req.SetBufferBody(req.File.Data) - - // 发送请求 - err := s3req.Send() - - // 检查是否有错误 + fileObject, _, err := l.r.FormFile("file") if err != nil { - // 如果有,打印错误并返回错误码 logx.Error(err) - return resp.SetStatus(basic.CodeS3PutObjectRequestErr) + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,no files") } - // 打印请求URL - logx.Info(s3req.HTTPRequest.URL.String()) + // 读取数据流 + ioData, err := io.ReadAll(fileObject) + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,no files") + } + + // 上传文件 + var upload = file.Upload{ + Ctx: l.ctx, + MysqlConn: l.svcCtx.MysqlConn, + AwsSession: l.svcCtx.AwsSession, + } + var resourceId string = hash.JsonHashKey(req.FileKey) + uploadRes, err := upload.UploadFileByByte(&file.UploadBaseReq{ + FileHash: resourceId, + FileByte: ioData, + UploadBucket: req.UploadBucket, + ApiType: req.ApiType, + UserId: userId, + GuestId: guestId, + }) + + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadErr, "upload file failed") + } // 返回成功的响应和上传URL return resp.SetStatus(basic.CodeOK, map[string]interface{}{ - "upload_url": s3req.HTTPRequest.URL.String(), + "upload_data": UploadUrl{ + Status: 1, + ResourceId: uploadRes.ResourceId, + ResourceUrl: uploadRes.ResourceUrl, + }, }) } diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index 24a5aeaa..6995b0c7 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -145,7 +145,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, FileHash: resourceId, FileByte: uploadDataInfo.FileData, UploadBucket: 1, - ApiType: 2, + ApiType: req.ApiType, UserId: userId, GuestId: guestId, }) diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go index 579ef53c..7bbc20e2 100644 --- a/server/upload/internal/logic/uploadlogologic.go +++ b/server/upload/internal/logic/uploadlogologic.go @@ -5,8 +5,8 @@ import ( "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/curl" "io" - "net/http" "strings" "time" @@ -83,11 +83,17 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us } var resultStr string var err error + var postMap = make(map[string]interface{}, 1) postMap["logo_url"] = req.ResourceUrl postMapB, _ := json.Marshal(postMap) - result, err := http.Post(l.svcCtx.Config.BLMService.ImageProcess.Url, "application/json", strings.NewReader(string(postMapB))) + //result, err := http.Post(l.svcCtx.Config.BLMService.ImageProcess.Url, "application/json", strings.NewReader(string(postMapB))) + + var headerData = make(map[string]string, 1) + headerData["Content-Type"] = "application/json" + result, err := curl.ApiCall(l.svcCtx.Config.BLMService.ImageProcess.Url, "POST", headerData, strings.NewReader(string(postMapB)), 20) + if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeFileUploadLogoErr, "service fail") diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index bb635925..b6363f9f 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -23,10 +23,12 @@ type UploadLogoReq struct { SkuId int64 `form:"sku_id,default=0"` // 模板ID } -type UploadInfo struct { - FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 - FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 - Metadata string `form:"meta_data,optional"` // 上传文件额外信息 +type UploadFileBackendReq 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=持久 + FileKey string `form:"file_key"` // 上传唯一标识信息 + FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 + Metadata string `form:"meta_data,optional"` // 上传文件额外信息 } type UploadFilesReq struct { diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index 4348f54a..a4057793 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -89,14 +89,14 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp return } defer conn.Close() - //鉴权不成功10秒后断开 + //鉴权不成功后断开 /*var ( userInfo *auth.UserInfo isAuth bool ) isAuth, userInfo = l.checkAuth(svcCtx, r) if !isAuth { - time.Sleep(time.Second) //兼容下火狐 + time.Sleep(time.Second * 4) //兼容下火狐 rsp := websocket_data.DataTransferData{ T: constants.WEBSOCKET_UNAUTH, D: nil, @@ -132,10 +132,12 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp //保存连接 mapConnPool.Store(uniqueId, ws) defer ws.close() - //把连接成功消息发回去 - time.Sleep(time.Second) //兼容下火狐 - b := ws.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, uniqueId) - _ = conn.WriteMessage(websocket.TextMessage, b) + go func() { + //把连接成功消息发回去 + time.Sleep(time.Second * 4) //兼容下火狐 + b := ws.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, uniqueId) + _ = conn.WriteMessage(websocket.TextMessage, b) + }() //循环读客户端信息 go ws.readLoop() //循环把数据发送给客户端 diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index efdfbc55..d7d5bb6c 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -60,6 +60,7 @@ func (w *wsConnectItem) renderImage(data []byte) { renderImageData.RenderData.Logo = "https://s3.us-west-1.amazonaws.com/storage.fusenpack.com/f5ccd11365099fa47a6316b1cd639f6dd6064dcd2d37c8d2fcd0a322160b33cc" } else { renderImageData.RenderData.Logo = *userMaterial.ResourceUrl + renderImageData.RenderData.UserMaterialId = userMaterial.Id } //用户id赋值 renderImageData.RenderData.UserId = w.userId diff --git a/server_api/upload.api b/server_api/upload.api index d8479feb..a9581adf 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -17,7 +17,7 @@ service upload { post /api/upload/upload-file-frontend(RequestUploadFileFrontend) returns (response); @handler UploadFileBackendHandler - post /api/upload/upload-file-backend(RequestUploadFileBackend) returns (response); + post /api/upload/upload-file-backend(UploadFileBackendReq) returns (response); //生成二维码 @handler UploadQrcodeHandler post /api/upload/qrcode(UploadQrcodeReq) returns (response); @@ -67,10 +67,12 @@ type ( ) type ( - UploadInfo { - FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 - FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 - Metadata string `form:"meta_data,optional"` // 上传文件额外信息 + UploadFileBackendReq { + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 + UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 + FileKey string `form:"file_key"` // 上传唯一标识信息 + FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 + Metadata string `form:"meta_data,optional"` // 上传文件额外信息 } UploadFilesReq { diff --git a/utils/file/upload.go b/utils/file/upload.go index 0038ed1c..d19752e7 100644 --- a/utils/file/upload.go +++ b/utils/file/upload.go @@ -66,10 +66,9 @@ func (upload *Upload) UploadFileByBase64(req *UploadBaseReq) (*UploadBaseRes, er var resourceId string = req.FileHash var uploadBaseRes = UploadBaseRes{} - resourceModel := gmodel.NewFsResourceModel(upload.MysqlConn) - err := resourceModel.Trans(upload.Ctx, func(ctx context.Context, connGorm *gorm.DB) error { - resourceModelTS := gmodel.NewFsResourceModel(connGorm) - resourceInfo, err := resourceModelTS.FindOneById(ctx, resourceId) + err := upload.MysqlConn.Transaction(func(tx *gorm.DB) error { + var resourceInfo *gmodel.FsResource + err := tx.Where("resource_id =?", resourceId).Take(&resourceInfo).Error if err == nil && resourceInfo.ResourceId != "" { uploadBaseRes.Status = 1 uploadBaseRes.ResourceId = resourceId @@ -109,7 +108,7 @@ func (upload *Upload) UploadFileByBase64(req *UploadBaseReq) (*UploadBaseRes, er uploadBaseRes.ResourceUrl = url var version string = "0.0.1" var nowTime = time.Now() - _, err = resourceModelTS.Create(upload.Ctx, &gmodel.FsResource{ + err = tx.Create(&gmodel.FsResource{ ResourceId: resourceId, UserId: &req.UserId, GuestId: &req.GuestId, @@ -120,15 +119,18 @@ func (upload *Upload) UploadFileByBase64(req *UploadBaseReq) (*UploadBaseRes, er Metadata: &req.Metadata, ApiType: &apiType, BucketName: bucketName, - }) + }).Error if err != nil { logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.resourceInfoAdd.mysql") return err } } } + + // 返回 nil 提交事务 return nil }) + if err != nil { return nil, err } @@ -161,10 +163,11 @@ func (upload *Upload) UploadFileByByte(req *UploadBaseReq) (*UploadBaseRes, erro var resourceId string = req.FileHash var uploadBaseRes = UploadBaseRes{} - resourceModel := gmodel.NewFsResourceModel(upload.MysqlConn) - err := resourceModel.Trans(upload.Ctx, func(ctx context.Context, connGorm *gorm.DB) error { - resourceModelTS := gmodel.NewFsResourceModel(connGorm) - resourceInfo, err := resourceModelTS.FindOneById(ctx, resourceId) + + err := upload.MysqlConn.Transaction(func(tx *gorm.DB) error { + var resourceInfo *gmodel.FsResource + err := tx.Where("resource_id =?", resourceId).Take(&resourceInfo).Error + // resourceInfo, err := resourceModelTS.FindOneById(ctx, resourceId) if err == nil && resourceInfo.ResourceId != "" { uploadBaseRes.Status = 1 uploadBaseRes.ResourceId = resourceId @@ -198,7 +201,7 @@ func (upload *Upload) UploadFileByByte(req *UploadBaseReq) (*UploadBaseRes, erro uploadBaseRes.ResourceUrl = url var version string = "0.0.1" var nowTime = time.Now() - _, err = resourceModelTS.Create(upload.Ctx, &gmodel.FsResource{ + err = tx.Create(&gmodel.FsResource{ ResourceId: resourceId, UserId: &req.UserId, GuestId: &req.GuestId, @@ -209,7 +212,7 @@ func (upload *Upload) UploadFileByByte(req *UploadBaseReq) (*UploadBaseRes, erro Metadata: &req.Metadata, ApiType: &apiType, BucketName: bucketName, - }) + }).Error if err != nil { logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.resourceInfoAdd.mysql") return err diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go index 928d1005..8bde5dbe 100644 --- a/utils/websocket_data/render_data.go +++ b/utils/websocket_data/render_data.go @@ -12,11 +12,12 @@ type RenderImageReqMsg struct { RenderData RenderData `json:"render_data"` } type RenderData struct { - TemplateTagId int64 `json:"template_tag_id"` //模板标签id - ProductId int64 `json:"product_id"` //产品id - Logo string `json:"logo"` //log资源地址(websocket连接建立再赋值) - UserId int64 `json:"user_id"` //用户id(websocket连接建立再赋值) - GuestId int64 `json:"guest_id"` //游客id(websocket连接建立再赋值) + TemplateTagId int64 `json:"template_tag_id"` //模板标签id + ProductId int64 `json:"product_id"` //产品id + UserMaterialId int64 `json:"user_material_id"` //用户素材id + Logo string `json:"logo"` //log资源地址(websocket连接建立再赋值) + UserId int64 `json:"user_id"` //用户id(websocket连接建立再赋值) + GuestId int64 `json:"guest_id"` //游客id(websocket连接建立再赋值) } // websocket发送渲染完的数据