From 1225a4efdc7209f659f735b25a19d3ea3e6e5774 Mon Sep 17 00:00:00 2001 From: Hiven Date: Fri, 28 Jul 2023 19:03:36 +0800 Subject: [PATCH 01/60] =?UTF-8?q?=E9=80=80=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- constants/order.go | 3 +- model/gmodel/fs_cart_logic.go | 2 +- model/gmodel/fs_pay_event_gen.go | 25 +++++++ model/gmodel/fs_pay_event_logic.go | 15 ++++ model/gmodel/fs_pay_gen.go | 1 - model/gmodel/fs_pay_logic.go | 26 +++++++ model/gmodel/fs_refund_reason_logic.go | 14 ++++ model/gmodel/var_gen.go | 2 + server/home-user-auth/etc/home-user-auth.yaml | 7 ++ .../home-user-auth/internal/config/config.go | 9 +++ .../internal/logic/userordercancellogic.go | 73 ++++++++++++++++++- server/pay/etc/pay.yaml | 1 - .../internal/handler/orderrefundhandler.go | 35 +++++++++ server/pay/internal/handler/routes.go | 5 ++ .../internal/handler/stripewebhookhandler.go | 9 +++ server/pay/internal/logic/orderrefundlogic.go | 43 +++++++++++ .../pay/internal/logic/stripewebhooklogic.go | 36 +++++++-- server/pay/internal/types/types.go | 7 ++ server_api/pay.api | 11 +++ utils/basic/basic.go | 8 +- utils/handler/payHandler.go | 64 ++++++++++++++++ utils/pay/pay.go | 12 +++ utils/pay/stripe.go | 13 ++++ 23 files changed, 403 insertions(+), 18 deletions(-) create mode 100644 model/gmodel/fs_pay_event_gen.go create mode 100644 model/gmodel/fs_pay_event_logic.go create mode 100644 server/pay/internal/handler/orderrefundhandler.go create mode 100644 server/pay/internal/logic/orderrefundlogic.go create mode 100644 utils/handler/payHandler.go diff --git a/constants/order.go b/constants/order.go index 79fa6497..a22fa9f3 100644 --- a/constants/order.go +++ b/constants/order.go @@ -126,7 +126,8 @@ type Day int64 // 订单取消时间 const ( - CANCLE_ORDER_EXPIRE Day = 48 * 3600 + CANCLE_ORDER_EXPIRE Day = 48 * 3600 + CANCLE_ORDER_EXPIRE_DAY Day = 2 // 2天 ) // 订单时间配置 diff --git a/model/gmodel/fs_cart_logic.go b/model/gmodel/fs_cart_logic.go index b18f7672..d86b18be 100755 --- a/model/gmodel/fs_cart_logic.go +++ b/model/gmodel/fs_cart_logic.go @@ -92,5 +92,5 @@ func (c *FsCartModel) DeleteCartsByIds(ctx context.Context, ids []int64) ( err e if len(ids) == 0 { return } - return c.db.WithContext(ctx).Model(&FsCart{}).Where("`id` in (?)", ids).Delete(&FsCart{}).Error + return c.db.Table(c.name).WithContext(ctx).Model(&FsCart{}).Where("`id` in (?)", ids).Update("status", 0).Error } diff --git a/model/gmodel/fs_pay_event_gen.go b/model/gmodel/fs_pay_event_gen.go new file mode 100644 index 00000000..38d6c56e --- /dev/null +++ b/model/gmodel/fs_pay_event_gen.go @@ -0,0 +1,25 @@ +package gmodel + +import ( + "gorm.io/gorm" +) + +// fs_pay_event 支付回调事件日志 +type FsPayEvent struct { + Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // + PayMethod *int64 `gorm:"default:0;" json:"pay_method"` // 支付方式 1 stripe 2 paypal + EventId *string `gorm:"default:'';" json:"event_id"` // 事件ID + EventType *string `gorm:"default:'';" json:"event_type"` // 事件类型 + EventData *string `gorm:"default:'';" json:"event_data"` // 事件数据 + EventCreated *int64 `gorm:"default:0;" json:"event_created"` // 事件时间 + Ip *string `gorm:"default:'';" json:"ip"` // 请求IP + CreatedAt *int64 `gorm:"default:0;" json:"created_at"` // 创建时间 +} +type FsPayEventModel struct { + db *gorm.DB + name string +} + +func NewFsPayEventModel(db *gorm.DB) *FsPayEventModel { + return &FsPayEventModel{db: db, name: "fs_pay_event"} +} diff --git a/model/gmodel/fs_pay_event_logic.go b/model/gmodel/fs_pay_event_logic.go new file mode 100644 index 00000000..8af36582 --- /dev/null +++ b/model/gmodel/fs_pay_event_logic.go @@ -0,0 +1,15 @@ +package gmodel + +import "context" + +// TODO: 使用model的属性做你想做的 + +func (p *FsPayEventModel) CreateOrUpdate(ctx context.Context, req *FsPayEvent) (resp *FsPayEvent, err error) { + rowBuilder := p.db.Table(p.name).WithContext(ctx) + if req.Id > 0 { + err = rowBuilder.Save(req).Error + } else { + err = rowBuilder.Create(req).Error + } + return req, err +} diff --git a/model/gmodel/fs_pay_gen.go b/model/gmodel/fs_pay_gen.go index e30685b6..0ee65802 100644 --- a/model/gmodel/fs_pay_gen.go +++ b/model/gmodel/fs_pay_gen.go @@ -7,7 +7,6 @@ import ( // fs_pay 支付记录 type FsPay struct { Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // - PayNo *string `gorm:"default:'';" json:"pay_no"` // 支付编号 UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户id OrderNumber *string `gorm:"default:'';" json:"order_number"` // 订单编号 TradeNo *string `gorm:"index;default:'';" json:"trade_no"` // 第三方支付编号 diff --git a/model/gmodel/fs_pay_logic.go b/model/gmodel/fs_pay_logic.go index d470f2e9..fa4a6093 100644 --- a/model/gmodel/fs_pay_logic.go +++ b/model/gmodel/fs_pay_logic.go @@ -3,6 +3,7 @@ package gmodel import ( "context" "fusenapi/utils/handler" + "reflect" "gorm.io/gorm" ) @@ -80,6 +81,31 @@ func (m *FsPayModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, fi } } +func (m *FsPayModel) FindAll(ctx context.Context, rowBuilder *gorm.DB, filterMap map[string]string, orderBy string) ([]*FsPay, error) { + var resp []*FsPay + // 过滤 + if filterMap != nil { + rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + } + + // 排序 + if orderBy != "" { + var fieldsMap = make(map[string]struct{}) + s := reflect.TypeOf(&FsOrder{}).Elem() //通过反射获取type定义 + for i := 0; i < s.NumField(); i++ { + fieldsMap[s.Field(i).Tag.Get("json")] = struct{}{} + } + rowBuilder = rowBuilder.Scopes(handler.OrderCheck(orderBy, fieldsMap)) + } + + result := rowBuilder.WithContext(ctx).Find(&resp) + if result.Error != nil { + return nil, result.Error + } else { + return resp, nil + } +} + // 事务 func (m *FsPayModel) Trans(ctx context.Context, fn func(ctx context.Context, connGorm *gorm.DB) error) error { tx := m.db.Table(m.name).WithContext(ctx).Begin() diff --git a/model/gmodel/fs_refund_reason_logic.go b/model/gmodel/fs_refund_reason_logic.go index 88644fc4..76d6810b 100644 --- a/model/gmodel/fs_refund_reason_logic.go +++ b/model/gmodel/fs_refund_reason_logic.go @@ -24,3 +24,17 @@ func (m *FsRefundReasonModel) Update(ctx context.Context, obj *FsRefundReason) e func (m *FsRefundReasonModel) UpdateByRefundReasonId(ctx context.Context, obj *FsRefundReason) error { return m.db.WithContext(ctx).Model(obj).Where("`refund_reason_id` = ?", obj.RefundReasonId).Updates(obj).Error } + +func (m *FsRefundReasonModel) CreateOrUpdate(ctx context.Context, req *FsRefundReason) (resp *FsRefundReason, err error) { + rowBuilder := m.db.Table(m.name).WithContext(ctx) + if req.Id > 0 { + err = rowBuilder.Save(req).Error + } else { + err = rowBuilder.Create(req).Error + } + return req, err +} + +func (m *FsRefundReasonModel) TableName() string { + return m.name +} diff --git a/model/gmodel/var_gen.go b/model/gmodel/var_gen.go index 191a9898..a90a6f7c 100644 --- a/model/gmodel/var_gen.go +++ b/model/gmodel/var_gen.go @@ -52,6 +52,7 @@ type AllModelsGen struct { FsOrderDetailTemplate *FsOrderDetailTemplateModel // fs_order_detail_template 订单模板详细表 FsOrderRemark *FsOrderRemarkModel // fs_order_remark 订单备注表 FsPay *FsPayModel // fs_pay 支付记录 + FsPayEvent *FsPayEventModel // fs_pay_event 支付回调事件日志 FsProduct *FsProductModel // fs_product 产品表 FsProductCopy1 *FsProductCopy1Model // fs_product_copy1 产品表 FsProductDesign *FsProductDesignModel // fs_product_design 产品设计表 @@ -144,6 +145,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen { FsOrderDetailTemplate: NewFsOrderDetailTemplateModel(gdb), FsOrderRemark: NewFsOrderRemarkModel(gdb), FsPay: NewFsPayModel(gdb), + FsPayEvent: NewFsPayEventModel(gdb), FsProduct: NewFsProductModel(gdb), FsProductCopy1: NewFsProductCopy1Model(gdb), FsProductDesign: NewFsProductDesignModel(gdb), diff --git a/server/home-user-auth/etc/home-user-auth.yaml b/server/home-user-auth/etc/home-user-auth.yaml index 7ef5a2c9..31722119 100644 --- a/server/home-user-auth/etc/home-user-auth.yaml +++ b/server/home-user-auth/etc/home-user-auth.yaml @@ -20,3 +20,10 @@ OAuth: Stripe: SK: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y" + +PayConfig: + Stripe: + Key: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y" + EndpointSecret: "whsec_f5f9a121d43af3789db7459352f08cf523eb9e0fbf3381f91ba6c97c324c174d" + SuccessURL: "http://www.baidu.com" + CancelURL: "http://www.baidu.com" diff --git a/server/home-user-auth/internal/config/config.go b/server/home-user-auth/internal/config/config.go index 19c515b1..fa7c3bf3 100644 --- a/server/home-user-auth/internal/config/config.go +++ b/server/home-user-auth/internal/config/config.go @@ -28,4 +28,13 @@ type Config struct { Stripe struct { SK string } + + PayConfig struct { + Stripe struct { + EndpointSecret string + Key string + CancelURL string + SuccessURL string + } + } } diff --git a/server/home-user-auth/internal/logic/userordercancellogic.go b/server/home-user-auth/internal/logic/userordercancellogic.go index 56a9ab4a..0f23aa41 100644 --- a/server/home-user-auth/internal/logic/userordercancellogic.go +++ b/server/home-user-auth/internal/logic/userordercancellogic.go @@ -6,11 +6,13 @@ import ( "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "time" "context" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" + handlerUtils "fusenapi/utils/handler" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" @@ -50,11 +52,76 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us } // 判断订单状态 - if *orderInfo.Status == int64(constants.STATUS_NEW_NOT_PAY) { - - } else { + var notCancelStatusMap = make(map[constants.Order]struct{}, 3) + notCancelStatusMap[constants.STATUS_NEW_NOT_PAY] = struct{}{} + notCancelStatusMap[constants.STATUS_NEW_PART_PAY] = struct{}{} + notCancelStatusMap[constants.STATUS_NEW_PAY_COMPLETED] = struct{}{} + _, ok := notCancelStatusMap[constants.Order(*orderInfo.Status)] + if !ok { return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "the order status not cancle") } + var cancelTime int64 = time.Now().Unix() - (*orderInfo.Ctime + int64(constants.CANCLE_ORDER_EXPIRE)) + // 第一次支付成功后48小时后不能进行取消操作 + if orderInfo.IsPayCompleted != nil && cancelTime > 0 { + return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "The current order cannot be cancelled") + } + + // 修改订单--取消状态和取消原因 + *orderInfo.Status = int64(constants.STATUS_NEW_CANCEL) + *orderInfo.IsCancel = 1 + orderInfo.RefundReasonId = &req.RefundReasonId + orderInfo.RefundReason = &req.RefundReason + + var nowTime = time.Now().Unix() + var payList []handlerUtils.PayInfo + // 事务处理 + err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { + // 修改订单信息 + orderModelTS := gmodel.NewFsOrderModel(connGorm) + err = orderModelTS.Update(ctx, orderInfo) + if err != nil { + return err + } + // 新增退款记录 + var isRefund int64 = 0 + refundReasonModelTS := gmodel.NewFsRefundReasonModel(connGorm) + refundReasonModelTS.CreateOrUpdate(ctx, &gmodel.FsRefundReason{ + IsRefund: &isRefund, + RefundReasonId: &req.RefundReasonId, + RefundReason: &req.RefundReason, + OrderId: &orderInfo.Id, + CreatedAt: &nowTime, + }) + // 退款申请 + // 退款申请--查询支付信息 + fsPayModelTS := gmodel.NewFsPayModel(connGorm) + 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 { + return err + } + for _, payInfo := range payInfoList { + var key string + if *payInfo.PaymentMethod == int64(constants.PAYMETHOD_STRIPE) { + key = l.svcCtx.Config.PayConfig.Stripe.Key + } + payList = append(payList, handlerUtils.PayInfo{ + TradeNo: *payInfo.TradeNo, + PaymentMethod: *payInfo.PaymentMethod, + Key: key, + }) + } + return nil + }) + // 退款申请--调取第三方接口发起退款 + handlerUtils.PayRefundHandler(&handlerUtils.PayRefundHandlerReq{ + PayInfoList: payList, + }) + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeOrderCancelledNotOk, "the order cancle failed") + } + return resp.SetStatus(basic.CodeOK) } diff --git a/server/pay/etc/pay.yaml b/server/pay/etc/pay.yaml index 841753e3..831292a9 100644 --- a/server/pay/etc/pay.yaml +++ b/server/pay/etc/pay.yaml @@ -1,7 +1,6 @@ Name: pay Host: 0.0.0.0 Port: 9915 -Timeout: 15000 SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest Auth: AccessSecret: fusen2023 diff --git a/server/pay/internal/handler/orderrefundhandler.go b/server/pay/internal/handler/orderrefundhandler.go new file mode 100644 index 00000000..3d7998ff --- /dev/null +++ b/server/pay/internal/handler/orderrefundhandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/pay/internal/logic" + "fusenapi/server/pay/internal/svc" + "fusenapi/server/pay/internal/types" +) + +func OrderRefundHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.OrderRefundReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewOrderRefundLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.OrderRefund(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/pay/internal/handler/routes.go b/server/pay/internal/handler/routes.go index 28292f5f..f1295e35 100644 --- a/server/pay/internal/handler/routes.go +++ b/server/pay/internal/handler/routes.go @@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/pay/payment-intent", Handler: OrderPaymentIntentHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/pay/refund", + Handler: OrderRefundHandler(serverCtx), + }, { Method: http.MethodPost, Path: "/api/pay/stripe-webhook", diff --git a/server/pay/internal/handler/stripewebhookhandler.go b/server/pay/internal/handler/stripewebhookhandler.go index b4447ba7..ca7689d0 100644 --- a/server/pay/internal/handler/stripewebhookhandler.go +++ b/server/pay/internal/handler/stripewebhookhandler.go @@ -30,6 +30,15 @@ func StripeWebhookHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { // return // } + IPAddress := r.Header.Get("X-Real-Ip") + if IPAddress == "" { + IPAddress = r.Header.Get("X-Forwarded-For") + } + if IPAddress == "" { + IPAddress = r.RemoteAddr + } + + req.RemoteAddr = IPAddress req.Payload = payload req.StripeSignature = r.Header.Get("Stripe-Signature") diff --git a/server/pay/internal/logic/orderrefundlogic.go b/server/pay/internal/logic/orderrefundlogic.go new file mode 100644 index 00000000..5f9e11db --- /dev/null +++ b/server/pay/internal/logic/orderrefundlogic.go @@ -0,0 +1,43 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/pay/internal/svc" + "fusenapi/server/pay/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type OrderRefundLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewOrderRefundLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderRefundLogic { + return &OrderRefundLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *OrderRefundLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *OrderRefundLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *OrderRefundLogic) OrderRefund(req *types.OrderRefundReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/pay/internal/logic/stripewebhooklogic.go b/server/pay/internal/logic/stripewebhooklogic.go index 048b78e7..8deaf2a6 100644 --- a/server/pay/internal/logic/stripewebhooklogic.go +++ b/server/pay/internal/logic/stripewebhooklogic.go @@ -64,6 +64,21 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "Webhook signature verification failed") } + // 新增支付回调事件日志 + var payMethod = int64(constants.PAYMETHOD_STRIPE) + var nowTime = time.Now().Unix() + var eventData = string(event.Data.Raw) + var fsPayEvent = &gmodel.FsPayEvent{ + PayMethod: &payMethod, + EventId: &event.ID, + EventType: &event.Type, + EventData: &eventData, + EventCreated: &event.Created, + Ip: &req.RemoteAddr, + CreatedAt: &nowTime, + } + l.HandlePayEventCreate(fsPayEvent) + // Unmarshal the event data into an appropriate struct depending on its Type switch event.Type { case "charge.succeeded": @@ -94,7 +109,7 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo logx.Error(err) return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded") } - err = l.handlePaymentIntentSucceeded(&paymentIntent) + err = l.HandlePaymentIntentSucceeded(&paymentIntent) if err != nil { return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type Unhandled") } @@ -114,6 +129,12 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo return resp.SetStatus(basic.CodeOK) } +// 回调事件日志 +func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent) error { + _, err := gmodel.NewFsPayEventModel(l.svcCtx.MysqlConn).CreateOrUpdate(l.ctx, fsPayEvent) + return err +} + // session完成 // func (l *StripeWebhookLogic) handlePaymentSessionCompleted(sessionId string, tradeNo string) (err error) { // // 查询支付记录 @@ -137,7 +158,7 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo // } // 成功的付款 -func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error { +func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error { orderSn, ok := paymentIntent.Metadata["order_sn"] if !ok || orderSn == "" { return errors.New("order_sn not found") @@ -146,14 +167,12 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe. // 查询支付记录 payModel := gmodel.NewFsPayModel(l.svcCtx.MysqlConn) rsbPay := payModel.RowSelectBuilder(nil) - rsbPay = rsbPay.Where("order_number = ?", orderSn) + rsbPay = rsbPay.Where("order_number = ?", orderSn).Where("pay_status = ?", constants.PAYSTATUS_UNSUCCESS) payInfo, err := payModel.FindOneByQuery(l.ctx, rsbPay, nil) if err != nil { return err } - if *payInfo.PayStatus == 1 { - return errors.New("pay status 1") - } + //订单信息 orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn) orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) @@ -209,6 +228,7 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe. *payInfo.PayTime = nowTime *payInfo.CardNo = card *payInfo.Brand = brand + *payInfo.TradeNo = paymentIntent.ID _, err = payModelT.CreateOrUpdate(ctx, payInfo) if err != nil { return err @@ -244,12 +264,12 @@ func (l *StripeWebhookLogic) handlePaymentIntentSucceeded(paymentIntent *stripe. // 支付记录是尾款 if *payInfo.PayStage == int64(constants.PAYSTAGE_REMAINING) { - if *orderInfo.Status < int64(constants.STATUS_NEW_PAY_COMPLETED) { + if *fsOrderRelInfo.Status < int64(constants.STATUS_NEW_PAY_COMPLETED) { orderStatus = int64(constants.STATUS_NEW_PAY_COMPLETED) } orderIsPayCompleted = 1 orderInfo.IsPayCompleted = &orderIsPayCompleted - orderPayedAmount = *orderInfo.PayedAmount + paymentIntent.Amount + orderPayedAmount = *fsOrderRelInfo.PayedAmount + paymentIntent.Amount } // 更新订单信息 diff --git a/server/pay/internal/types/types.go b/server/pay/internal/types/types.go index 76c0341e..fab57728 100644 --- a/server/pay/internal/types/types.go +++ b/server/pay/internal/types/types.go @@ -5,6 +5,12 @@ import ( "fusenapi/utils/basic" ) +type OrderRefundReq struct { +} + +type OrderRefundRes struct { +} + type OrderPaymentIntentReq struct { Sn string `form:"sn"` //订单编号 DeliveryMethod int64 `form:"delivery_method"` //发货方式 @@ -20,6 +26,7 @@ type OrderPaymentIntentRes struct { type StripeWebhookReq struct { Payload []byte `json:"base_byte_slice,optional"` StripeSignature string `json:"Stripe-Signature"` + RemoteAddr string `json:"remote_addr"` } type Request struct { diff --git a/server_api/pay.api b/server_api/pay.api index b7a1b0d1..4044c1e3 100644 --- a/server_api/pay.api +++ b/server_api/pay.api @@ -14,10 +14,20 @@ service pay { @handler OrderPaymentIntentHandler post /api/pay/payment-intent(OrderPaymentIntentReq) returns (response); + @handler OrderRefundHandler + post /api/pay/refund(OrderRefundReq) returns (response); + @handler StripeWebhookHandler post /api/pay/stripe-webhook(StripeWebhookReq) returns (response); + } +// 退款 +type ( + OrderRefundReq struct{} + OrderRefundRes struct{} +) + // 生成预付款 type ( OrderPaymentIntentReq { @@ -37,5 +47,6 @@ type ( StripeWebhookReq { Payload []byte `json:"base_byte_slice,optional"` StripeSignature string `json:"Stripe-Signature"` + RemoteAddr string `json:"remote_addr"` } ) \ No newline at end of file diff --git a/utils/basic/basic.go b/utils/basic/basic.go index 7ec3d02f..66aaffc0 100644 --- a/utils/basic/basic.go +++ b/utils/basic/basic.go @@ -52,9 +52,11 @@ var ( CodeSafeValueRangeErr = &StatusResponse{5040, "value not in range"} // 值不在范围内 CodeTemplateErr = &StatusResponse{5040, "template parsed error"} // 模板解析错误 - CodeOrderNotFoundErr = &StatusResponse{5030, "order not found"} //未找到订单 - CodeCloudOrderNotFoundErr = &StatusResponse{5031, "cloud order not found"} //未找到云仓订单 - CodeOrderNotCancelledErr = &StatusResponse{5032, "current order cannot be cancelled"} // 当前订单无法取消 + CodeOrderNotFoundErr = &StatusResponse{5030, "order not found"} //未找到订单 + CodeCloudOrderNotFoundErr = &StatusResponse{5031, "cloud order not found"} //未找到云仓订单 + CodeOrderNotCancelledErr = &StatusResponse{5032, "current order cannot be cancelled"} // 当前订单无法取消 + CodeOrderCancelledNotOk = &StatusResponse{5033, "current order cancelled failed"} // 当前订单取消失败 + CodeOrderCancelledOk = &StatusResponse{5034, "current order cancelled successful"} // 当前订单取消成功 CodePayNotFoundErr = &StatusResponse{5020, "pay info not found"} // 支付信息无法查询 CodePayCancelOk = &StatusResponse{5021, "cancellation successful"} // 支付取消成功 diff --git a/utils/handler/payHandler.go b/utils/handler/payHandler.go new file mode 100644 index 00000000..f69412b7 --- /dev/null +++ b/utils/handler/payHandler.go @@ -0,0 +1,64 @@ +package handler + +import ( + "fusenapi/constants" + "fusenapi/utils/pay" + + "github.com/zeromicro/go-zero/core/mr" +) + +type ( + PayInfo struct { + TradeNo string `json:"trade_no"` + PaymentMethod int64 `json:"payment_method"` + Key string `json:"key"` + } + PayRefundHandlerReq struct { + PayInfoList []PayInfo + } + PayRefundHandlerRes struct { + } +) + +// 申请第三方退款 +func PayRefundHandler(req *PayRefundHandlerReq) (res PayRefundHandlerRes, err error) { + + _, err = mr.MapReduce(func(source chan<- interface{}) { + for _, payInfo := range req.PayInfoList { + source <- payInfo + } + }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { + payConfig := new(pay.Config) + payInfo := item.(PayInfo) + switch payInfo.PaymentMethod { + case int64(constants.PAYMETHOD_STRIPE): + // stripe 支付 + payConfig.Stripe.Key = payInfo.Key + } + payDriver := pay.NewPayDriver(payInfo.PaymentMethod, payConfig) + _, err = payDriver.PayRefund(&pay.PayRefundReq{ + TradeNo: payInfo.TradeNo, + }) + + if err != nil { + // Notice 如果不加 cancel(err),会返回校验成功的id; 如果加上cancel(err),返回的结果会是一个空列表 + // Notice 实际上,如果这里返回错误,其他协程直接就退出了! + // Notice 看实际中业务的需求情况来定了... + cancel(err) + } + // Notice 这个必须加! + writer.Write(payInfo) + }, func(pipe <-chan interface{}, writer mr.Writer[interface{}], cancel func(error)) { + var payInfoList []PayInfo + for p := range pipe { + payInfoList = append(payInfoList, p.(PayInfo)) + } + // Notice 这个必须加! + writer.Write(payInfoList) + }) + if err != nil { + return res, err + } + + return res, nil +} diff --git a/utils/pay/pay.go b/utils/pay/pay.go index a378e4a8..e982139e 100644 --- a/utils/pay/pay.go +++ b/utils/pay/pay.go @@ -20,7 +20,12 @@ func NewPayDriver(PayMethod int64, config *Config) Pay { // Pay 支付集成接口 type Pay interface { + + // 支付预处理 GeneratePrepayment(req *GeneratePrepaymentReq) (res *GeneratePrepaymentRes, err error) + + // 支付退款申请 + PayRefund(req *PayRefundReq) (res *PayRefundRes, err error) } type GeneratePrepaymentReq struct { @@ -41,3 +46,10 @@ type GeneratePrepaymentRes struct { ClientSecret string `json:"clientSecret"` //交易密钥 SessionId string `json:"session_id"` //SessionId } + +type PayRefundReq struct { + TradeNo string `json:"trade_no"` // 交易编号 +} + +type PayRefundRes struct { +} diff --git a/utils/pay/stripe.go b/utils/pay/stripe.go index cc8127f7..e2e13799 100644 --- a/utils/pay/stripe.go +++ b/utils/pay/stripe.go @@ -3,12 +3,25 @@ package pay import ( "github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74/checkout/session" + "github.com/stripe/stripe-go/v74/refund" + "github.com/zeromicro/go-zero/core/logx" ) type Stripe struct { Key string `json:"key"` } +// 生成退款 +func (stripePay *Stripe) PayRefund(req *PayRefundReq) (res *PayRefundRes, err error) { + stripe.Key = stripePay.Key + params := &stripe.RefundParams{PaymentIntent: stripe.String(req.TradeNo)} + _, err = refund.New(params) + if err != nil { + logx.Error(err) + } + return res, err +} + // 生成预付款 func (stripePay *Stripe) GeneratePrepayment(req *GeneratePrepaymentReq) (res *GeneratePrepaymentRes, err error) { var productData stripe.CheckoutSessionLineItemPriceDataProductDataParams From 5a713d4d9dd777449c05b78a1d9b4d01fff50622 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 31 Jul 2023 10:08:56 +0800 Subject: [PATCH 02/60] fix --- server/websocket/internal/logic/ws_render_image_logic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index c91d09c0..7e969d40 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -61,7 +61,7 @@ func (w *wsConnectItem) SendToCloudRender(data []byte) { } //发送给对应的流水线组装数据 if err := w.rabbitMq.SendMsg(constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, data); err != nil { - logx.Error("发送渲染任务数据到MQ失败:", string(data)) + logx.Error("发送渲染任务数据到MQ失败:", string(data), "err:", err) continue } logx.Info("发送渲染数据到rabbitmq成功:", string(data)) From c7f3ca5ab40aef50be5df2d776906eec46afbaa7 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 31 Jul 2023 10:40:54 +0800 Subject: [PATCH 03/60] fix --- constants/rabbitmq.go | 6 ------ initalize/rabbitmq.go | 8 +++++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/constants/rabbitmq.go b/constants/rabbitmq.go index c7b8281e..85269033 100644 --- a/constants/rabbitmq.go +++ b/constants/rabbitmq.go @@ -9,9 +9,3 @@ const ( //渲染结果数据队列 RABBIT_MQ_RENDER_RESULT_DATA RABBIT_MQ = "RABBIT_MQ_RENDER_RESULT_DATA" ) - -// 队列列表 -var MQ_QUEUE_ARR = []RABBIT_MQ{ - RABBIT_MQ_ASSEMBLE_RENDER_DATA, - RABBIT_MQ_RENDER_RESULT_DATA, -} diff --git a/initalize/rabbitmq.go b/initalize/rabbitmq.go index 3713a7b8..fc92d496 100644 --- a/initalize/rabbitmq.go +++ b/initalize/rabbitmq.go @@ -18,6 +18,12 @@ type queueItem struct { queue amqp.Queue } +// 队列列表 +var mqQueueArr = []constants.RABBIT_MQ{ + constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, + constants.RABBIT_MQ_RENDER_RESULT_DATA, +} + // 存储连接 var mapMq = make(map[constants.RABBIT_MQ]queueItem) @@ -35,7 +41,7 @@ func InitRabbitMq(url string, config *tls.Config) *RabbitMqHandle { log.Fatalf("Failed to open a channel: %v", err) } //声明队列 - for _, queueName := range constants.MQ_QUEUE_ARR { + for _, queueName := range mqQueueArr { q, err := ch.QueueDeclare( string(queueName), // 队列名 true, // 是否持久化 From f2109eee9b5a3fc080df07114f110838282703e0 Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 31 Jul 2023 11:32:40 +0800 Subject: [PATCH 04/60] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E9=80=80=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_refund_reason_logic.go | 27 +++++++ .../internal/logic/userordercancellogic.go | 12 +-- .../pay/internal/logic/stripewebhooklogic.go | 80 ++++++++++++++++++- utils/basic/basic.go | 2 + 4 files changed, 112 insertions(+), 9 deletions(-) diff --git a/model/gmodel/fs_refund_reason_logic.go b/model/gmodel/fs_refund_reason_logic.go index 76d6810b..48e67d51 100644 --- a/model/gmodel/fs_refund_reason_logic.go +++ b/model/gmodel/fs_refund_reason_logic.go @@ -2,6 +2,7 @@ package gmodel import ( "context" + "fusenapi/utils/handler" "gorm.io/gorm" ) @@ -35,6 +36,32 @@ func (m *FsRefundReasonModel) CreateOrUpdate(ctx context.Context, req *FsRefundR return req, err } +func (m *FsRefundReasonModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, filterMap map[string]string) (*FsRefundReason, error) { + var resp FsRefundReason + + if filterMap != nil { + rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + } + + result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) + if result.Error != nil { + return nil, result.Error + } else { + return &resp, nil + } +} + +func (m *FsRefundReasonModel) RowSelectBuilder(selectData []string) *gorm.DB { + var rowBuilder = m.db.Table(m.name) + + if selectData != nil { + rowBuilder = rowBuilder.Select(selectData) + } else { + rowBuilder = rowBuilder.Select("*") + } + return rowBuilder +} + func (m *FsRefundReasonModel) TableName() string { return m.name } diff --git a/server/home-user-auth/internal/logic/userordercancellogic.go b/server/home-user-auth/internal/logic/userordercancellogic.go index 0f23aa41..ce64a5b2 100644 --- a/server/home-user-auth/internal/logic/userordercancellogic.go +++ b/server/home-user-auth/internal/logic/userordercancellogic.go @@ -52,18 +52,18 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us } // 判断订单状态 - var notCancelStatusMap = make(map[constants.Order]struct{}, 3) - notCancelStatusMap[constants.STATUS_NEW_NOT_PAY] = struct{}{} - notCancelStatusMap[constants.STATUS_NEW_PART_PAY] = struct{}{} - notCancelStatusMap[constants.STATUS_NEW_PAY_COMPLETED] = struct{}{} - _, ok := notCancelStatusMap[constants.Order(*orderInfo.Status)] + var notCancelStatusMap = make(map[int64]struct{}, 3) + notCancelStatusMap[int64(constants.STATUS_NEW_NOT_PAY)] = struct{}{} + notCancelStatusMap[int64(constants.STATUS_NEW_PART_PAY)] = struct{}{} + notCancelStatusMap[int64(constants.STATUS_NEW_PAY_COMPLETED)] = struct{}{} + _, ok := notCancelStatusMap[int64(*orderInfo.Status)] if !ok { return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "the order status not cancle") } var cancelTime int64 = time.Now().Unix() - (*orderInfo.Ctime + int64(constants.CANCLE_ORDER_EXPIRE)) // 第一次支付成功后48小时后不能进行取消操作 - if orderInfo.IsPayCompleted != nil && cancelTime > 0 { + if *orderInfo.IsPayCompleted == 1 && cancelTime > 0 { return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "The current order cannot be cancelled") } diff --git a/server/pay/internal/logic/stripewebhooklogic.go b/server/pay/internal/logic/stripewebhooklogic.go index 8deaf2a6..038c2bce 100644 --- a/server/pay/internal/logic/stripewebhooklogic.go +++ b/server/pay/internal/logic/stripewebhooklogic.go @@ -106,12 +106,13 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo var paymentIntent stripe.PaymentIntent err := json.Unmarshal(event.Data.Raw, &paymentIntent) if err != nil { - logx.Error(err) + logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type payment_intent.succeeded") return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded") } err = l.HandlePaymentIntentSucceeded(&paymentIntent) if err != nil { - return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type Unhandled") + logx.Errorf("err:%+v,desc:%s", err, "pay notify handle payment_intent.succeeded") + return resp.SetStatusWithMessage(basic.CodePaybackNotOk, "pay notify handle payment_intent.succeeded") } case "payment_method.attached": var paymentMethod stripe.PaymentMethod @@ -120,6 +121,19 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo logx.Error(err) return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_method.attached") } + case "charge.refunded": + var chargeRefunded stripe.Charge + err := json.Unmarshal(event.Data.Raw, &chargeRefunded) + if err != nil { + logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type charge.refunded") + return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type charge.refunded") + } + err = l.HandleChargeRefunded(&chargeRefunded) + if err != nil { + logx.Errorf("err:%+v,desc:%s", err, "pay notify handle charge.refunded") + return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify handle charge.refunded") + } + // ... handle other event types default: logx.Error("Unhandled event") @@ -135,6 +149,66 @@ func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent) return err } +// 退款成功 +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) { + // 查询支付记录 + 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) + if err != nil { + return err + } + // 更新支付记录 + *payInfo.IsRefund = 1 + _, err = payModelT.CreateOrUpdate(ctx, payInfo) + if err != nil { + return err + } + // 获取是否还有未退款的数据 + payModelTRSB2 := payModelTRSB.Where("order_number = ?", payInfo.OrderNumber).Where("pay_status = ?", constants.PAYSTATUS_SUCCESS).Where("is_refund = ?", 0) + count, err := payModelT.FindCount(l.ctx, payModelTRSB2, nil) + if count == 0 { + // 退款完成更新订单状态 + orderModelT := gmodel.NewFsOrderModel(connGorm) + orderModelTRSB := orderModelT.RowSelectBuilder(nil).Where("sn =?", payInfo.OrderNumber) + orderInfoRel, err := orderModelT.FindOneByQuery(ctx, orderModelTRSB, nil) + if err != nil { + return err + } + var isRefunded int64 = 1 + var isRefunding int64 = 1 + var orderStatus int64 = int64(constants.STATUS_NEW_REFUNDED) + var orderInfo = &gmodel.FsOrder{} + orderInfo.Id = orderInfoRel.Id + orderInfo.IsRefunded = &isRefunded + orderInfo.IsRefunding = &isRefunding + orderInfo.Status = &orderStatus + orderModelT.Update(ctx, orderInfo) + + // 记录退款原因 + refundReasonModelT := gmodel.NewFsRefundReasonModel(connGorm) + refundReasonModelTRSB := refundReasonModelT.RowSelectBuilder(nil).Where("order_id =?", orderInfoRel.Id) + refundReasonInfo, err := refundReasonModelT.FindOneByQuery(ctx, refundReasonModelTRSB, nil) + if err != nil { + return err + } + *refundReasonInfo.IsRefund = 1 + _, err = refundReasonModelT.CreateOrUpdate(ctx, refundReasonInfo) + if err != nil { + return err + } + } + return err + }) + } + return err +} + // session完成 // func (l *StripeWebhookLogic) handlePaymentSessionCompleted(sessionId string, tradeNo string) (err error) { // // 查询支付记录 @@ -157,7 +231,7 @@ func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent) // return err // } -// 成功的付款 +// 付款成功 func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error { orderSn, ok := paymentIntent.Metadata["order_sn"] if !ok || orderSn == "" { diff --git a/utils/basic/basic.go b/utils/basic/basic.go index 66aaffc0..c8a5f370 100644 --- a/utils/basic/basic.go +++ b/utils/basic/basic.go @@ -62,6 +62,8 @@ var ( CodePayCancelOk = &StatusResponse{5021, "cancellation successful"} // 支付取消成功 CodePayCancelNotOk = &StatusResponse{5022, "cancellation failed"} // 支付取消失败 + CodePaybackNotOk = &StatusResponse{5023, "pay back failed"} // 支付回调处理失败 + CodeGuestDupErr = &StatusResponse{5010, "user is already guest and does not need to reapply"} // 用户已经是访客用户,无需重复申请 CodeGuestGenErr = &StatusResponse{5011, "serialization failed for guest ID"} // 访客ID序列化失败 From c86a6bbe757262297ddb95b250a90dc3cc52a388 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 31 Jul 2023 16:45:48 +0800 Subject: [PATCH 05/60] fix --- server/product/internal/logic/gettagproductlistlogic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index 27ce7ba5..7badfd95 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -220,7 +220,7 @@ func (l *GetTagProductListLogic) dealWithTagMenuData(req dealWithTagMenuDataReq) *req.MinLevel = lenLevel } tagTem := types.TagItem{ - TagProductList: nil, + TagProductList: []interface{}{}, TypeName: *tagInfo.Title, TypeId: tagInfo.Id, Icon: *tagInfo.Icon, From c75e55a5cfa63e7748935f51a9c36e22a1fe56f3 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Tue, 1 Aug 2023 10:30:57 +0800 Subject: [PATCH 06/60] fix --- server/product/internal/logic/gettagproductlistlogic.go | 1 + server/product/internal/types/types.go | 1 + server_api/product.api | 1 + 3 files changed, 3 insertions(+) diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index 7badfd95..bd17aa12 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -222,6 +222,7 @@ func (l *GetTagProductListLogic) dealWithTagMenuData(req dealWithTagMenuDataReq) tagTem := types.TagItem{ TagProductList: []interface{}{}, TypeName: *tagInfo.Title, + Description: *tagInfo.Description, TypeId: tagInfo.Id, Icon: *tagInfo.Icon, Sort: *tagInfo.Sort, diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index f2d27f0a..d374460a 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -259,6 +259,7 @@ type GetTagProductListRsp struct { type TagItem struct { TypeName string `json:"type_name"` + Description string `json:"description"` TypeId int64 `json:"type_id"` Icon string `json:"icon"` Sort int64 `json:"sort"` diff --git a/server_api/product.api b/server_api/product.api index 48ac5a50..03fb29b6 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -309,6 +309,7 @@ type GetTagProductListRsp { } type TagItem { TypeName string `json:"type_name"` + Description string `json:"description"` TypeId int64 `json:"type_id"` Icon string `json:"icon"` Sort int64 `json:"sort"` From 4a2a7822b7e529457c944aa5208a24b4a44a40ff Mon Sep 17 00:00:00 2001 From: Hiven Date: Tue, 1 Aug 2023 18:13:30 +0800 Subject: [PATCH 07/60] =?UTF-8?q?=E5=A4=9A=E6=96=87=E4=BB=B6=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0--=E5=90=8E=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_resource_gen.go | 1 + model/gmodel/fs_resource_logic.go | 84 ++++++- model/gmodel/fs_resources_logic.go | 71 +++++- server/upload/internal/handler/routes.go | 15 ++ .../internal/handler/uploadcallbackhandler.go | 35 +++ .../handler/uploadfilesbackendhandler.go | 35 +++ .../handler/uploadfilesfrontendhandler.go | 35 +++ .../internal/logic/uploadcallbacklogic.go | 42 ++++ .../internal/logic/uploadfilesbackendlogic.go | 226 ++++++++++++++++++ .../logic/uploadfilesfrontendlogic.go | 45 ++++ server/upload/internal/types/types.go | 19 ++ server_api/upload.api | 36 ++- utils/basic/basic.go | 2 + utils/format/s3keyname.go | 2 + 14 files changed, 644 insertions(+), 4 deletions(-) create mode 100644 server/upload/internal/handler/uploadcallbackhandler.go create mode 100644 server/upload/internal/handler/uploadfilesbackendhandler.go create mode 100644 server/upload/internal/handler/uploadfilesfrontendhandler.go create mode 100644 server/upload/internal/logic/uploadcallbacklogic.go create mode 100644 server/upload/internal/logic/uploadfilesbackendlogic.go create mode 100644 server/upload/internal/logic/uploadfilesfrontendlogic.go diff --git a/model/gmodel/fs_resource_gen.go b/model/gmodel/fs_resource_gen.go index 23623ee0..4c7d2311 100644 --- a/model/gmodel/fs_resource_gen.go +++ b/model/gmodel/fs_resource_gen.go @@ -16,6 +16,7 @@ type FsResource struct { UploadedAt *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"uploaded_at"` // 上传时间 Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 MetaKey1 *string `gorm:"index;default:'';" json:"meta_key1"` // 需要关键信息查询的自定义属性1,可以动态增加 + ApiType *int64 `gorm:"default:1;" json:"api_type"` // 调用类型:1=对外,2=对内 } type FsResourceModel struct { db *gorm.DB diff --git a/model/gmodel/fs_resource_logic.go b/model/gmodel/fs_resource_logic.go index e68225aa..814257c5 100644 --- a/model/gmodel/fs_resource_logic.go +++ b/model/gmodel/fs_resource_logic.go @@ -1,2 +1,84 @@ package gmodel -// TODO: 使用model的属性做你想做的 \ No newline at end of file + +import ( + "context" + "errors" + "fusenapi/utils/handler" + + "gorm.io/gorm" +) + +// TODO: 使用model的属性做你想做的 + +func (p *FsResourceModel) FindOneById(ctx context.Context, resourceId string) (*FsResource, error) { + var resp FsResource + result := p.db.Table(p.name).WithContext(ctx).Where("resource_id =?", resourceId).Take(&resp) + if result.Error != nil { + // 检查 ErrRecordNotFound 错误 + if !errors.Is(result.Error, gorm.ErrRecordNotFound) { + return nil, result.Error + } + } + return &resp, nil +} + +func (p *FsResourceModel) CreateOrUpdate(ctx context.Context, req *FsResource) (resp *FsResource, err error) { + rowBuilder := p.db.Table(p.name).WithContext(ctx) + if req.ResourceId != "" { + err = rowBuilder.Save(req).Error + } else { + err = rowBuilder.Create(req).Error + } + return req, err +} + +func (m *FsResourceModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, filterMap map[string]string) (*FsResource, error) { + var resp FsResource + + if filterMap != nil { + rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + } + + result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) + if result.Error != nil { + return nil, result.Error + } else { + return &resp, nil + } +} + +func (m *FsResourceModel) RowSelectBuilder(selectData []string) *gorm.DB { + var rowBuilder = m.db.Table(m.name) + + if selectData != nil { + rowBuilder = rowBuilder.Select(selectData) + } else { + rowBuilder = rowBuilder.Select("*") + } + return rowBuilder +} + +// 事务 +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 err + } + + if err := fn(ctx, tx); err != nil { + tx.Rollback() + return err + } + + return tx.Commit().Error +} + +func (m *FsResourceModel) TableName() string { + return m.name +} diff --git a/model/gmodel/fs_resources_logic.go b/model/gmodel/fs_resources_logic.go index e68225aa..767af34a 100644 --- a/model/gmodel/fs_resources_logic.go +++ b/model/gmodel/fs_resources_logic.go @@ -1,2 +1,71 @@ package gmodel -// TODO: 使用model的属性做你想做的 \ No newline at end of file + +import ( + "context" + "fusenapi/utils/handler" + + "gorm.io/gorm" +) + +// TODO: 使用model的属性做你想做的 + +func (p *FsResourcesModel) CreateOrUpdate(ctx context.Context, req *FsResources) (resp *FsResources, err error) { + rowBuilder := p.db.Table(p.name).WithContext(ctx) + if req.ResourceId != "" { + err = rowBuilder.Save(req).Error + } else { + err = rowBuilder.Create(req).Error + } + return req, err +} + +func (m *FsResourcesModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, filterMap map[string]string) (*FsResources, error) { + var resp FsResources + + if filterMap != nil { + rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + } + + result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) + if result.Error != nil { + return nil, result.Error + } else { + return &resp, nil + } +} + +func (m *FsResourcesModel) RowSelectBuilder(selectData []string) *gorm.DB { + var rowBuilder = m.db.Table(m.name) + + if selectData != nil { + rowBuilder = rowBuilder.Select(selectData) + } else { + rowBuilder = rowBuilder.Select("*") + } + return rowBuilder +} + +// 事务 +func (m *FsResourcesModel) 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 err + } + + if err := fn(ctx, tx); err != nil { + tx.Rollback() + return err + } + + return tx.Commit().Error +} + +func (m *FsResourcesModel) TableName() string { + return m.name +} diff --git a/server/upload/internal/handler/routes.go b/server/upload/internal/handler/routes.go index b3a3cee2..1417f043 100644 --- a/server/upload/internal/handler/routes.go +++ b/server/upload/internal/handler/routes.go @@ -32,6 +32,21 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/upload/qrcode", Handler: UploadQrcodeHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/upload/upload-files-backend", + Handler: UploadFilesBackendHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/api/upload/upload-files-frontend", + Handler: UploadFilesFrontendHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/api/upload/upload-callback", + Handler: UploadCallbackHandler(serverCtx), + }, }, ) } diff --git a/server/upload/internal/handler/uploadcallbackhandler.go b/server/upload/internal/handler/uploadcallbackhandler.go new file mode 100644 index 00000000..3882a06b --- /dev/null +++ b/server/upload/internal/handler/uploadcallbackhandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/upload/internal/logic" + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" +) + +func UploadCallbackHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.UploadCallbackReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUploadCallbackLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UploadCallback(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/upload/internal/handler/uploadfilesbackendhandler.go b/server/upload/internal/handler/uploadfilesbackendhandler.go new file mode 100644 index 00000000..38fe3326 --- /dev/null +++ b/server/upload/internal/handler/uploadfilesbackendhandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/upload/internal/logic" + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" +) + +func UploadFilesBackendHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.UploadFilesReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUploadFilesBackendLogic(r, svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UploadFilesBackend(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/upload/internal/handler/uploadfilesfrontendhandler.go b/server/upload/internal/handler/uploadfilesfrontendhandler.go new file mode 100644 index 00000000..f28f5eb1 --- /dev/null +++ b/server/upload/internal/handler/uploadfilesfrontendhandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/upload/internal/logic" + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" +) + +func UploadFilesFrontendHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.UploadFilesReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUploadFilesFrontendLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UploadFilesFrontend(&req, userinfo) + + 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 new file mode 100644 index 00000000..1f9147d5 --- /dev/null +++ b/server/upload/internal/logic/uploadcallbacklogic.go @@ -0,0 +1,42 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UploadCallbackLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUploadCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadCallbackLogic { + return &UploadCallbackLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *UploadCallbackLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UploadCallbackLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go new file mode 100644 index 00000000..c01b71e4 --- /dev/null +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -0,0 +1,226 @@ +package logic + +import ( + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "io" + "net/http" + "time" + + "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" + "github.com/zeromicro/go-zero/core/mr" +) + +type UploadFilesBackendLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext + r *http.Request +} + +func NewUploadFilesBackendLogic(r *http.Request, svcCtx *svc.ServiceContext) *UploadFilesBackendLogic { + return &UploadFilesBackendLogic{ + Logger: logx.WithContext(r.Context()), + ctx: r.Context(), + svcCtx: svcCtx, + r: r, + } +} + +// 处理进入前逻辑w,r +// func (l *UploadFilesBackendLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UploadFilesBackendLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, 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 userId int64 + var guestId int64 + + // 检查用户是否是游客 + if userinfo.IsGuest() { + // 如果是,使用游客ID和游客键名格式 + guestId = userinfo.GuestId + } else { + // 否则,使用用户ID和用户键名格式 + userId = userinfo.UserId + } + + var aa = make([]types.UploadInfo, 2) + aa[0].FileKeys = "202308011632" + aa[1].FileKeys = "202308011633" + req.UploadInfo = aa + var fileLen = len(req.UploadInfo) + + if fileLen == 0 { + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,no files") + } + if req.ApiType == 1 && fileLen > 100 { + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err, files count is beyond the maximum") + } + //设置内存大小 + l.r.ParseMultipartForm(32 << 20) + //获取上传的文件组 + files := l.r.MultipartForm.File["file"] + + // 设置AWS会话的区域 + l.svcCtx.AwsSession.Config.Region = aws.String("us-west-1") + + // 创建新的S3服务实例 + svc := s3.New(l.svcCtx.AwsSession) + + // 定义S3请求和当前时间 + var s3req *request.Request + + var uploadBucket = req.UploadBucket + resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) + result, err := mr.MapReduce(func(source chan<- interface{}) { + for i, info := range req.UploadInfo { + fileType := files[i].Header.Get("Content-Type") + // 打开文件 + file, err := files[i].Open() + if err != nil { + logx.Error(err) + } + defer file.Close() + // 读取数据流 + ioData, err := io.ReadAll(file) + if err != nil { + logx.Error(err) + } + + // 一系列业务逻辑....验证类型,文件大小 + var fileKey string = info.FileKeys + source <- uploadData{ + FileKey: fileKey, + FileType: fileType, + Metadata: info.Metadata, + FileData: ioData, + ApiType: req.ApiType, + } + } + }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { + var uploadUrl = uploadUrl{} + uploadDataInfo := item.(uploadData) + + var resourceId string = uploadDataInfo.FileKey + // 查询数据库 + resourceInfo, err := resourceModel.FindOneById(l.ctx, resourceId) + if err == nil && resourceInfo.ResourceId != "" { + uploadUrl.Status = 1 + uploadUrl.ResourceId = resourceId + uploadUrl.Url = *resourceInfo.ResourceUrl + uploadUrl.Key = resourceId + } else { + // 创建S3对象存储请求 + s3req, _ = svc.PutObjectRequest( + &s3.PutObjectInput{ + Bucket: &uploadBucket, + Key: &uploadDataInfo.FileKey, + }, + ) + + // 设置请求体为文件数据 + s3req.SetBufferBody(uploadDataInfo.FileData) + + // 发送请求 + err = s3req.Send() + + // 检查是否有错误 + if err != nil { + logx.Error(err) + uploadUrl.Status = 0 + uploadUrl.Url = "" + uploadUrl.Key = uploadDataInfo.FileKey + } else { + var url = s3req.HTTPRequest.URL.String() + // 打印请求URL + logx.Info(url) + uploadUrl.Status = 1 + uploadUrl.Url = url + uploadUrl.Key = uploadDataInfo.FileKey + uploadUrl.ResourceId = resourceId + var version string = "0.0.1" + var nowTime = time.Now() + _, err = resourceModel.CreateOrUpdate(l.ctx, &gmodel.FsResource{ + ResourceId: resourceId, + UserId: &userId, + GuestId: &guestId, + ResourceType: &uploadDataInfo.FileType, + ResourceUrl: &url, + Version: &version, + UploadedAt: &nowTime, + Metadata: &uploadDataInfo.Metadata, + ApiType: &uploadDataInfo.ApiType, + }) + if err != nil { + logx.Error(err) + } + } + } + + // Notice 这个必须加! + writer.Write(uploadUrl) + }, func(pipe <-chan interface{}, writer mr.Writer[interface{}], cancel func(error)) { + var uploadUrlList = make(map[string][]*uploadUrl) + var uploadUrlListFail []*uploadUrl + var uploadUrlListSuccess []*uploadUrl + for p := range pipe { + var uploadUrl = p.(uploadUrl) + if uploadUrl.Status == 1 { + uploadUrlListSuccess = append(uploadUrlListSuccess, &uploadUrl) + } else { + uploadUrlListFail = append(uploadUrlListFail, &uploadUrl) + } + } + + // Notice 这个必须加! + uploadUrlList["success"] = uploadUrlListSuccess + uploadUrlList["fail"] = uploadUrlListFail + writer.Write(uploadUrlList) + }) + if err != nil { + logx.Error(err) + } + + // 返回成功的响应和上传URL + return resp.SetStatus(basic.CodeOK, map[string]interface{}{ + "upload_urls": result, + }) +} + +type uploadData struct { + ApiType int64 `json:"api_type"` + FileType string `json:"file_type"` + FileKey string `json:"file_key"` + Metadata string `json:"metadata"` + FileData []byte `fsfile:"data"` +} + +type uploadUrl struct { + Status int64 `json:"status"` + ResourceId string `json:"resource_id"` + Url string `json:"url"` + Key string `json:"key"` + Metadata string `json:"metadata"` +} diff --git a/server/upload/internal/logic/uploadfilesfrontendlogic.go b/server/upload/internal/logic/uploadfilesfrontendlogic.go new file mode 100644 index 00000000..c086f8e7 --- /dev/null +++ b/server/upload/internal/logic/uploadfilesfrontendlogic.go @@ -0,0 +1,45 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UploadFilesFrontendLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUploadFilesFrontendLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadFilesFrontendLogic { + return &UploadFilesFrontendLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *UploadFilesFrontendLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UploadFilesFrontendLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + // 检查用户是否是旁观者,旁观者没有文件上传权限 + + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index 9f64f4ea..a684b1c0 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -5,6 +5,25 @@ import ( "fusenapi/utils/basic" ) +type UploadInfo struct { + FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 + Metadata string `form:"file_keys,optional"` // 上传文件额外信息 +} + +type UploadFilesReq struct { + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 + UploadBucket string `form:"upload_bucket"` // 上传桶名 + UploadInfo []UploadInfo `form:"upload_info,optional"` // 上传信息 +} + +type UploadCallbackReq struct { + FileType string `form:"file_type"` // 文件类型 / fbx / hdr + UploadKey string `form:"upload_key"` // 上传KEY + UploadBucket string `form:"upload_bucket"` // 上传桶名 + Version string `form:"version,optional"` // 版本信息 + Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 +} + type RequestUpFile struct { UpFile string `form:"upfile"` IsCut string `form:"is_cut"` // 是否裁剪 diff --git a/server_api/upload.api b/server_api/upload.api index 91171381..52dcb143 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -12,17 +12,49 @@ import "basic.api" service upload { @handler UploadUpFileHandler get /api/upload/up-file(RequestUpFile) returns (response); - + @handler UploadFileFrontendHandler post /api/upload/upload-file-frontend(RequestUploadFileFrontend) returns (response); - + @handler UploadFileBackendHandler post /api/upload/upload-file-backend(RequestUploadFileBackend) returns (response); //生成二维码 @handler UploadQrcodeHandler post /api/upload/qrcode(UploadQrcodeReq) returns (response); + + // 上传文件发起--单个文件--后端上传 + @handler UploadFilesBackendHandler + post /api/upload/upload-files-backend(UploadFilesReq) returns (response); + + // 上传文件发起--多个文件--前端上传 + @handler UploadFilesFrontendHandler + post /api/upload/upload-files-frontend(UploadFilesReq) returns (response); + + // 上传文件回调 + @handler UploadCallbackHandler + post /api/upload/upload-callback(UploadCallbackReq) returns (response); } +type ( + UploadInfo { + FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 + Metadata string `form:"file_keys,optional"` // 上传文件额外信息 + } + + UploadFilesReq { + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 + UploadBucket string `form:"upload_bucket"` // 上传桶名 + UploadInfo []UploadInfo `form:"upload_info,optional"` // 上传信息 + } + UploadCallbackReq { + FileType string `form:"file_type"` // 文件类型 / fbx / hdr + UploadKey string `form:"upload_key"` // 上传KEY + UploadBucket string `form:"upload_bucket"` // 上传桶名 + Version string `form:"version,optional"` // 版本信息 + Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 + } +) + type RequestUpFile { UpFile string `form:"upfile"` IsCut string `form:"is_cut"` // 是否裁剪 diff --git a/utils/basic/basic.go b/utils/basic/basic.go index c8a5f370..a2ae1644 100644 --- a/utils/basic/basic.go +++ b/utils/basic/basic.go @@ -76,6 +76,8 @@ var ( CodeAesCbcEncryptionErr = &StatusResponse{5106, "encryption data err"} // 加密数据失败 CodeAesCbcDecryptionErr = &StatusResponse{5107, "decryption data err"} // 解密数据失败 + + CodeFileUploadErr = &StatusResponse{5110, "file upload err"} // 文件上传失败 ) type Response struct { diff --git a/utils/format/s3keyname.go b/utils/format/s3keyname.go index a72a1447..706ebbfd 100644 --- a/utils/format/s3keyname.go +++ b/utils/format/s3keyname.go @@ -107,3 +107,5 @@ func FormatS3KeyNameGuest(guestid int64, now time.Time, env string, category Typ } } + +// generateS3KeyName 生成 From a0ed98d2d15ab8f108dcc24fa19ee8bfa8be3b6d Mon Sep 17 00:00:00 2001 From: Hiven Date: Tue, 1 Aug 2023 19:49:56 +0800 Subject: [PATCH 08/60] =?UTF-8?q?=E5=A4=9A=E6=96=87=E4=BB=B6=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0--=E5=89=8D=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/logic/uploadfilesbackendlogic.go | 6 +- .../logic/uploadfilesfrontendlogic.go | 104 +++++++++++++++++- server/upload/internal/types/types.go | 1 + server_api/upload.api | 1 + 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index c01b71e4..95b0bc86 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -80,6 +80,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, } //设置内存大小 l.r.ParseMultipartForm(32 << 20) + //获取上传的文件组 files := l.r.MultipartForm.File["file"] @@ -117,6 +118,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, Metadata: info.Metadata, FileData: ioData, ApiType: req.ApiType, + Bucket: uploadBucket, } } }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { @@ -135,7 +137,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, // 创建S3对象存储请求 s3req, _ = svc.PutObjectRequest( &s3.PutObjectInput{ - Bucket: &uploadBucket, + Bucket: &uploadDataInfo.Bucket, Key: &uploadDataInfo.FileKey, }, ) @@ -211,9 +213,11 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, type uploadData struct { ApiType int64 `json:"api_type"` + FileSize int64 `json:"file_size"` FileType string `json:"file_type"` FileKey string `json:"file_key"` Metadata string `json:"metadata"` + Bucket string `json:"bucket"` FileData []byte `fsfile:"data"` } diff --git a/server/upload/internal/logic/uploadfilesfrontendlogic.go b/server/upload/internal/logic/uploadfilesfrontendlogic.go index c086f8e7..1edabc89 100644 --- a/server/upload/internal/logic/uploadfilesfrontendlogic.go +++ b/server/upload/internal/logic/uploadfilesfrontendlogic.go @@ -3,13 +3,17 @@ package logic import ( "fusenapi/utils/auth" "fusenapi/utils/basic" + "time" "context" "fusenapi/server/upload/internal/svc" "fusenapi/server/upload/internal/types" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/core/mr" ) type UploadFilesFrontendLogic struct { @@ -39,7 +43,103 @@ func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null - // 检查用户是否是旁观者,旁观者没有文件上传权限 + // 定义用户ID和S3键名格式 + // var userId int64 + // var guestId int64 - return resp.SetStatus(basic.CodeOK) + // 检查用户是否是游客 + // if userinfo.IsGuest() { + // // 如果是,使用游客ID和游客键名格式 + // guestId = userinfo.GuestId + // } else { + // // 否则,使用用户ID和用户键名格式 + // userId = userinfo.UserId + // } + + var aa = make([]types.UploadInfo, 2) + aa[0].FileKeys = "202308011632" + aa[1].FileKeys = "202308011633" + req.UploadInfo = aa + var fileLen = len(req.UploadInfo) + + if fileLen == 0 { + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,no files") + } + if req.ApiType == 1 && fileLen > 100 { + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err, files count is beyond the maximum") + } + + var uploadBucket = req.UploadBucket + + // 设置AWS会话的区域 + l.svcCtx.AwsSession.Config.Region = aws.String("us-west-1") + + // 创建新的S3服务实例 + svc := s3.New(l.svcCtx.AwsSession) + + result, err := mr.MapReduce(func(source chan<- interface{}) { + for _, info := range req.UploadInfo { + if info.FileSize <= 1024*1024*500 { + // 一系列业务逻辑....验证类型,文件大小 + var fileKey string = info.FileKeys + source <- uploadData{ + FileKey: fileKey, + FileSize: info.FileSize, + Bucket: uploadBucket, + } + } + } + }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { + var uploadUrl = uploadUrl{} + uploadDataInfo := item.(uploadData) + + s3req, _ := svc.PutObjectRequest( + &s3.PutObjectInput{ + Bucket: &uploadBucket, + Key: &uploadDataInfo.FileKey, + ContentLength: aws.Int64(uploadDataInfo.FileSize), + }, + ) + + url, err := s3req.Presign(time.Minute * 5) + if err != nil { + logx.Error(err) + uploadUrl.Status = 0 + uploadUrl.Url = "" + uploadUrl.Key = uploadDataInfo.FileKey + } else { + // 打印请求URL + logx.Info(url) + uploadUrl.Status = 1 + uploadUrl.Url = url + uploadUrl.Key = uploadDataInfo.FileKey + } + // Notice 这个必须加! + writer.Write(uploadUrl) + }, func(pipe <-chan interface{}, writer mr.Writer[interface{}], cancel func(error)) { + var uploadUrlList = make(map[string][]*uploadUrl) + var uploadUrlListFail []*uploadUrl + var uploadUrlListSuccess []*uploadUrl + for p := range pipe { + var uploadUrl = p.(uploadUrl) + if uploadUrl.Status == 1 { + uploadUrlListSuccess = append(uploadUrlListSuccess, &uploadUrl) + } else { + uploadUrlListFail = append(uploadUrlListFail, &uploadUrl) + } + } + + // Notice 这个必须加! + uploadUrlList["success"] = uploadUrlListSuccess + uploadUrlList["fail"] = uploadUrlListFail + writer.Write(uploadUrlList) + }) + if err != nil { + logx.Error(err) + } + + // 返回成功的响应和上传URL + return resp.SetStatus(basic.CodeOK, map[string]interface{}{ + "upload_urls": result, + }) } diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index a684b1c0..5f8d2aa6 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -6,6 +6,7 @@ import ( ) type UploadInfo struct { + FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 Metadata string `form:"file_keys,optional"` // 上传文件额外信息 } diff --git a/server_api/upload.api b/server_api/upload.api index 52dcb143..b10ae1b7 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -37,6 +37,7 @@ service upload { type ( UploadInfo { + FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 Metadata string `form:"file_keys,optional"` // 上传文件额外信息 } From dab532044417a188b97c8b330e12353a956e6032 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Wed, 2 Aug 2023 10:08:14 +0800 Subject: [PATCH 09/60] fix --- server/product/internal/logic/gettagproductlistlogic.go | 1 - server/product/internal/types/types.go | 1 - server_api/product.api | 1 - 3 files changed, 3 deletions(-) diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index bd17aa12..7badfd95 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -222,7 +222,6 @@ func (l *GetTagProductListLogic) dealWithTagMenuData(req dealWithTagMenuDataReq) tagTem := types.TagItem{ TagProductList: []interface{}{}, TypeName: *tagInfo.Title, - Description: *tagInfo.Description, TypeId: tagInfo.Id, Icon: *tagInfo.Icon, Sort: *tagInfo.Sort, diff --git a/server/product/internal/types/types.go b/server/product/internal/types/types.go index d374460a..f2d27f0a 100644 --- a/server/product/internal/types/types.go +++ b/server/product/internal/types/types.go @@ -259,7 +259,6 @@ type GetTagProductListRsp struct { type TagItem struct { TypeName string `json:"type_name"` - Description string `json:"description"` TypeId int64 `json:"type_id"` Icon string `json:"icon"` Sort int64 `json:"sort"` diff --git a/server_api/product.api b/server_api/product.api index 03fb29b6..48ac5a50 100644 --- a/server_api/product.api +++ b/server_api/product.api @@ -309,7 +309,6 @@ type GetTagProductListRsp { } type TagItem { TypeName string `json:"type_name"` - Description string `json:"description"` TypeId int64 `json:"type_id"` Icon string `json:"icon"` Sort int64 `json:"sort"` From d75bc8f2befc96f8dd87490db3808d3afa164e2c Mon Sep 17 00:00:00 2001 From: Hiven Date: Wed, 2 Aug 2023 11:13:28 +0800 Subject: [PATCH 10/60] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/logic/uploadfilesbackendlogic.go | 89 ++++++++++++------- .../logic/uploadfilesfrontendlogic.go | 78 ++++++++++------ server/upload/internal/types/types.go | 8 +- server_api/upload.api | 8 +- utils/hash/hash.go | 70 +++++++++++++++ 5 files changed, 186 insertions(+), 67 deletions(-) create mode 100644 utils/hash/hash.go diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index 95b0bc86..bddf0cf2 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -1,9 +1,12 @@ package logic import ( + "encoding/json" + "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/hash" "io" "net/http" "time" @@ -54,6 +57,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, } // 定义用户ID和S3键名格式 + var uid int64 var userId int64 var guestId int64 @@ -61,16 +65,21 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, if userinfo.IsGuest() { // 如果是,使用游客ID和游客键名格式 guestId = userinfo.GuestId + uid = guestId } else { // 否则,使用用户ID和用户键名格式 userId = userinfo.UserId + uid = userId } - var aa = make([]types.UploadInfo, 2) - aa[0].FileKeys = "202308011632" - aa[1].FileKeys = "202308011633" - req.UploadInfo = aa - var fileLen = len(req.UploadInfo) + var uploadInfoList []UploadInfo + err := json.Unmarshal([]byte(req.UploadInfo), &uploadInfoList) + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,params Unmarshal failed") + } + + var fileLen = len(uploadInfoList) if fileLen == 0 { return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,no files") @@ -78,6 +87,18 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, if req.ApiType == 1 && fileLen > 100 { return resp.SetStatus(basic.CodeFileUploadErr, "file upload err, files count is beyond the maximum") } + + // 定义存储桶名称 + var bucketName *string + + // 根据类别选择存储桶 + switch req.UploadBucket { + case 2: + bucketName = basic.TempfileBucketName + default: + bucketName = basic.StorageBucketName + } + //设置内存大小 l.r.ParseMultipartForm(32 << 20) @@ -93,10 +114,9 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, // 定义S3请求和当前时间 var s3req *request.Request - var uploadBucket = req.UploadBucket resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) result, err := mr.MapReduce(func(source chan<- interface{}) { - for i, info := range req.UploadInfo { + for i, info := range uploadInfoList { fileType := files[i].Header.Get("Content-Type") // 打开文件 file, err := files[i].Open() @@ -111,34 +131,36 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, } // 一系列业务逻辑....验证类型,文件大小 - var fileKey string = info.FileKeys - source <- uploadData{ - FileKey: fileKey, + + var hashKey string = hash.JsonHashKey(fmt.Sprintf("%s%d", info.FileKeys, uid)) + source <- UploadData{ + FileKey: info.FileKeys, FileType: fileType, Metadata: info.Metadata, FileData: ioData, ApiType: req.ApiType, - Bucket: uploadBucket, + Bucket: bucketName, + HashKey: hashKey, } } }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { - var uploadUrl = uploadUrl{} - uploadDataInfo := item.(uploadData) + var uploadUrl = UploadUrl{} + uploadDataInfo := item.(UploadData) - var resourceId string = uploadDataInfo.FileKey + var resourceId string = uploadDataInfo.HashKey // 查询数据库 resourceInfo, err := resourceModel.FindOneById(l.ctx, resourceId) if err == nil && resourceInfo.ResourceId != "" { uploadUrl.Status = 1 uploadUrl.ResourceId = resourceId uploadUrl.Url = *resourceInfo.ResourceUrl - uploadUrl.Key = resourceId + uploadUrl.Key = uploadDataInfo.FileKey } else { // 创建S3对象存储请求 s3req, _ = svc.PutObjectRequest( &s3.PutObjectInput{ - Bucket: &uploadDataInfo.Bucket, - Key: &uploadDataInfo.FileKey, + Bucket: uploadDataInfo.Bucket, + Key: &uploadDataInfo.HashKey, }, ) @@ -184,11 +206,11 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, // Notice 这个必须加! writer.Write(uploadUrl) }, func(pipe <-chan interface{}, writer mr.Writer[interface{}], cancel func(error)) { - var uploadUrlList = make(map[string][]*uploadUrl) - var uploadUrlListFail []*uploadUrl - var uploadUrlListSuccess []*uploadUrl + var uploadUrlList = make(map[string][]*UploadUrl) + var uploadUrlListFail []*UploadUrl + var uploadUrlListSuccess []*UploadUrl for p := range pipe { - var uploadUrl = p.(uploadUrl) + var uploadUrl = p.(UploadUrl) if uploadUrl.Status == 1 { uploadUrlListSuccess = append(uploadUrlListSuccess, &uploadUrl) } else { @@ -211,17 +233,24 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, }) } -type uploadData struct { - ApiType int64 `json:"api_type"` - FileSize int64 `json:"file_size"` - FileType string `json:"file_type"` - FileKey string `json:"file_key"` - Metadata string `json:"metadata"` - Bucket string `json:"bucket"` - FileData []byte `fsfile:"data"` +type UploadInfo struct { + FileSize int64 `json:"file_size"` // 上传唯一标识信息 + FileKeys string `json:"file_keys"` // 上传唯一标识信息 + Metadata string `json:"meta_data"` // 上传文件额外信息 } -type uploadUrl struct { +type UploadData struct { + ApiType int64 `json:"api_type"` + FileSize int64 `json:"file_size"` + FileType string `json:"file_type"` + FileKey string `json:"file_key"` + Metadata string `json:"metadata"` + Bucket *string `json:"bucket"` + HashKey string `json:"hash_key"` + FileData []byte `fsfile:"data"` +} + +type UploadUrl struct { Status int64 `json:"status"` ResourceId string `json:"resource_id"` Url string `json:"url"` diff --git a/server/upload/internal/logic/uploadfilesfrontendlogic.go b/server/upload/internal/logic/uploadfilesfrontendlogic.go index 1edabc89..b0910736 100644 --- a/server/upload/internal/logic/uploadfilesfrontendlogic.go +++ b/server/upload/internal/logic/uploadfilesfrontendlogic.go @@ -1,8 +1,11 @@ package logic import ( + "encoding/json" + "fmt" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/hash" "time" "context" @@ -42,25 +45,30 @@ func NewUploadFilesFrontendLogic(ctx context.Context, svcCtx *svc.ServiceContext func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null - // 定义用户ID和S3键名格式 - // var userId int64 - // var guestId int64 + var uid int64 + var userId int64 + var guestId int64 // 检查用户是否是游客 - // if userinfo.IsGuest() { - // // 如果是,使用游客ID和游客键名格式 - // guestId = userinfo.GuestId - // } else { - // // 否则,使用用户ID和用户键名格式 - // userId = userinfo.UserId - // } + if userinfo.IsGuest() { + // 如果是,使用游客ID和游客键名格式 + guestId = userinfo.GuestId + uid = guestId + } else { + // 否则,使用用户ID和用户键名格式 + userId = userinfo.UserId + uid = userId + } - var aa = make([]types.UploadInfo, 2) - aa[0].FileKeys = "202308011632" - aa[1].FileKeys = "202308011633" - req.UploadInfo = aa - var fileLen = len(req.UploadInfo) + var uploadInfoList []UploadInfo + err := json.Unmarshal([]byte(req.UploadInfo), &uploadInfoList) + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,params Unmarshal failed") + } + + var fileLen = len(uploadInfoList) if fileLen == 0 { return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,no files") @@ -69,7 +77,16 @@ func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq return resp.SetStatus(basic.CodeFileUploadErr, "file upload err, files count is beyond the maximum") } - var uploadBucket = req.UploadBucket + // 定义存储桶名称 + var bucketName *string + + // 根据类别选择存储桶 + switch req.UploadBucket { + case 2: + bucketName = basic.TempfileBucketName + default: + bucketName = basic.StorageBucketName + } // 设置AWS会话的区域 l.svcCtx.AwsSession.Config.Region = aws.String("us-west-1") @@ -78,25 +95,26 @@ func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq svc := s3.New(l.svcCtx.AwsSession) result, err := mr.MapReduce(func(source chan<- interface{}) { - for _, info := range req.UploadInfo { + for _, info := range uploadInfoList { if info.FileSize <= 1024*1024*500 { // 一系列业务逻辑....验证类型,文件大小 - var fileKey string = info.FileKeys - source <- uploadData{ - FileKey: fileKey, + var hashKey string = hash.JsonHashKey(fmt.Sprintf("%s%d", info.FileKeys, uid)) + source <- UploadData{ + FileKey: info.FileKeys, FileSize: info.FileSize, - Bucket: uploadBucket, + Bucket: bucketName, + HashKey: hashKey, } } } }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { - var uploadUrl = uploadUrl{} - uploadDataInfo := item.(uploadData) + var uploadUrl = UploadUrl{} + uploadDataInfo := item.(UploadData) s3req, _ := svc.PutObjectRequest( &s3.PutObjectInput{ - Bucket: &uploadBucket, - Key: &uploadDataInfo.FileKey, + Bucket: uploadDataInfo.Bucket, + Key: &uploadDataInfo.HashKey, ContentLength: aws.Int64(uploadDataInfo.FileSize), }, ) @@ -106,22 +124,24 @@ func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq logx.Error(err) uploadUrl.Status = 0 uploadUrl.Url = "" + uploadUrl.ResourceId = uploadDataInfo.HashKey uploadUrl.Key = uploadDataInfo.FileKey } else { // 打印请求URL logx.Info(url) uploadUrl.Status = 1 uploadUrl.Url = url + uploadUrl.ResourceId = uploadDataInfo.HashKey uploadUrl.Key = uploadDataInfo.FileKey } // Notice 这个必须加! writer.Write(uploadUrl) }, func(pipe <-chan interface{}, writer mr.Writer[interface{}], cancel func(error)) { - var uploadUrlList = make(map[string][]*uploadUrl) - var uploadUrlListFail []*uploadUrl - var uploadUrlListSuccess []*uploadUrl + var uploadUrlList = make(map[string][]*UploadUrl) + var uploadUrlListFail []*UploadUrl + var uploadUrlListSuccess []*UploadUrl for p := range pipe { - var uploadUrl = p.(uploadUrl) + var uploadUrl = p.(UploadUrl) if uploadUrl.Status == 1 { uploadUrlListSuccess = append(uploadUrlListSuccess, &uploadUrl) } else { diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index 5f8d2aa6..5a7a1a3f 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -8,13 +8,13 @@ import ( type UploadInfo struct { FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 - Metadata string `form:"file_keys,optional"` // 上传文件额外信息 + Metadata string `form:"meta_data,optional"` // 上传文件额外信息 } type UploadFilesReq struct { - ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 - UploadBucket string `form:"upload_bucket"` // 上传桶名 - UploadInfo []UploadInfo `form:"upload_info,optional"` // 上传信息 + 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 } type UploadCallbackReq struct { diff --git a/server_api/upload.api b/server_api/upload.api index b10ae1b7..eca41ebf 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -39,13 +39,13 @@ type ( UploadInfo { FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 - Metadata string `form:"file_keys,optional"` // 上传文件额外信息 + Metadata string `form:"meta_data,optional"` // 上传文件额外信息 } UploadFilesReq { - ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 - UploadBucket string `form:"upload_bucket"` // 上传桶名 - UploadInfo []UploadInfo `form:"upload_info,optional"` // 上传信息 + 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 } UploadCallbackReq { FileType string `form:"file_type"` // 文件类型 / fbx / hdr diff --git a/utils/hash/hash.go b/utils/hash/hash.go new file mode 100644 index 00000000..37ea1c00 --- /dev/null +++ b/utils/hash/hash.go @@ -0,0 +1,70 @@ +package hash + +import ( + "bytes" + "crypto/sha256" + "encoding/json" + "fmt" + "sort" +) + +func JsonHashKey(v interface{}) string { + h := sha256.New() + h.Write(marshalOrdered(v)) + return fmt.Sprintf("%x", h.Sum(nil)) +} + +func marshalOrdered(v interface{}) []byte { + switch v := v.(type) { + case map[string]interface{}: + sortedKeys := make([]string, 0, len(v)) + for key := range v { + sortedKeys = append(sortedKeys, key) + } + sort.Strings(sortedKeys) + + var buf bytes.Buffer + buf.WriteByte('{') + for i, key := range sortedKeys { + if i > 0 { + buf.WriteByte(',') + } + b, err := json.Marshal(key) + if err != nil { + panic(err) + } + buf.Write(b) + buf.WriteByte(':') + + b = marshalOrdered(v[key]) + buf.Write(b) + } + buf.WriteByte('}') + return buf.Bytes() + + case []interface{}: + var buf bytes.Buffer + + sort.Slice(v, func(i, j int) bool { + return bytes.Compare(marshalOrdered(v[i]), marshalOrdered(v[j])) == 1 + }) + buf.WriteByte('[') + for i, val := range v { + if i > 0 { + buf.WriteByte(',') + } + + b := marshalOrdered(val) + buf.Write(b) + } + buf.WriteByte(']') + return buf.Bytes() + + default: + b, err := json.Marshal(v) + if err != nil { + panic(err) + } + return b + } +} From 3388b446fd85392fbb2317aa0061bbca9a56d991 Mon Sep 17 00:00:00 2001 From: Hiven Date: Wed, 2 Aug 2023 11:30:27 +0800 Subject: [PATCH 11/60] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/logic/uploadfilesbackendlogic.go | 26 +++++++++---------- .../logic/uploadfilesfrontendlogic.go | 12 ++++----- server/upload/internal/types/types.go | 10 +++---- server_api/upload.api | 10 +++---- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index bddf0cf2..e37c9ec8 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -144,17 +144,20 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, } } }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { - var uploadUrl = UploadUrl{} uploadDataInfo := item.(UploadData) + var uploadUrl = UploadUrl{} + uploadUrl.Key = uploadDataInfo.FileKey + uploadUrl.ApiType = uploadDataInfo.ApiType + uploadUrl.ResourceType = uploadDataInfo.FileType + var resourceId string = uploadDataInfo.HashKey // 查询数据库 resourceInfo, err := resourceModel.FindOneById(l.ctx, resourceId) if err == nil && resourceInfo.ResourceId != "" { uploadUrl.Status = 1 uploadUrl.ResourceId = resourceId - uploadUrl.Url = *resourceInfo.ResourceUrl - uploadUrl.Key = uploadDataInfo.FileKey + uploadUrl.ResourceUrl = *resourceInfo.ResourceUrl } else { // 创建S3对象存储请求 s3req, _ = svc.PutObjectRequest( @@ -169,21 +172,17 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, // 发送请求 err = s3req.Send() - // 检查是否有错误 if err != nil { logx.Error(err) uploadUrl.Status = 0 - uploadUrl.Url = "" - uploadUrl.Key = uploadDataInfo.FileKey } else { var url = s3req.HTTPRequest.URL.String() // 打印请求URL logx.Info(url) uploadUrl.Status = 1 - uploadUrl.Url = url - uploadUrl.Key = uploadDataInfo.FileKey uploadUrl.ResourceId = resourceId + uploadUrl.ResourceUrl = url var version string = "0.0.1" var nowTime = time.Now() _, err = resourceModel.CreateOrUpdate(l.ctx, &gmodel.FsResource{ @@ -251,9 +250,10 @@ type UploadData struct { } type UploadUrl struct { - Status int64 `json:"status"` - ResourceId string `json:"resource_id"` - Url string `json:"url"` - Key string `json:"key"` - Metadata string `json:"metadata"` + Key string `json:"key"` + Status int64 `json:"status"` + ApiType int64 `json:"api_type"` + ResourceId string `json:"resource_id"` + ResourceType string `json:"resource_type"` + ResourceUrl string `json:"resource_url"` } diff --git a/server/upload/internal/logic/uploadfilesfrontendlogic.go b/server/upload/internal/logic/uploadfilesfrontendlogic.go index b0910736..6ca20550 100644 --- a/server/upload/internal/logic/uploadfilesfrontendlogic.go +++ b/server/upload/internal/logic/uploadfilesfrontendlogic.go @@ -108,9 +108,13 @@ func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq } } }, func(item interface{}, writer mr.Writer[interface{}], cancel func(error)) { - var uploadUrl = UploadUrl{} uploadDataInfo := item.(UploadData) + var uploadUrl = UploadUrl{} + uploadUrl.Key = uploadDataInfo.FileKey + uploadUrl.ApiType = uploadDataInfo.ApiType + uploadUrl.ResourceType = uploadDataInfo.FileType + s3req, _ := svc.PutObjectRequest( &s3.PutObjectInput{ Bucket: uploadDataInfo.Bucket, @@ -123,16 +127,12 @@ func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq if err != nil { logx.Error(err) uploadUrl.Status = 0 - uploadUrl.Url = "" - uploadUrl.ResourceId = uploadDataInfo.HashKey - uploadUrl.Key = uploadDataInfo.FileKey } else { // 打印请求URL logx.Info(url) uploadUrl.Status = 1 - uploadUrl.Url = url + uploadUrl.ResourceUrl = url uploadUrl.ResourceId = uploadDataInfo.HashKey - uploadUrl.Key = uploadDataInfo.FileKey } // Notice 这个必须加! writer.Write(uploadUrl) diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index 5a7a1a3f..f09a9e44 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -18,11 +18,11 @@ type UploadFilesReq struct { } type UploadCallbackReq struct { - FileType string `form:"file_type"` // 文件类型 / fbx / hdr - UploadKey string `form:"upload_key"` // 上传KEY - UploadBucket string `form:"upload_bucket"` // 上传桶名 - Version string `form:"version,optional"` // 版本信息 - Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 + ResourceId string `form:"resource_id"` // 资源ID + ResourceType string `form:"resource_type"` // 资源类型 + ResourceUrl string `form:"resource_url"` // 资源URL + Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 } type RequestUpFile struct { diff --git a/server_api/upload.api b/server_api/upload.api index eca41ebf..de42df59 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -48,11 +48,11 @@ type ( UploadInfo string `form:"upload_info"` // 上传信息 json } UploadCallbackReq { - FileType string `form:"file_type"` // 文件类型 / fbx / hdr - UploadKey string `form:"upload_key"` // 上传KEY - UploadBucket string `form:"upload_bucket"` // 上传桶名 - Version string `form:"version,optional"` // 版本信息 - Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 + ResourceId string `form:"resource_id"` // 资源ID + ResourceType string `form:"resource_type"` // 资源类型 + ResourceUrl string `form:"resource_url"` // 资源URL + Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 } ) From c08c1e7eba21f08f3858e9c859f9948c23b1ef13 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Wed, 2 Aug 2023 11:42:03 +0800 Subject: [PATCH 12/60] fix --- initalize/rabbitmq.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/initalize/rabbitmq.go b/initalize/rabbitmq.go index fc92d496..040a3a00 100644 --- a/initalize/rabbitmq.go +++ b/initalize/rabbitmq.go @@ -7,6 +7,7 @@ import ( "github.com/streadway/amqp" "github.com/zeromicro/go-zero/core/logx" "log" + "sync" ) type RabbitMqHandle struct { @@ -100,16 +101,19 @@ func (h *RabbitMqHandle) Consume(queueName constants.RABBIT_MQ, handleFunc func( } //允许20的并发 limit := make(chan struct{}, 20) + wait := sync.WaitGroup{} defer close(limit) // 消费消息 for msg := range msgs { limit <- struct{}{} + wait.Add(1) go func(m amqp.Delivery) { if err := recover(); err != nil { logx.Error(err) } defer func() { <-limit + wait.Done() }() if err = handleFunc(m.Body); err != nil { logx.Error("failed to deal with MQ message:", string(m.Body)) @@ -122,5 +126,6 @@ func (h *RabbitMqHandle) Consume(queueName constants.RABBIT_MQ, handleFunc func( } }(msg) } + wait.Wait() return nil } From 9363ca68b668fdf505a7e526ee44138133a8dfd2 Mon Sep 17 00:00:00 2001 From: Hiven Date: Wed, 2 Aug 2023 11:50:16 +0800 Subject: [PATCH 13/60] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_resource_logic.go | 14 +++++----- .../internal/logic/uploadcallbacklogic.go | 28 +++++++++++++++++++ .../internal/logic/uploadfilesbackendlogic.go | 2 +- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/model/gmodel/fs_resource_logic.go b/model/gmodel/fs_resource_logic.go index 814257c5..e72f5ae3 100644 --- a/model/gmodel/fs_resource_logic.go +++ b/model/gmodel/fs_resource_logic.go @@ -22,13 +22,13 @@ func (p *FsResourceModel) FindOneById(ctx context.Context, resourceId string) (* return &resp, nil } -func (p *FsResourceModel) CreateOrUpdate(ctx context.Context, req *FsResource) (resp *FsResource, err error) { - rowBuilder := p.db.Table(p.name).WithContext(ctx) - if req.ResourceId != "" { - err = rowBuilder.Save(req).Error - } else { - err = rowBuilder.Create(req).Error - } +func (p *FsResourceModel) Create(ctx context.Context, req *FsResource) (resp *FsResource, err error) { + err = p.db.Table(p.name).WithContext(ctx).Create(req).Error + return req, err +} + +func (p *FsResourceModel) Update(ctx context.Context, req *FsResource) (resp *FsResource, err error) { + err = p.db.Table(p.name).WithContext(ctx).Where("resource_id =?", req.ResourceId).Save(req).Error return req, err } diff --git a/server/upload/internal/logic/uploadcallbacklogic.go b/server/upload/internal/logic/uploadcallbacklogic.go index 1f9147d5..7c15d85f 100644 --- a/server/upload/internal/logic/uploadcallbacklogic.go +++ b/server/upload/internal/logic/uploadcallbacklogic.go @@ -1,6 +1,7 @@ package logic import ( + "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -10,6 +11,7 @@ import ( "fusenapi/server/upload/internal/types" "github.com/zeromicro/go-zero/core/logx" + "gorm.io/gorm" ) type UploadCallbackLogic struct { @@ -38,5 +40,31 @@ func NewUploadCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Up func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null + + resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) + err := resourceModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { + resourceModelTS := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) + resourceInfo, err := resourceModelTS.FindOneById(ctx, req.ResourceId) + if err != nil { + return err + } + + var fsResource = &gmodel.FsResource{} + fsResource.ResourceId = req.ResourceId + fsResource.ResourceType = &req.ResourceType + fsResource.ResourceUrl = &req.ResourceUrl + fsResource.Metadata = &req.Metadata + fsResource.ApiType = &req.ApiType + if resourceInfo.ResourceId == "" { + _, err = resourceModelTS.Create(ctx, fsResource) + } else { + _, err = resourceModelTS.Update(ctx, fsResource) + } + return err + }) + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,UploadCallback failed") + } return resp.SetStatus(basic.CodeOK) } diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index e37c9ec8..74a7ba00 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -185,7 +185,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, uploadUrl.ResourceUrl = url var version string = "0.0.1" var nowTime = time.Now() - _, err = resourceModel.CreateOrUpdate(l.ctx, &gmodel.FsResource{ + _, err = resourceModel.Create(l.ctx, &gmodel.FsResource{ ResourceId: resourceId, UserId: &userId, GuestId: &guestId, From 4aaa5c169d1ab14e5c9c5f53a2d9fc282a04ea18 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Wed, 2 Aug 2023 15:06:04 +0800 Subject: [PATCH 14/60] fix --- model/gmodel/fs_tags_gen.go | 1 + model/gmodel/fs_tags_logic.go | 4 ++++ model/gmodel/fs_user_material_gen.go | 24 +++++++++++++++++++ model/gmodel/fs_user_material_logic.go | 2 ++ model/gmodel/var_gen.go | 2 ++ .../internal/logic/gettagproductlistlogic.go | 4 ++++ 6 files changed, 37 insertions(+) create mode 100644 model/gmodel/fs_user_material_gen.go create mode 100644 model/gmodel/fs_user_material_logic.go diff --git a/model/gmodel/fs_tags_gen.go b/model/gmodel/fs_tags_gen.go index 13bc3800..00878da7 100644 --- a/model/gmodel/fs_tags_gen.go +++ b/model/gmodel/fs_tags_gen.go @@ -18,6 +18,7 @@ type FsTags struct { Description *string `gorm:"default:'';" json:"description"` // 介绍 Seo RecommendProduct *string `gorm:"default:'';" json:"recommend_product"` // RecommendProductSort *string `gorm:"default:'';" json:"recommend_product_sort"` // + Categroy *int64 `gorm:"default:1;" json:"categroy"` // 分类:1前台用的 2后台用的 } type FsTagsModel struct { db *gorm.DB diff --git a/model/gmodel/fs_tags_logic.go b/model/gmodel/fs_tags_logic.go index 75028f93..35efa42c 100755 --- a/model/gmodel/fs_tags_logic.go +++ b/model/gmodel/fs_tags_logic.go @@ -36,6 +36,7 @@ type GetAllTagByParamsReq struct { OrderBy string LevelPrefixLeftLike string //右模糊 WithChild bool //是否包含子层级 + Category int64 } func (t *FsTagsModel) GetAllTagByParams(ctx context.Context, req GetAllTagByParamsReq) (resp []FsTags, err error) { @@ -46,6 +47,9 @@ func (t *FsTagsModel) GetAllTagByParams(ctx context.Context, req GetAllTagByPara if req.Status != nil { db = db.Where("`status` = ?", *req.Status) } + if req.Category != 0 { + db = db.Where("`category` = ?", req.Category) + } if req.LevelPrefixLeftLike != "" { //查询子集 if req.WithChild { diff --git a/model/gmodel/fs_user_material_gen.go b/model/gmodel/fs_user_material_gen.go new file mode 100644 index 00000000..4de4076d --- /dev/null +++ b/model/gmodel/fs_user_material_gen.go @@ -0,0 +1,24 @@ +package gmodel + +import ( + "gorm.io/gorm" +) + +// fs_user_material 用户素材表 +type FsUserMaterial struct { + Id int64 `gorm:"primary_key;default:0;" json:"id"` // 用户 ID + Module *string `gorm:"default:'';" json:"module"` // 所属模块 + UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户 ID + ResourceId *string `gorm:"default:'';" json:"resource_id"` // 资源ID + ResourceUrl *string `gorm:"default:'';" json:"resource_url"` // 资源 URL + Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 + CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 上传时间 +} +type FsUserMaterialModel struct { + db *gorm.DB + name string +} + +func NewFsUserMaterialModel(db *gorm.DB) *FsUserMaterialModel { + return &FsUserMaterialModel{db: db, name: "fs_user_material"} +} diff --git a/model/gmodel/fs_user_material_logic.go b/model/gmodel/fs_user_material_logic.go new file mode 100644 index 00000000..e68225aa --- /dev/null +++ b/model/gmodel/fs_user_material_logic.go @@ -0,0 +1,2 @@ +package gmodel +// TODO: 使用model的属性做你想做的 \ No newline at end of file diff --git a/model/gmodel/var_gen.go b/model/gmodel/var_gen.go index a90a6f7c..c2139293 100644 --- a/model/gmodel/var_gen.go +++ b/model/gmodel/var_gen.go @@ -90,6 +90,7 @@ type AllModelsGen struct { FsTrade *FsTradeModel // fs_trade FsUser *FsUserModel // fs_user 用户表 FsUserDesign *FsUserDesignModel // fs_user_design 废弃表 + FsUserMaterial *FsUserMaterialModel // fs_user_material 用户素材表 FsUserStock *FsUserStockModel // fs_user_stock 用户云仓库存 FsWebSet *FsWebSetModel // fs_web_set 网站配置表 @@ -183,6 +184,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen { FsTrade: NewFsTradeModel(gdb), FsUser: NewFsUserModel(gdb), FsUserDesign: NewFsUserDesignModel(gdb), + FsUserMaterial: NewFsUserMaterialModel(gdb), FsUserStock: NewFsUserStockModel(gdb), FsWebSet: NewFsWebSetModel(gdb), } diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index 7badfd95..ca726814 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -50,6 +50,7 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR Status: &tStatus, OrderBy: "`sort` DESC", WithChild: true, //需要子集 + Category: 1, //前台网站用的 } //传入分类id if req.Cid > 0 { @@ -62,6 +63,9 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get tag info") } + if *tagData.Categroy != 1 { + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "invalid tag") + } tReq.LevelPrefixLeftLike = *tagData.LevelPrefix } tagList, err := l.svcCtx.AllModels.FsTags.GetAllTagByParams(l.ctx, tReq) From 786fc59b0d64a71e5a7d947c427a51e634ea7fa7 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Wed, 2 Aug 2023 15:10:16 +0800 Subject: [PATCH 15/60] fixz --- model/gmodel/fs_tags_gen.go | 2 +- server/product/internal/logic/gettagproductlistlogic.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/model/gmodel/fs_tags_gen.go b/model/gmodel/fs_tags_gen.go index 00878da7..5f27544b 100644 --- a/model/gmodel/fs_tags_gen.go +++ b/model/gmodel/fs_tags_gen.go @@ -18,7 +18,7 @@ type FsTags struct { Description *string `gorm:"default:'';" json:"description"` // 介绍 Seo RecommendProduct *string `gorm:"default:'';" json:"recommend_product"` // RecommendProductSort *string `gorm:"default:'';" json:"recommend_product_sort"` // - Categroy *int64 `gorm:"default:1;" json:"categroy"` // 分类:1前台用的 2后台用的 + Category *int64 `gorm:"default:1;" json:"category"` // 分类:1前台用的 2后台用的 } type FsTagsModel struct { db *gorm.DB diff --git a/server/product/internal/logic/gettagproductlistlogic.go b/server/product/internal/logic/gettagproductlistlogic.go index ca726814..42e240e1 100644 --- a/server/product/internal/logic/gettagproductlistlogic.go +++ b/server/product/internal/logic/gettagproductlistlogic.go @@ -63,7 +63,7 @@ func (l *GetTagProductListLogic) GetTagProductList(req *types.GetTagProductListR logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get tag info") } - if *tagData.Categroy != 1 { + if *tagData.Category != 1 { return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "invalid tag") } tReq.LevelPrefixLeftLike = *tagData.LevelPrefix From d06241b2678e1bad6825341e180a88328a51ce1e Mon Sep 17 00:00:00 2001 From: Hiven Date: Wed, 2 Aug 2023 18:14:53 +0800 Subject: [PATCH 16/60] =?UTF-8?q?=E4=B8=8A=E4=BC=A0logo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_user_material_gen.go | 24 ++++ model/gmodel/fs_user_material_logic.go | 15 ++ model/gmodel/var_gen.go | 2 + server/upload/etc/upload.yaml | 5 +- server/upload/internal/config/config.go | 5 + server/upload/internal/handler/routes.go | 5 + .../internal/handler/uploadlogohandler.go | 35 +++++ .../upload/internal/logic/uploadlogologic.go | 134 ++++++++++++++++++ server/upload/internal/types/types.go | 8 ++ server_api/upload.api | 15 ++ utils/basic/basic.go | 3 +- 11 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 model/gmodel/fs_user_material_gen.go create mode 100644 model/gmodel/fs_user_material_logic.go create mode 100644 server/upload/internal/handler/uploadlogohandler.go create mode 100644 server/upload/internal/logic/uploadlogologic.go diff --git a/model/gmodel/fs_user_material_gen.go b/model/gmodel/fs_user_material_gen.go new file mode 100644 index 00000000..4de4076d --- /dev/null +++ b/model/gmodel/fs_user_material_gen.go @@ -0,0 +1,24 @@ +package gmodel + +import ( + "gorm.io/gorm" +) + +// fs_user_material 用户素材表 +type FsUserMaterial struct { + Id int64 `gorm:"primary_key;default:0;" json:"id"` // 用户 ID + Module *string `gorm:"default:'';" json:"module"` // 所属模块 + UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户 ID + ResourceId *string `gorm:"default:'';" json:"resource_id"` // 资源ID + ResourceUrl *string `gorm:"default:'';" json:"resource_url"` // 资源 URL + Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 + CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 上传时间 +} +type FsUserMaterialModel struct { + db *gorm.DB + name string +} + +func NewFsUserMaterialModel(db *gorm.DB) *FsUserMaterialModel { + return &FsUserMaterialModel{db: db, name: "fs_user_material"} +} diff --git a/model/gmodel/fs_user_material_logic.go b/model/gmodel/fs_user_material_logic.go new file mode 100644 index 00000000..89dcc405 --- /dev/null +++ b/model/gmodel/fs_user_material_logic.go @@ -0,0 +1,15 @@ +package gmodel + +import "context" + +// TODO: 使用model的属性做你想做的 + +func (p *FsUserMaterialModel) CreateOrUpdate(ctx context.Context, req *FsUserMaterial) (resp *FsUserMaterial, err error) { + rowBuilder := p.db.Table(p.name).WithContext(ctx) + if req.Id > 0 { + err = rowBuilder.Save(req).Error + } else { + err = rowBuilder.Create(req).Error + } + return req, err +} diff --git a/model/gmodel/var_gen.go b/model/gmodel/var_gen.go index a90a6f7c..c2139293 100644 --- a/model/gmodel/var_gen.go +++ b/model/gmodel/var_gen.go @@ -90,6 +90,7 @@ type AllModelsGen struct { FsTrade *FsTradeModel // fs_trade FsUser *FsUserModel // fs_user 用户表 FsUserDesign *FsUserDesignModel // fs_user_design 废弃表 + FsUserMaterial *FsUserMaterialModel // fs_user_material 用户素材表 FsUserStock *FsUserStockModel // fs_user_stock 用户云仓库存 FsWebSet *FsWebSetModel // fs_web_set 网站配置表 @@ -183,6 +184,7 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen { FsTrade: NewFsTradeModel(gdb), FsUser: NewFsUserModel(gdb), FsUserDesign: NewFsUserDesignModel(gdb), + FsUserMaterial: NewFsUserMaterialModel(gdb), FsUserStock: NewFsUserStockModel(gdb), FsWebSet: NewFsWebSetModel(gdb), } diff --git a/server/upload/etc/upload.yaml b/server/upload/etc/upload.yaml index 8481514f..e9c285fd 100644 --- a/server/upload/etc/upload.yaml +++ b/server/upload/etc/upload.yaml @@ -12,4 +12,7 @@ AWS: Credentials: AccessKeyID: AKIAZB2JKUXDPNRP4YT2 Secret: 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 - Token: \ No newline at end of file + Token: +BLMService: + ImageProcess: + Url: "http://110.41.19.98:8868/removebg" diff --git a/server/upload/internal/config/config.go b/server/upload/internal/config/config.go index a8d273d7..43cc0577 100644 --- a/server/upload/internal/config/config.go +++ b/server/upload/internal/config/config.go @@ -20,4 +20,9 @@ type Config struct { } } } + BLMService struct { + ImageProcess struct { + Url string + } + } } diff --git a/server/upload/internal/handler/routes.go b/server/upload/internal/handler/routes.go index 1417f043..8d5b0aa0 100644 --- a/server/upload/internal/handler/routes.go +++ b/server/upload/internal/handler/routes.go @@ -47,6 +47,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/upload/upload-callback", Handler: UploadCallbackHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/upload/up-logo", + Handler: UploadLogoHandler(serverCtx), + }, }, ) } diff --git a/server/upload/internal/handler/uploadlogohandler.go b/server/upload/internal/handler/uploadlogohandler.go new file mode 100644 index 00000000..52c58424 --- /dev/null +++ b/server/upload/internal/handler/uploadlogohandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/upload/internal/logic" + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" +) + +func UploadLogoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.UploadLogoReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUploadLogoLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UploadLogo(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go new file mode 100644 index 00000000..df4283c9 --- /dev/null +++ b/server/upload/internal/logic/uploadlogologic.go @@ -0,0 +1,134 @@ +package logic + +import ( + "fmt" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "time" + + "context" + + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UploadLogoLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUploadLogoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadLogoLogic { + return &UploadLogoLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *UploadLogoLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UploadLogoLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + if userinfo.IsOnlooker() { + // 如果是,返回未授权的错误码 + return resp.SetStatus(basic.CodeUnAuth) + } + + // 定义用户ID + var uid int64 + + // 检查用户是否是游客 + if userinfo.IsGuest() { + // 如果是,使用游客ID和游客键名格式 + uid = userinfo.GuestId + } else { + // 否则,使用用户ID和用户键名格式 + uid = userinfo.UserId + } + + fmt.Println(uid) + + var logoWidth int64 + var logoHeight int64 + // 查看sku是否存在 + if req.SkuId > 0 { + // 查询出产品模板信息 + productTemplateV2Model := gmodel.NewFsProductTemplateV2Model(l.svcCtx.MysqlConn) + productTemplateV2Info, err := productTemplateV2Model.FindOne(l.ctx, req.SkuId) + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadLogoErr, "logo upload err,no product template") + } + + logoWidth = *productTemplateV2Info.LogoWidth + logoHeight = *productTemplateV2Info.LogoHeight + } + // 设置默认宽高 + if logoWidth == 0 || logoHeight == 0 { + logoWidth = 300 + logoHeight = 200 + } + var resultStr string + + // apiUrl := l.svcCtx.Config.BLMService.ImageProcess.Url + // var onlyScale = true + // data := url.Values{} + // data.Set("imgurl", req.ResourceUrl) + // data.Set("layerwidth", strconv.Itoa(int(logoWidth))) + // data.Set("layerheight", strconv.Itoa(int(logoHeight))) + // data.Set("is_remove_bg", strconv.Itoa(int(req.IsRemoveBg))) + // data.Set("proportion", strconv.Itoa(int(req.Proportion))) + // data.Set("only_scale", fmt.Sprintf("%v", onlyScale)) + + // u, err := url.ParseRequestURI(apiUrl) + // if err != nil { + // logx.Error(err) + // return resp.SetStatus(basic.CodeFileUploadLogoErr, "service fail") + // } + // u.RawQuery = data.Encode() // URL encode + // fmt.Println(u.String()) + // result, err := http.Get(u.String()) + // if err != nil { + // logx.Error(err) + // return resp.SetStatus(basic.CodeFileUploadLogoErr, "service fail") + // } + // defer result.Body.Close() + // b, err := io.ReadAll(result.Body) + // if err != nil { + // logx.Error(err) + // return resp.SetStatus(basic.CodeFileUploadLogoErr, "service fail") + // } + // resultStr = string(b) + + var module = "logo" + var nowTime = time.Now().Unix() + // 新增记录 + userMaterialModel := gmodel.NewFsUserMaterialModel(l.svcCtx.MysqlConn) + _, err := userMaterialModel.CreateOrUpdate(l.ctx, &gmodel.FsUserMaterial{ + Module: &module, + UserId: &uid, + ResourceId: &req.ResourceId, + ResourceUrl: &req.ResourceUrl, + Metadata: &resultStr, + CreateAt: &nowTime, + }) + + if err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadLogoErr, "service fail") + } + + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index f09a9e44..8373d29c 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -5,6 +5,14 @@ import ( "fusenapi/utils/basic" ) +type UploadLogoReq struct { + ResourceId string `form:"resource_id"` // 资源ID + ResourceUrl string `form:"resource_url"` // 资源URL + IsRemoveBg int64 `form:"is_remove_bg"` // 是否要去掉背景 + Proportion int64 `form:"proportion,default=60"` // 贴图在模型面板上的比例 + SkuId int64 `form:"sku_id,default=0"` // 模板ID +} + type UploadInfo struct { FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 FileKeys string `form:"file_keys,optional"` // 上传唯一标识信息 diff --git a/server_api/upload.api b/server_api/upload.api index de42df59..5524fead 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -33,8 +33,23 @@ service upload { // 上传文件回调 @handler UploadCallbackHandler post /api/upload/upload-callback(UploadCallbackReq) returns (response); + + // 上传LOGO + @handler UploadLogoHandler + post /api/upload/up-logo(UploadLogoReq) returns (response); + } +type ( + UploadLogoReq { + ResourceId string `form:"resource_id"` // 资源ID + ResourceUrl string `form:"resource_url"` // 资源URL + IsRemoveBg int64 `form:"is_remove_bg"` // 是否要去掉背景 + Proportion int64 `form:"proportion,default=60"` // 贴图在模型面板上的比例 + SkuId int64 `form:"sku_id,default=0"` // 模板ID + } +) + type ( UploadInfo { FileSize int64 `form:"file_size,optional"` // 上传唯一标识信息 diff --git a/utils/basic/basic.go b/utils/basic/basic.go index a2ae1644..8de345cc 100644 --- a/utils/basic/basic.go +++ b/utils/basic/basic.go @@ -77,7 +77,8 @@ var ( CodeAesCbcEncryptionErr = &StatusResponse{5106, "encryption data err"} // 加密数据失败 CodeAesCbcDecryptionErr = &StatusResponse{5107, "decryption data err"} // 解密数据失败 - CodeFileUploadErr = &StatusResponse{5110, "file upload err"} // 文件上传失败 + CodeFileUploadErr = &StatusResponse{5110, "file upload err"} // 文件上传失败 + CodeFileUploadLogoErr = &StatusResponse{5111, "logo upload err"} // 用户上传LOGO失败 ) type Response struct { From 1658238ff2a6147ed075d79b6d971c9d9be888f8 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 14:26:40 +0800 Subject: [PATCH 17/60] fix --- server/websocket/internal/logic/datatransferlogic.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index 25bf50e7..cbd2a0c9 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -146,10 +146,13 @@ func (l *DataTransferLogic) checkAuth(svcCtx *svc.ServiceContext, r *http.Reques if err != nil { return false, nil } - } else { - return false, nil + //不是登录用户也不是游客 + if !userInfo.IsUser() && !userInfo.IsGuest() { + return false, nil + } + return true, userInfo } - return true, userInfo + return false, nil } // 心跳 From 39ffc78d6d03141f194588291f324eba59ae3c85 Mon Sep 17 00:00:00 2001 From: Hiven Date: Thu, 3 Aug 2023 14:38:17 +0800 Subject: [PATCH 18/60] =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=A8=A1=E5=9D=97--log?= =?UTF-8?q?o=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_user_material_gen.go | 15 ++-- model/gmodel/fs_user_material_logic.go | 44 +++++++++++- .../home-user-auth/internal/handler/routes.go | 5 ++ .../internal/handler/userlogolisthandler.go | 35 +++++++++ .../internal/logic/userlogolistlogic.go | 71 +++++++++++++++++++ server/home-user-auth/internal/types/types.go | 6 ++ .../upload/internal/logic/uploadlogologic.go | 14 ++-- server_api/home-user-auth.api | 10 +++ 8 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 server/home-user-auth/internal/handler/userlogolisthandler.go create mode 100644 server/home-user-auth/internal/logic/userlogolistlogic.go diff --git a/model/gmodel/fs_user_material_gen.go b/model/gmodel/fs_user_material_gen.go index 4de4076d..5f880096 100644 --- a/model/gmodel/fs_user_material_gen.go +++ b/model/gmodel/fs_user_material_gen.go @@ -6,13 +6,14 @@ import ( // fs_user_material 用户素材表 type FsUserMaterial struct { - Id int64 `gorm:"primary_key;default:0;" json:"id"` // 用户 ID - Module *string `gorm:"default:'';" json:"module"` // 所属模块 - UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户 ID - ResourceId *string `gorm:"default:'';" json:"resource_id"` // 资源ID - ResourceUrl *string `gorm:"default:'';" json:"resource_url"` // 资源 URL - Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 - CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 上传时间 + Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 用户 ID + Module *string `gorm:"default:'';" json:"module"` // 所属模块 + UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户 ID + GuestId *int64 `gorm:"index;default:0;" json:"guest_id"` // 游客 ID + ResourceId *string `gorm:"default:'';" json:"resource_id"` // 资源ID + ResourceUrl *string `gorm:"default:'';" json:"resource_url"` // 资源 URL + Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 + CreateAt *int64 `gorm:"default:0;" json:"create_at"` // 上传时间 } type FsUserMaterialModel struct { db *gorm.DB diff --git a/model/gmodel/fs_user_material_logic.go b/model/gmodel/fs_user_material_logic.go index 89dcc405..73111e58 100644 --- a/model/gmodel/fs_user_material_logic.go +++ b/model/gmodel/fs_user_material_logic.go @@ -1,6 +1,12 @@ package gmodel -import "context" +import ( + "context" + "fusenapi/utils/handler" + "reflect" + + "gorm.io/gorm" +) // TODO: 使用model的属性做你想做的 @@ -13,3 +19,39 @@ func (p *FsUserMaterialModel) CreateOrUpdate(ctx context.Context, req *FsUserMat } return req, err } + +func (m *FsUserMaterialModel) FindAll(ctx context.Context, rowBuilder *gorm.DB, filterMap map[string]string, orderBy string) ([]*FsUserMaterial, error) { + var resp []*FsUserMaterial + // 过滤 + if filterMap != nil { + rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + } + + // 排序 + if orderBy != "" { + var fieldsMap = make(map[string]struct{}) + s := reflect.TypeOf(&FsUserMaterial{}).Elem() //通过反射获取type定义 + for i := 0; i < s.NumField(); i++ { + fieldsMap[s.Field(i).Tag.Get("json")] = struct{}{} + } + rowBuilder = rowBuilder.Scopes(handler.OrderCheck(orderBy, fieldsMap)) + } + + result := rowBuilder.WithContext(ctx).Find(&resp) + if result.Error != nil { + return nil, result.Error + } else { + return resp, nil + } +} + +func (m *FsUserMaterialModel) RowSelectBuilder(selectData []string) *gorm.DB { + var rowBuilder = m.db.Table(m.name) + + if selectData != nil { + rowBuilder = rowBuilder.Select(selectData) + } else { + rowBuilder = rowBuilder.Select("*") + } + return rowBuilder +} diff --git a/server/home-user-auth/internal/handler/routes.go b/server/home-user-auth/internal/handler/routes.go index 91852e0d..a06a6fea 100644 --- a/server/home-user-auth/internal/handler/routes.go +++ b/server/home-user-auth/internal/handler/routes.go @@ -92,6 +92,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/user/order-cancel", Handler: UserOrderCancelHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/api/user/logo-list", + Handler: UserLogoListHandler(serverCtx), + }, }, ) } diff --git a/server/home-user-auth/internal/handler/userlogolisthandler.go b/server/home-user-auth/internal/handler/userlogolisthandler.go new file mode 100644 index 00000000..873ab4d5 --- /dev/null +++ b/server/home-user-auth/internal/handler/userlogolisthandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserLogoListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.UserLogoListReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUserLogoListLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UserLogoList(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/home-user-auth/internal/logic/userlogolistlogic.go b/server/home-user-auth/internal/logic/userlogolistlogic.go new file mode 100644 index 00000000..b3615e04 --- /dev/null +++ b/server/home-user-auth/internal/logic/userlogolistlogic.go @@ -0,0 +1,71 @@ +package logic + +import ( + "errors" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" + + "github.com/zeromicro/go-zero/core/logx" + "gorm.io/gorm" +) + +type UserLogoListLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUserLogoListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLogoListLogic { + return &UserLogoListLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *UserLogoListLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UserLogoListLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UserLogoListLogic) UserLogoList(req *types.UserLogoListReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + // 定义用户ID + var userId int64 + var guestId int64 + + // 检查用户是否是游客 + if userinfo.IsGuest() { + // 如果是,使用游客ID和游客键名格式 + guestId = userinfo.GuestId + } else { + // 否则,使用用户ID和用户键名格式 + userId = userinfo.UserId + } + + userMaterialModel := gmodel.NewFsUserMaterialModel(l.svcCtx.MysqlConn) + userMaterialRSB := userMaterialModel.RowSelectBuilder(nil).Where("module = ?", "logo").Where("user_id = ?", userId).Where("guest_id = ?", guestId).Order("id desc") + list, err := userMaterialModel.FindAll(l.ctx, userMaterialRSB, nil, "") + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info") + } + return resp.SetStatus(basic.CodeOK, []interface{}{ + list, + }) +} diff --git a/server/home-user-auth/internal/types/types.go b/server/home-user-auth/internal/types/types.go index 81011e49..7ab699ff 100644 --- a/server/home-user-auth/internal/types/types.go +++ b/server/home-user-auth/internal/types/types.go @@ -5,6 +5,12 @@ import ( "fusenapi/utils/basic" ) +type UserLogoListReq struct { +} + +type UserLogoListRes struct { +} + type UserOrderDeleteReq struct { ID int64 `form:"id"` //订单id } diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go index df4283c9..b5a4ede5 100644 --- a/server/upload/internal/logic/uploadlogologic.go +++ b/server/upload/internal/logic/uploadlogologic.go @@ -1,7 +1,6 @@ package logic import ( - "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -46,20 +45,18 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us return resp.SetStatus(basic.CodeUnAuth) } - // 定义用户ID - var uid int64 + var userId int64 + var guestId int64 // 检查用户是否是游客 if userinfo.IsGuest() { // 如果是,使用游客ID和游客键名格式 - uid = userinfo.GuestId + guestId = userinfo.GuestId } else { // 否则,使用用户ID和用户键名格式 - uid = userinfo.UserId + userId = userinfo.UserId } - fmt.Println(uid) - var logoWidth int64 var logoHeight int64 // 查看sku是否存在 @@ -118,7 +115,8 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us userMaterialModel := gmodel.NewFsUserMaterialModel(l.svcCtx.MysqlConn) _, err := userMaterialModel.CreateOrUpdate(l.ctx, &gmodel.FsUserMaterial{ Module: &module, - UserId: &uid, + UserId: &userId, + GuestId: &guestId, ResourceId: &req.ResourceId, ResourceUrl: &req.ResourceUrl, Metadata: &resultStr, diff --git a/server_api/home-user-auth.api b/server_api/home-user-auth.api index bc07a158..c5684eb7 100644 --- a/server_api/home-user-auth.api +++ b/server_api/home-user-auth.api @@ -68,8 +68,18 @@ service home-user-auth { @handler UserOrderCancelHandler get /api/user/order-cancel (UserOrderCancelReq) returns (response); + // 用户logo列表 + @handler UserLogoListHandler + get /api/user/logo-list (UserLogoListReq) returns (response); } +type ( + UserLogoListReq { + } + UserLogoListRes { + } +) + type ( UserOrderDeleteReq { ID int64 `form:"id"` //订单id From ddb93bae41123405cb1710e2674241af3511572c Mon Sep 17 00:00:00 2001 From: Hiven Date: Thu, 3 Aug 2023 14:50:07 +0800 Subject: [PATCH 19/60] =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=A8=A1=E5=9D=97--log?= =?UTF-8?q?o=E5=88=97=E8=A1=A8=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/home-user-auth/internal/logic/userlogolistlogic.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/home-user-auth/internal/logic/userlogolistlogic.go b/server/home-user-auth/internal/logic/userlogolistlogic.go index b3615e04..fc68b59e 100644 --- a/server/home-user-auth/internal/logic/userlogolistlogic.go +++ b/server/home-user-auth/internal/logic/userlogolistlogic.go @@ -41,7 +41,6 @@ func NewUserLogoListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *User func (l *UserLogoListLogic) UserLogoList(req *types.UserLogoListReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null - // 定义用户ID var userId int64 var guestId int64 @@ -56,14 +55,15 @@ func (l *UserLogoListLogic) UserLogoList(req *types.UserLogoListReq, userinfo *a } userMaterialModel := gmodel.NewFsUserMaterialModel(l.svcCtx.MysqlConn) - userMaterialRSB := userMaterialModel.RowSelectBuilder(nil).Where("module = ?", "logo").Where("user_id = ?", userId).Where("guest_id = ?", guestId).Order("id desc") + userMaterialRSB := userMaterialModel.RowSelectBuilder(nil). + Where("module = ?", "logo").Where("user_id = ?", userId).Where("guest_id = ?", guestId).Order("id desc") list, err := userMaterialModel.FindAll(l.ctx, userMaterialRSB, nil, "") if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "data not found") } logx.Error(err) - return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info") + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get data list") } return resp.SetStatus(basic.CodeOK, []interface{}{ list, From a864335c0e97ce004f8a38cc2ab1c1f50cec1efc Mon Sep 17 00:00:00 2001 From: Hiven Date: Thu, 3 Aug 2023 14:55:56 +0800 Subject: [PATCH 20/60] =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=A8=A1=E5=9D=97--log?= =?UTF-8?q?o=E5=88=97=E8=A1=A8=E8=B0=83=E6=95=B4=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/home-user-auth/internal/logic/userlogolistlogic.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/home-user-auth/internal/logic/userlogolistlogic.go b/server/home-user-auth/internal/logic/userlogolistlogic.go index fc68b59e..14bc97d4 100644 --- a/server/home-user-auth/internal/logic/userlogolistlogic.go +++ b/server/home-user-auth/internal/logic/userlogolistlogic.go @@ -65,7 +65,7 @@ func (l *UserLogoListLogic) UserLogoList(req *types.UserLogoListReq, userinfo *a logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get data list") } - return resp.SetStatus(basic.CodeOK, []interface{}{ - list, + return resp.SetStatus(basic.CodeOK, map[string]interface{}{ + "list": list, }) } From b40293fdd9d017cce53da173a0d1db503a02aac3 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 15:54:50 +0800 Subject: [PATCH 21/60] fix --- server/assistant/Dockerfile | 5 +++++ server/backend/Dockerfile | 5 +++++ server/canteen/Dockerfile | 5 +++++ server/data-transfer/Dockerfile | 5 +++++ server/home-user-auth/Dockerfile | 5 +++++ server/inventory/Dockerfile | 5 +++++ server/map-library/Dockerfile | 5 +++++ server/orders/Dockerfile | 5 +++++ server/pay/Dockerfile | 5 +++++ server/product-model/Dockerfile | 5 +++++ server/product-template-tag/Dockerfile | 5 +++++ server/product-template/Dockerfile | 5 +++++ server/product/Dockerfile | 5 +++++ server/render/Dockerfile | 5 +++++ server/shopping-cart-confirmation/Dockerfile | 5 +++++ server/upload/Dockerfile | 5 +++++ server/webset/Dockerfile | 5 +++++ server/websocket/Dockerfile | 5 +++++ 18 files changed, 90 insertions(+) create mode 100755 server/assistant/Dockerfile create mode 100755 server/backend/Dockerfile create mode 100755 server/canteen/Dockerfile create mode 100755 server/data-transfer/Dockerfile create mode 100755 server/home-user-auth/Dockerfile create mode 100755 server/inventory/Dockerfile create mode 100755 server/map-library/Dockerfile create mode 100755 server/orders/Dockerfile create mode 100755 server/pay/Dockerfile create mode 100755 server/product-model/Dockerfile create mode 100755 server/product-template-tag/Dockerfile create mode 100755 server/product-template/Dockerfile create mode 100755 server/product/Dockerfile create mode 100755 server/render/Dockerfile create mode 100755 server/shopping-cart-confirmation/Dockerfile create mode 100755 server/upload/Dockerfile create mode 100755 server/webset/Dockerfile create mode 100755 server/websocket/Dockerfile diff --git a/server/assistant/Dockerfile b/server/assistant/Dockerfile new file mode 100755 index 00000000..2a482d6f --- /dev/null +++ b/server/assistant/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-assistant-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-assistant-srv"] diff --git a/server/backend/Dockerfile b/server/backend/Dockerfile new file mode 100755 index 00000000..65f2a7e5 --- /dev/null +++ b/server/backend/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-backend-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-backend-srv"] diff --git a/server/canteen/Dockerfile b/server/canteen/Dockerfile new file mode 100755 index 00000000..bebaacaa --- /dev/null +++ b/server/canteen/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-canteen-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-canteen-srv"] diff --git a/server/data-transfer/Dockerfile b/server/data-transfer/Dockerfile new file mode 100755 index 00000000..ccb4944b --- /dev/null +++ b/server/data-transfer/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-data-transfer-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-data-transfer-srv"] diff --git a/server/home-user-auth/Dockerfile b/server/home-user-auth/Dockerfile new file mode 100755 index 00000000..80b09874 --- /dev/null +++ b/server/home-user-auth/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-home-user-auth-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-home-user-auth-srv"] diff --git a/server/inventory/Dockerfile b/server/inventory/Dockerfile new file mode 100755 index 00000000..4a6e1a1a --- /dev/null +++ b/server/inventory/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-inventory-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-inventory-srv"] diff --git a/server/map-library/Dockerfile b/server/map-library/Dockerfile new file mode 100755 index 00000000..7bec150c --- /dev/null +++ b/server/map-library/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-map-library-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-map-library-srv"] diff --git a/server/orders/Dockerfile b/server/orders/Dockerfile new file mode 100755 index 00000000..16130ac0 --- /dev/null +++ b/server/orders/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-order-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-order-srv"] diff --git a/server/pay/Dockerfile b/server/pay/Dockerfile new file mode 100755 index 00000000..dfa78ce5 --- /dev/null +++ b/server/pay/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-pay-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-pay-srv"] diff --git a/server/product-model/Dockerfile b/server/product-model/Dockerfile new file mode 100755 index 00000000..6aedc86f --- /dev/null +++ b/server/product-model/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-product-model-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-product-model-srv"] diff --git a/server/product-template-tag/Dockerfile b/server/product-template-tag/Dockerfile new file mode 100755 index 00000000..719821a6 --- /dev/null +++ b/server/product-template-tag/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-product-template-tag-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-product-template-tag-srv"] diff --git a/server/product-template/Dockerfile b/server/product-template/Dockerfile new file mode 100755 index 00000000..a26db3b3 --- /dev/null +++ b/server/product-template/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-product-template-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-product-template-srv"] diff --git a/server/product/Dockerfile b/server/product/Dockerfile new file mode 100755 index 00000000..5c066e4c --- /dev/null +++ b/server/product/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-product-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-product-srv"] diff --git a/server/render/Dockerfile b/server/render/Dockerfile new file mode 100755 index 00000000..b56cc917 --- /dev/null +++ b/server/render/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-render-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-render-srv"] diff --git a/server/shopping-cart-confirmation/Dockerfile b/server/shopping-cart-confirmation/Dockerfile new file mode 100755 index 00000000..ae93ddea --- /dev/null +++ b/server/shopping-cart-confirmation/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-shopping-cart-confirmation-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-shopping-cart-confirmation-srv"] diff --git a/server/upload/Dockerfile b/server/upload/Dockerfile new file mode 100755 index 00000000..84f5d6e4 --- /dev/null +++ b/server/upload/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-upload-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-upload-srv"] diff --git a/server/webset/Dockerfile b/server/webset/Dockerfile new file mode 100755 index 00000000..c33eaa87 --- /dev/null +++ b/server/webset/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-webset-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-webset-srv"] diff --git a/server/websocket/Dockerfile b/server/websocket/Dockerfile new file mode 100755 index 00000000..ed7ab7c0 --- /dev/null +++ b/server/websocket/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine + +WORKDIR /www/fusenapi/ +COPY ./api-websocket-srv /www/fusenapi/ +CMD ["/www/fusenapi/api-websocket-srv"] From 9f01ecaf8003eebc1089782b6795d59b2ee51e43 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 16:49:25 +0800 Subject: [PATCH 22/60] fix --- .gitignore | 2 +- fs_package_docker_image.sh | 10 ++++++++++ server/assistant/Dockerfile | 3 ++- server/backend/Dockerfile | 3 ++- server/canteen/Dockerfile | 3 ++- server/data-transfer/Dockerfile | 3 ++- server/home-user-auth/Dockerfile | 3 ++- server/inventory/Dockerfile | 3 ++- server/map-library/Dockerfile | 3 ++- server/orders/Dockerfile | 3 ++- server/pay/Dockerfile | 3 ++- server/product-model/Dockerfile | 3 ++- server/product-template-tag/Dockerfile | 3 ++- server/product-template/Dockerfile | 3 ++- server/product/Dockerfile | 3 ++- server/render/Dockerfile | 3 ++- server/shopping-cart-confirmation/Dockerfile | 3 ++- server/upload/Dockerfile | 3 ++- server/webset/Dockerfile | 3 ++- server/websocket/Dockerfile | 3 ++- 20 files changed, 47 insertions(+), 19 deletions(-) create mode 100755 fs_package_docker_image.sh diff --git a/.gitignore b/.gitignore index 9a4b0c48..2b19cbb7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ *.dll *.so *.dylib - +bin/ # Test binary, built with `go test -c` *.test diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh new file mode 100755 index 00000000..04a1ab9e --- /dev/null +++ b/fs_package_docker_image.sh @@ -0,0 +1,10 @@ +#!/bin/bash +name=${1%%\\*} +#进入对应服务目录 +cd server/$name +#构建二进制文件 +CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$name-srv ./$name.go +#删除之前旧的镜像 +docker rmi -f api-$name-srv:latest +#打包docker镜像 +docker build -t api-$name-srv:latest . diff --git a/server/assistant/Dockerfile b/server/assistant/Dockerfile index 2a482d6f..55d617cc 100755 --- a/server/assistant/Dockerfile +++ b/server/assistant/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-assistant-srv /www/fusenapi/ +COPY ./bin/api-assistant-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-assistant-srv"] diff --git a/server/backend/Dockerfile b/server/backend/Dockerfile index 65f2a7e5..e30c6bed 100755 --- a/server/backend/Dockerfile +++ b/server/backend/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-backend-srv /www/fusenapi/ +COPY ./bin/api-backend-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-backend-srv"] diff --git a/server/canteen/Dockerfile b/server/canteen/Dockerfile index bebaacaa..a268222d 100755 --- a/server/canteen/Dockerfile +++ b/server/canteen/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-canteen-srv /www/fusenapi/ +COPY ./bin/api-canteen-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-canteen-srv"] diff --git a/server/data-transfer/Dockerfile b/server/data-transfer/Dockerfile index ccb4944b..82090c4b 100755 --- a/server/data-transfer/Dockerfile +++ b/server/data-transfer/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-data-transfer-srv /www/fusenapi/ +COPY ./bin/api-data-transfer-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-data-transfer-srv"] diff --git a/server/home-user-auth/Dockerfile b/server/home-user-auth/Dockerfile index 80b09874..3c7a0da5 100755 --- a/server/home-user-auth/Dockerfile +++ b/server/home-user-auth/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-home-user-auth-srv /www/fusenapi/ +COPY ./bin/api-home-user-auth-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-home-user-auth-srv"] diff --git a/server/inventory/Dockerfile b/server/inventory/Dockerfile index 4a6e1a1a..4fa34360 100755 --- a/server/inventory/Dockerfile +++ b/server/inventory/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-inventory-srv /www/fusenapi/ +COPY ./bin/api-inventory-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-inventory-srv"] diff --git a/server/map-library/Dockerfile b/server/map-library/Dockerfile index 7bec150c..460cbfd5 100755 --- a/server/map-library/Dockerfile +++ b/server/map-library/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-map-library-srv /www/fusenapi/ +COPY ./bin/api-map-library-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-map-library-srv"] diff --git a/server/orders/Dockerfile b/server/orders/Dockerfile index 16130ac0..2a5043d6 100755 --- a/server/orders/Dockerfile +++ b/server/orders/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-order-srv /www/fusenapi/ +COPY ./bin/api-order-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-order-srv"] diff --git a/server/pay/Dockerfile b/server/pay/Dockerfile index dfa78ce5..df5dab5b 100755 --- a/server/pay/Dockerfile +++ b/server/pay/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-pay-srv /www/fusenapi/ +COPY ./bin/api-pay-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-pay-srv"] diff --git a/server/product-model/Dockerfile b/server/product-model/Dockerfile index 6aedc86f..e207b762 100755 --- a/server/product-model/Dockerfile +++ b/server/product-model/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-product-model-srv /www/fusenapi/ +COPY ./bin/api-product-model-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-product-model-srv"] diff --git a/server/product-template-tag/Dockerfile b/server/product-template-tag/Dockerfile index 719821a6..abc15189 100755 --- a/server/product-template-tag/Dockerfile +++ b/server/product-template-tag/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-product-template-tag-srv /www/fusenapi/ +COPY ./bin/api-product-template-tag-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-product-template-tag-srv"] diff --git a/server/product-template/Dockerfile b/server/product-template/Dockerfile index a26db3b3..2012a6d9 100755 --- a/server/product-template/Dockerfile +++ b/server/product-template/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-product-template-srv /www/fusenapi/ +COPY ./bin/api-product-template-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-product-template-srv"] diff --git a/server/product/Dockerfile b/server/product/Dockerfile index 5c066e4c..4ec40fcf 100755 --- a/server/product/Dockerfile +++ b/server/product/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-product-srv /www/fusenapi/ +COPY ./bin/api-product-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-product-srv"] diff --git a/server/render/Dockerfile b/server/render/Dockerfile index b56cc917..b9722b92 100755 --- a/server/render/Dockerfile +++ b/server/render/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-render-srv /www/fusenapi/ +COPY ./bin/api-render-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-render-srv"] diff --git a/server/shopping-cart-confirmation/Dockerfile b/server/shopping-cart-confirmation/Dockerfile index ae93ddea..5aa4c0d5 100755 --- a/server/shopping-cart-confirmation/Dockerfile +++ b/server/shopping-cart-confirmation/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-shopping-cart-confirmation-srv /www/fusenapi/ +COPY ./bin/api-shopping-cart-confirmation-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-shopping-cart-confirmation-srv"] diff --git a/server/upload/Dockerfile b/server/upload/Dockerfile index 84f5d6e4..b3ee358e 100755 --- a/server/upload/Dockerfile +++ b/server/upload/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-upload-srv /www/fusenapi/ +COPY ./bin/api-upload-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-upload-srv"] diff --git a/server/webset/Dockerfile b/server/webset/Dockerfile index c33eaa87..7cbcc7eb 100755 --- a/server/webset/Dockerfile +++ b/server/webset/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-webset-srv /www/fusenapi/ +COPY ./bin/api-webset-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-webset-srv"] diff --git a/server/websocket/Dockerfile b/server/websocket/Dockerfile index ed7ab7c0..e183ac2b 100755 --- a/server/websocket/Dockerfile +++ b/server/websocket/Dockerfile @@ -1,5 +1,6 @@ FROM alpine WORKDIR /www/fusenapi/ -COPY ./api-websocket-srv /www/fusenapi/ +COPY ./bin/api-websocket-srv /www/fusenapi/ +COPY ./etc /www/fusenapi/etc CMD ["/www/fusenapi/api-websocket-srv"] From 57af3338a245207dddcd2bf4e15398e18f24de23 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 17:12:58 +0800 Subject: [PATCH 23/60] fix --- fs_package_docker_image.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh index 04a1ab9e..cd97c0ac 100755 --- a/fs_package_docker_image.sh +++ b/fs_package_docker_image.sh @@ -8,3 +8,5 @@ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$na docker rmi -f api-$name-srv:latest #打包docker镜像 docker build -t api-$name-srv:latest . +#上传镜像到dockerhub +#docker push api-$name-srv:latest \ No newline at end of file From c49235b59d5c5e842841ea4f7f612626a0490541 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 17:30:46 +0800 Subject: [PATCH 24/60] fix --- fs_package_docker_image.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh index cd97c0ac..0210110a 100755 --- a/fs_package_docker_image.sh +++ b/fs_package_docker_image.sh @@ -8,5 +8,7 @@ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$na docker rmi -f api-$name-srv:latest #打包docker镜像 docker build -t api-$name-srv:latest . -#上传镜像到dockerhub +#把本地镜像load到k8s中(这个适用于无dockerhub镜像仓库情况,需要对应的deployment中的 imagePullPolicy 参数从 Always 变成None) +minikube image load api-$name-srv:latest +#上传镜像到dockerhub(有dockerhub镜像仓库后打开,且把上面的load image去掉,对应的deployment中的 imagePullPolicy 参数从 None Always) #docker push api-$name-srv:latest \ No newline at end of file From ae9bad0baa58978cd3ef53aa558f0d28be7fca14 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 17:36:11 +0800 Subject: [PATCH 25/60] fix --- goctl_template/api/etc.tpl | 1 + server/websocket/etc/websocket.yaml | 9 --------- server/websocket/websocket.go | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 server/websocket/etc/websocket.yaml diff --git a/goctl_template/api/etc.tpl b/goctl_template/api/etc.tpl index a39c0af4..a813c4d3 100644 --- a/goctl_template/api/etc.tpl +++ b/goctl_template/api/etc.tpl @@ -1,6 +1,7 @@ Name: {{.serviceName}} Host: {{.host}} Port: {{.port}} +Timeout: 15000 #服务超时时间(毫秒) SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest Auth: AccessSecret: fusen2023 diff --git a/server/websocket/etc/websocket.yaml b/server/websocket/etc/websocket.yaml deleted file mode 100644 index 5f58765d..00000000 --- a/server/websocket/etc/websocket.yaml +++ /dev/null @@ -1,9 +0,0 @@ -Name: websocket -Host: 0.0.0.0 -Port: 9914 -SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest -Auth: - AccessSecret: fusen2023 - AccessExpire: 2592000 - RefreshAfter: 1592000 -SourceRabbitMq: amqp://rabbit001:rabbit001129@110.41.19.98:5672 \ No newline at end of file diff --git a/server/websocket/websocket.go b/server/websocket/websocket.go index c5e7bdd0..04f326e9 100644 --- a/server/websocket/websocket.go +++ b/server/websocket/websocket.go @@ -23,7 +23,6 @@ func main() { var c config.Config conf.MustLoad(*configFile, &c) - c.Timeout = int64(time.Second * 15) server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(auth.FsCors, func(w http.ResponseWriter) { })) defer server.Stop() From 07dae7093079cfdf0bcaf975dd1ea6f2967e7775 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 17:37:21 +0800 Subject: [PATCH 26/60] fix --- server/websocket/websocket.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/websocket/websocket.go b/server/websocket/websocket.go index 04f326e9..b6c469b6 100644 --- a/server/websocket/websocket.go +++ b/server/websocket/websocket.go @@ -4,7 +4,6 @@ import ( "flag" "fmt" "net/http" - "time" "fusenapi/utils/auth" @@ -29,7 +28,6 @@ func main() { ctx := svc.NewServiceContext(c) handler.RegisterHandlers(server, ctx) - fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) server.Start() } From 6158779a9507980817a9fc07f36c8050d4bb208d Mon Sep 17 00:00:00 2001 From: Hiven Date: Thu, 3 Aug 2023 17:37:25 +0800 Subject: [PATCH 27/60] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_order_logic.go | 12 +- model/gmodel/fs_pay_logic.go | 10 +- model/gmodel/fs_refund_reason_logic.go | 4 +- model/gmodel/fs_resource_logic.go | 4 +- model/gmodel/fs_resources_logic.go | 4 +- model/gmodel/fs_user_material_logic.go | 6 +- .../home-user-auth/internal/handler/routes.go | 5 + .../internal/handler/useragainorderhandler.go | 35 +++++ .../internal/logic/useragainorderlogic.go | 144 ++++++++++++++++++ .../internal/logic/userordercancellogic.go | 8 +- server/home-user-auth/internal/types/types.go | 7 + server_api/home-user-auth.api | 11 ++ utils/{handler => handlers}/gormHandler.go | 2 +- utils/{handler => handlers}/payHandler.go | 2 +- 14 files changed, 228 insertions(+), 26 deletions(-) create mode 100644 server/home-user-auth/internal/handler/useragainorderhandler.go create mode 100644 server/home-user-auth/internal/logic/useragainorderlogic.go rename utils/{handler => handlers}/gormHandler.go (99%) rename utils/{handler => handlers}/payHandler.go (99%) diff --git a/model/gmodel/fs_order_logic.go b/model/gmodel/fs_order_logic.go index b96e4d90..60ce74d8 100755 --- a/model/gmodel/fs_order_logic.go +++ b/model/gmodel/fs_order_logic.go @@ -6,7 +6,7 @@ import ( "reflect" "time" - "fusenapi/utils/handler" + "fusenapi/utils/handlers" "gorm.io/gorm" ) @@ -60,7 +60,7 @@ func (o *FsOrderModel) FindPageListByPage(ctx context.Context, rowBuilder *gorm. var resp []*FsOrderRel // 过滤 if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } // 排序 @@ -70,11 +70,11 @@ func (o *FsOrderModel) FindPageListByPage(ctx context.Context, rowBuilder *gorm. for i := 0; i < s.NumField(); i++ { fieldsMap[s.Field(i).Tag.Get("json")] = struct{}{} } - rowBuilder = rowBuilder.Scopes(handler.OrderCheck(orderBy, fieldsMap)) + rowBuilder = rowBuilder.Scopes(handlers.OrderCheck(orderBy, fieldsMap)) } // 分页 - rowBuilder = rowBuilder.Scopes(handler.Paginate(page, pageSize)) + rowBuilder = rowBuilder.Scopes(handlers.Paginate(page, pageSize)) // 结果 result := rowBuilder.Debug().WithContext(ctx).Find(&resp) @@ -125,7 +125,7 @@ func (m *FsOrderModel) FindCount(ctx context.Context, countBuilder *gorm.DB, fil // 过滤 if filterMap != nil { - countBuilder = countBuilder.Scopes(handler.FilterData(filterMap)) + countBuilder = countBuilder.Scopes(handlers.FilterData(filterMap)) } result := countBuilder.WithContext(ctx).Limit(1).Count(&count) @@ -140,7 +140,7 @@ func (m *FsOrderModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, var resp FsOrderRel if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) diff --git a/model/gmodel/fs_pay_logic.go b/model/gmodel/fs_pay_logic.go index fa4a6093..c23f3b36 100644 --- a/model/gmodel/fs_pay_logic.go +++ b/model/gmodel/fs_pay_logic.go @@ -2,7 +2,7 @@ package gmodel import ( "context" - "fusenapi/utils/handler" + "fusenapi/utils/handlers" "reflect" "gorm.io/gorm" @@ -55,7 +55,7 @@ func (m *FsPayModel) FindCount(ctx context.Context, countBuilder *gorm.DB, filte // 过滤 if filterMap != nil { - countBuilder = countBuilder.Scopes(handler.FilterData(filterMap)) + countBuilder = countBuilder.Scopes(handlers.FilterData(filterMap)) } result := countBuilder.WithContext(ctx).Limit(1).Count(&count) @@ -70,7 +70,7 @@ func (m *FsPayModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, fi var resp FsPay if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) @@ -85,7 +85,7 @@ func (m *FsPayModel) FindAll(ctx context.Context, rowBuilder *gorm.DB, filterMap var resp []*FsPay // 过滤 if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } // 排序 @@ -95,7 +95,7 @@ func (m *FsPayModel) FindAll(ctx context.Context, rowBuilder *gorm.DB, filterMap for i := 0; i < s.NumField(); i++ { fieldsMap[s.Field(i).Tag.Get("json")] = struct{}{} } - rowBuilder = rowBuilder.Scopes(handler.OrderCheck(orderBy, fieldsMap)) + rowBuilder = rowBuilder.Scopes(handlers.OrderCheck(orderBy, fieldsMap)) } result := rowBuilder.WithContext(ctx).Find(&resp) diff --git a/model/gmodel/fs_refund_reason_logic.go b/model/gmodel/fs_refund_reason_logic.go index 48e67d51..14acda7a 100644 --- a/model/gmodel/fs_refund_reason_logic.go +++ b/model/gmodel/fs_refund_reason_logic.go @@ -2,7 +2,7 @@ package gmodel import ( "context" - "fusenapi/utils/handler" + "fusenapi/utils/handlers" "gorm.io/gorm" ) @@ -40,7 +40,7 @@ func (m *FsRefundReasonModel) FindOneByQuery(ctx context.Context, rowBuilder *go var resp FsRefundReason if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) diff --git a/model/gmodel/fs_resource_logic.go b/model/gmodel/fs_resource_logic.go index e72f5ae3..6dab100f 100644 --- a/model/gmodel/fs_resource_logic.go +++ b/model/gmodel/fs_resource_logic.go @@ -3,7 +3,7 @@ package gmodel import ( "context" "errors" - "fusenapi/utils/handler" + "fusenapi/utils/handlers" "gorm.io/gorm" ) @@ -36,7 +36,7 @@ func (m *FsResourceModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.D var resp FsResource if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) diff --git a/model/gmodel/fs_resources_logic.go b/model/gmodel/fs_resources_logic.go index 767af34a..3ae4657c 100644 --- a/model/gmodel/fs_resources_logic.go +++ b/model/gmodel/fs_resources_logic.go @@ -2,7 +2,7 @@ package gmodel import ( "context" - "fusenapi/utils/handler" + "fusenapi/utils/handlers" "gorm.io/gorm" ) @@ -23,7 +23,7 @@ func (m *FsResourcesModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm. var resp FsResources if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp) diff --git a/model/gmodel/fs_user_material_logic.go b/model/gmodel/fs_user_material_logic.go index 73111e58..d8ecaaf4 100644 --- a/model/gmodel/fs_user_material_logic.go +++ b/model/gmodel/fs_user_material_logic.go @@ -2,7 +2,7 @@ package gmodel import ( "context" - "fusenapi/utils/handler" + "fusenapi/utils/handlers" "reflect" "gorm.io/gorm" @@ -24,7 +24,7 @@ func (m *FsUserMaterialModel) FindAll(ctx context.Context, rowBuilder *gorm.DB, var resp []*FsUserMaterial // 过滤 if filterMap != nil { - rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap)) + rowBuilder = rowBuilder.Scopes(handlers.FilterData(filterMap)) } // 排序 @@ -34,7 +34,7 @@ func (m *FsUserMaterialModel) FindAll(ctx context.Context, rowBuilder *gorm.DB, for i := 0; i < s.NumField(); i++ { fieldsMap[s.Field(i).Tag.Get("json")] = struct{}{} } - rowBuilder = rowBuilder.Scopes(handler.OrderCheck(orderBy, fieldsMap)) + rowBuilder = rowBuilder.Scopes(handlers.OrderCheck(orderBy, fieldsMap)) } result := rowBuilder.WithContext(ctx).Find(&resp) diff --git a/server/home-user-auth/internal/handler/routes.go b/server/home-user-auth/internal/handler/routes.go index a06a6fea..607e6278 100644 --- a/server/home-user-auth/internal/handler/routes.go +++ b/server/home-user-auth/internal/handler/routes.go @@ -97,6 +97,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/user/logo-list", Handler: UserLogoListHandler(serverCtx), }, + { + Method: http.MethodGet, + Path: "/api/user/one-more-order", + Handler: UserAgainOrderHandler(serverCtx), + }, }, ) } diff --git a/server/home-user-auth/internal/handler/useragainorderhandler.go b/server/home-user-auth/internal/handler/useragainorderhandler.go new file mode 100644 index 00000000..4bf584e7 --- /dev/null +++ b/server/home-user-auth/internal/handler/useragainorderhandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserAgainOrderHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.UserAgainOrderReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUserAgainOrderLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UserAgainOrder(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/home-user-auth/internal/logic/useragainorderlogic.go b/server/home-user-auth/internal/logic/useragainorderlogic.go new file mode 100644 index 00000000..c1edb6c4 --- /dev/null +++ b/server/home-user-auth/internal/logic/useragainorderlogic.go @@ -0,0 +1,144 @@ +package logic + +import ( + "errors" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "time" + + "context" + + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" + + "github.com/zeromicro/go-zero/core/logx" + "gorm.io/gorm" +) + +type UserAgainOrderLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUserAgainOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserAgainOrderLogic { + return &UserAgainOrderLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *UserAgainOrderLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UserAgainOrderLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UserAgainOrderLogic) UserAgainOrder(req *types.UserAgainOrderReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + if userinfo == nil || userinfo.UserId == 0 { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") + } + + // 查询订单数据 + orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn) + orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn) + fsOrderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn) + fsProductDesignModel := gmodel.NewFsProductDesignModel(l.svcCtx.MysqlConn) + + rsbOrder := orderModel.RowSelectBuilder(nil) + rsbOrder = rsbOrder.Where("sn =?", req.Sn).Preload("FsOrderDetails") + rsbOrder = rsbOrder.Preload("FsOrderDetails", func(dbPreload *gorm.DB) *gorm.DB { + return dbPreload.Table(fsOrderDetailModel.TableName()).Preload("FsOrderDetailTemplateInfo", func(dbPreload *gorm.DB) *gorm.DB { + return dbPreload.Table(orderDetailTemplateModel.TableName()).Preload("FsProductDesignInfo", func(dbPreload *gorm.DB) *gorm.DB { + return dbPreload.Table(fsProductDesignModel.TableName()) + }) + }) + }) + + fsOrderRelInfo, err := orderModel.FindOneByQuery(l.ctx, rsbOrder, nil) + + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found") + } + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info") + } + + if len(fsOrderRelInfo.FsOrderDetails) > 0 { + for _, fsOrderDetail := range fsOrderRelInfo.FsOrderDetails { + var isCheck int64 = 1 + productDesignInfo := fsOrderDetail.FsOrderDetailTemplateInfo.FsProductDesignInfo + if productDesignInfo.Id != 0 { + + // 查找是否有此材质、产品、大小id的阶梯价格 + productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn) + priceStatus := int64(1) + priceReq := gmodel.FindOneProductPriceByParamsReq{ + ProductId: productDesignInfo.ProductId, + MaterialId: productDesignInfo.MaterialId, + SizeId: productDesignInfo.SizeId, + Status: &priceStatus, + } + productPriceInfo, err := productPriceModel.FindOneProductPriceByParams(l.ctx, priceReq) + if err == nil && productPriceInfo.Id != 0 && *productPriceInfo.EachBoxNum > 0 { + + // 买的数量和每箱数量取余为0 且 份数大于等于最小购买数量才算满足条件 + if *fsOrderDetail.BuyNum%*productPriceInfo.EachBoxNum == 0 && int64(float64(*fsOrderDetail.BuyNum)/float64(*productPriceInfo.EachBoxNum)) >= *productPriceInfo.MinBuyNum { + + // 查询购物车 + cartModel := gmodel.NewFsCartModel(l.svcCtx.MysqlConn) + cartStatus := int64(1) + cartReq := gmodel.FindOneCartByParamsReq{ + UserId: &userinfo.UserId, + ProductId: productDesignInfo.ProductId, + TemplateId: productDesignInfo.TemplateId, + PriceId: &productPriceInfo.Id, + DesignId: &productDesignInfo.Id, + MaterialId: productDesignInfo.MaterialId, + Status: &cartStatus, + } + cartInfo, err := cartModel.FindOneCartByParams(l.ctx, cartReq) + if err == nil && (err != nil && errors.Is(err, gorm.ErrRecordNotFound)) { + now := time.Now().Unix() + nowTime := time.Now() + data := gmodel.FsCart{ + UserId: &userinfo.UserId, + ProductId: productPriceInfo.ProductId, + TemplateId: productDesignInfo.TemplateId, + PriceId: &productPriceInfo.Id, + MaterialId: productDesignInfo.MaterialId, + SizeId: productDesignInfo.SizeId, + BuyNum: fsOrderDetail.BuyNum, + Cover: productDesignInfo.Cover, + DesignId: &productDesignInfo.Id, + Ctime: &now, + Status: &cartStatus, + OptionalId: productDesignInfo.OptionalId, + IsCheck: &isCheck, + TsTime: &nowTime, + } + if cartInfo == nil { + err = cartModel.Create(l.ctx, data) + } else { + err = cartModel.Update(l.ctx, cartInfo.Id, data) + } + if err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to add to cart") + } + } + } + } + } + } + } + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/home-user-auth/internal/logic/userordercancellogic.go b/server/home-user-auth/internal/logic/userordercancellogic.go index ce64a5b2..3fad53bb 100644 --- a/server/home-user-auth/internal/logic/userordercancellogic.go +++ b/server/home-user-auth/internal/logic/userordercancellogic.go @@ -6,13 +6,13 @@ import ( "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/handlers" "time" "context" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" - handlerUtils "fusenapi/utils/handler" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" @@ -74,7 +74,7 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us orderInfo.RefundReason = &req.RefundReason var nowTime = time.Now().Unix() - var payList []handlerUtils.PayInfo + var payList []handlers.PayInfo // 事务处理 err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { // 修改订单信息 @@ -106,7 +106,7 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us if *payInfo.PaymentMethod == int64(constants.PAYMETHOD_STRIPE) { key = l.svcCtx.Config.PayConfig.Stripe.Key } - payList = append(payList, handlerUtils.PayInfo{ + payList = append(payList, handlers.PayInfo{ TradeNo: *payInfo.TradeNo, PaymentMethod: *payInfo.PaymentMethod, Key: key, @@ -115,7 +115,7 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us return nil }) // 退款申请--调取第三方接口发起退款 - handlerUtils.PayRefundHandler(&handlerUtils.PayRefundHandlerReq{ + handlers.PayRefundHandler(&handlers.PayRefundHandlerReq{ PayInfoList: payList, }) if err != nil { diff --git a/server/home-user-auth/internal/types/types.go b/server/home-user-auth/internal/types/types.go index 7ab699ff..b183ef86 100644 --- a/server/home-user-auth/internal/types/types.go +++ b/server/home-user-auth/internal/types/types.go @@ -5,6 +5,13 @@ import ( "fusenapi/utils/basic" ) +type UserAgainOrderReq struct { + Sn string `form:"sn"` // 订单编号 +} + +type UserAgainOrderRes struct { +} + type UserLogoListReq struct { } diff --git a/server_api/home-user-auth.api b/server_api/home-user-auth.api index c5684eb7..3b686163 100644 --- a/server_api/home-user-auth.api +++ b/server_api/home-user-auth.api @@ -71,8 +71,19 @@ service home-user-auth { // 用户logo列表 @handler UserLogoListHandler get /api/user/logo-list (UserLogoListReq) returns (response); + + // 再来一单 + @handler UserAgainOrderHandler + get /api/user/one-more-order (UserAgainOrderReq) returns (response); } +type ( + UserAgainOrderReq { + Sn string `form:"sn"` // 订单编号 + } + UserAgainOrderRes struct{} +) + type ( UserLogoListReq { } diff --git a/utils/handler/gormHandler.go b/utils/handlers/gormHandler.go similarity index 99% rename from utils/handler/gormHandler.go rename to utils/handlers/gormHandler.go index d239931e..e9b21633 100644 --- a/utils/handler/gormHandler.go +++ b/utils/handlers/gormHandler.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "encoding/json" diff --git a/utils/handler/payHandler.go b/utils/handlers/payHandler.go similarity index 99% rename from utils/handler/payHandler.go rename to utils/handlers/payHandler.go index f69412b7..66fd7590 100644 --- a/utils/handler/payHandler.go +++ b/utils/handlers/payHandler.go @@ -1,4 +1,4 @@ -package handler +package handlers import ( "fusenapi/constants" From 7966077838281d5968b4ebf0cfeb166c6c18f162 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 17:37:35 +0800 Subject: [PATCH 28/60] fix --- server/websocket/etc/websocket.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 server/websocket/etc/websocket.yaml diff --git a/server/websocket/etc/websocket.yaml b/server/websocket/etc/websocket.yaml new file mode 100644 index 00000000..ea43c1b1 --- /dev/null +++ b/server/websocket/etc/websocket.yaml @@ -0,0 +1,10 @@ +Name: websocket +Host: 0.0.0.0 +Port: 8888 +Timeout: 15000 #服务超时时间 +SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest +Auth: + AccessSecret: fusen2023 + AccessExpire: 2592000 + RefreshAfter: 1592000 +SourceRabbitMq: amqp://rabbit001:rabbit001129@110.41.19.98:5672 \ No newline at end of file From a9d646c180c594e0e8bd2cbab9c2d7e58a6e9300 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 17:40:13 +0800 Subject: [PATCH 29/60] fix --- server/websocket/etc/websocket.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/websocket/etc/websocket.yaml b/server/websocket/etc/websocket.yaml index ea43c1b1..d47e1243 100644 --- a/server/websocket/etc/websocket.yaml +++ b/server/websocket/etc/websocket.yaml @@ -1,6 +1,6 @@ Name: websocket Host: 0.0.0.0 -Port: 8888 +Port: 9914 Timeout: 15000 #服务超时时间 SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest Auth: From e00c813e7234e7cffac9f832989d76f5463868cb Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Thu, 3 Aug 2023 17:49:17 +0800 Subject: [PATCH 30/60] fix --- fs_package_docker_image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh index 0210110a..1b9a4ca8 100755 --- a/fs_package_docker_image.sh +++ b/fs_package_docker_image.sh @@ -10,5 +10,5 @@ docker rmi -f api-$name-srv:latest docker build -t api-$name-srv:latest . #把本地镜像load到k8s中(这个适用于无dockerhub镜像仓库情况,需要对应的deployment中的 imagePullPolicy 参数从 Always 变成None) minikube image load api-$name-srv:latest -#上传镜像到dockerhub(有dockerhub镜像仓库后打开,且把上面的load image去掉,对应的deployment中的 imagePullPolicy 参数从 None Always) +#上传镜像到dockerhub(有dockerhub镜像仓库后打开,且把上面的load image去掉,对应的deployment中的 imagePullPolicy 参数从 None 改为 Always) #docker push api-$name-srv:latest \ No newline at end of file From 56acf683938760fc242765417c1f5e8299f6a3a0 Mon Sep 17 00:00:00 2001 From: Hiven Date: Thu, 3 Aug 2023 18:27:52 +0800 Subject: [PATCH 31/60] =?UTF-8?q?fix:=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/inventory/etc/inventory.yaml | 1 + server/inventory/internal/handler/routes.go | 2 +- server/inventory/internal/types/types.go | 6 +++--- server/inventory/inventory_test.go | 12 ++++++++++++ server_api/inventory.api | 8 ++++---- 5 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 server/inventory/inventory_test.go diff --git a/server/inventory/etc/inventory.yaml b/server/inventory/etc/inventory.yaml index a8195506..3633f1b0 100644 --- a/server/inventory/etc/inventory.yaml +++ b/server/inventory/etc/inventory.yaml @@ -1,6 +1,7 @@ Name: inventory Host: 0.0.0.0 Port: 9905 + SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest Auth: AccessSecret: fusen2023 diff --git a/server/inventory/internal/handler/routes.go b/server/inventory/internal/handler/routes.go index 3809a2cb..4368a379 100644 --- a/server/inventory/internal/handler/routes.go +++ b/server/inventory/internal/handler/routes.go @@ -18,7 +18,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Handler: TakeHandler(serverCtx), }, { - Method: http.MethodGet, + Method: http.MethodPost, Path: "/api/inventory/list", Handler: GetCloudListHandler(serverCtx), }, diff --git a/server/inventory/internal/types/types.go b/server/inventory/internal/types/types.go index 480970e8..e31a945f 100644 --- a/server/inventory/internal/types/types.go +++ b/server/inventory/internal/types/types.go @@ -16,9 +16,9 @@ type TakeForm struct { } type GetCloudListReq struct { - Page int `form:"page"` - PageSize int `form:"page_size"` - Size int64 `form:"size"` + Page int `json:"page"` + PageSize int `json:"page_size"` + Size int64 `json:"size"` } type GetCloudListRsp struct { diff --git a/server/inventory/inventory_test.go b/server/inventory/inventory_test.go new file mode 100644 index 00000000..d035c13a --- /dev/null +++ b/server/inventory/inventory_test.go @@ -0,0 +1,12 @@ +package main + +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() +} diff --git a/server_api/inventory.api b/server_api/inventory.api index 33ddd65f..0700842f 100644 --- a/server_api/inventory.api +++ b/server_api/inventory.api @@ -14,7 +14,7 @@ service inventory { post /api/inventory/take(TakeReq) returns (response); //获取云仓库存列表 @handler GetCloudListHandler - get /api/inventory/list(GetCloudListReq) returns (response); + post /api/inventory/list(GetCloudListReq) returns (response); //云仓补货 @handler SupplementHandler post /api/inventory/supplement(SupplementReq) returns (response); @@ -34,9 +34,9 @@ type TakeForm { } //获取云仓库存列表 type GetCloudListReq { - Page int `form:"page"` - PageSize int `form:"page_size"` - Size int64 `form:"size"` + Page int `json:"page"` + PageSize int `json:"page_size"` + Size int64 `json:"size"` } type GetCloudListRsp { WarehouseBoxes int64 `json:"warehouse_boxes"` From 87ff8335bcceda001024538a8284367d7317c360 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 4 Aug 2023 10:35:26 +0800 Subject: [PATCH 32/60] fix --- fs_package_docker_image.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh index 1b9a4ca8..56724690 100755 --- a/fs_package_docker_image.sh +++ b/fs_package_docker_image.sh @@ -9,6 +9,6 @@ docker rmi -f api-$name-srv:latest #打包docker镜像 docker build -t api-$name-srv:latest . #把本地镜像load到k8s中(这个适用于无dockerhub镜像仓库情况,需要对应的deployment中的 imagePullPolicy 参数从 Always 变成None) -minikube image load api-$name-srv:latest +#minikube image load api-$name-srv:latest #上传镜像到dockerhub(有dockerhub镜像仓库后打开,且把上面的load image去掉,对应的deployment中的 imagePullPolicy 参数从 None 改为 Always) #docker push api-$name-srv:latest \ No newline at end of file From c9d832ecded8d22aaddbf4bbcf8f69dbb2367268 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 4 Aug 2023 12:21:30 +0800 Subject: [PATCH 33/60] fix --- fs_package_docker_image.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh index 56724690..422fea30 100755 --- a/fs_package_docker_image.sh +++ b/fs_package_docker_image.sh @@ -6,9 +6,10 @@ cd server/$name CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$name-srv ./$name.go #删除之前旧的镜像 docker rmi -f api-$name-srv:latest +docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen/fusen_docker_hub:latest #打包docker镜像 docker build -t api-$name-srv:latest . -#把本地镜像load到k8s中(这个适用于无dockerhub镜像仓库情况,需要对应的deployment中的 imagePullPolicy 参数从 Always 变成None) -#minikube image load api-$name-srv:latest -#上传镜像到dockerhub(有dockerhub镜像仓库后打开,且把上面的load image去掉,对应的deployment中的 imagePullPolicy 参数从 None 改为 Always) -#docker push api-$name-srv:latest \ No newline at end of file +#打tag(测试环境,正式把fusen-test改成fusen) +docker tag api-$name-srv:latest registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest +#推送到阿里云镜像库(测试环境,正式把fusen-test改成fusen) +docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest \ No newline at end of file From 8b88a78e4ddfefce751ff5bb58b6f6036f4809e5 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 4 Aug 2023 13:25:51 +0800 Subject: [PATCH 34/60] fix --- fs_package_docker_image.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh index 422fea30..d73f11aa 100755 --- a/fs_package_docker_image.sh +++ b/fs_package_docker_image.sh @@ -6,10 +6,10 @@ cd server/$name CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$name-srv ./$name.go #删除之前旧的镜像 docker rmi -f api-$name-srv:latest -docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen/fusen_docker_hub:latest +docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen-test/fusen_docker_hub:latest #打包docker镜像 docker build -t api-$name-srv:latest . -#打tag(测试环境,正式把fusen-test改成fusen) +#打tag(测试环境,正式把命名空间fusen-test改成fusen) docker tag api-$name-srv:latest registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest -#推送到阿里云镜像库(测试环境,正式把fusen-test改成fusen) -docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest \ No newline at end of file +#推送到阿里云镜像库(测试环境,正式把命名空间fusen-test改成fusen) +docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest From 50ef8db377649392a6ed2f223acde9f2a25be35e Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 4 Aug 2023 16:09:05 +0800 Subject: [PATCH 35/60] fix --- fs_package_docker_image.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs_package_docker_image.sh b/fs_package_docker_image.sh index d73f11aa..bb9fe4e5 100755 --- a/fs_package_docker_image.sh +++ b/fs_package_docker_image.sh @@ -9,7 +9,7 @@ docker rmi -f api-$name-srv:latest docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen-test/fusen_docker_hub:latest #打包docker镜像 docker build -t api-$name-srv:latest . -#打tag(测试环境,正式把命名空间fusen-test改成fusen) +#打tag(测试环境,正式把命名空间fusentest改成fusen) docker tag api-$name-srv:latest registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest -#推送到阿里云镜像库(测试环境,正式把命名空间fusen-test改成fusen) +#推送到阿里云镜像库(测试环境,正式把命名空间fusentest改成fusen) docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest From d5a6f780a57d644df8e878f477e75c16b9f55121 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 4 Aug 2023 16:50:01 +0800 Subject: [PATCH 36/60] fix --- server_api/pay.api | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server_api/pay.api b/server_api/pay.api index 4044c1e3..8eb2f508 100644 --- a/server_api/pay.api +++ b/server_api/pay.api @@ -1,8 +1,8 @@ syntax = "v1" info ( - title: 支付模块 - desc: 支付相关 + title: "支付模块" + desc: "支付相关" author: "" email: "" ) From 624b90260f035fe02c98b095afe8ed03ab087875 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Fri, 4 Aug 2023 17:45:36 +0800 Subject: [PATCH 37/60] fix --- initalize/rabbitmq.go | 12 ++++++++++-- server/websocket/consumer/consumer.go | 16 ++++++++++++++++ server/websocket/websocket.go | 8 ++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 server/websocket/consumer/consumer.go diff --git a/initalize/rabbitmq.go b/initalize/rabbitmq.go index 040a3a00..7fd3fd06 100644 --- a/initalize/rabbitmq.go +++ b/initalize/rabbitmq.go @@ -1,9 +1,11 @@ package initalize import ( + "context" "crypto/tls" "errors" "fusenapi/constants" + "fusenapi/server/websocket/consumer" "github.com/streadway/amqp" "github.com/zeromicro/go-zero/core/logx" "log" @@ -82,11 +84,17 @@ func (h *RabbitMqHandle) SendMsg(queueName constants.RABBIT_MQ, message []byte) } // 消费消息 -func (h *RabbitMqHandle) Consume(queueName constants.RABBIT_MQ, handleFunc func(data []byte) error) error { +func (h *RabbitMqHandle) Consume(ctx context.Context, queueName constants.RABBIT_MQ, handle consumer.MqHandle) error { object, ok := mapMq[queueName] if !ok { return errors.New("unknown queue") } + go func() { + select { + case <-ctx.Done(): + panic("err ctx deadline") + } + }() msgs, err := object.ch.Consume( object.queue.Name, // 队列名 object.queue.Name, // 消费者名,如果为空,则是随机生成一个 @@ -115,7 +123,7 @@ func (h *RabbitMqHandle) Consume(queueName constants.RABBIT_MQ, handleFunc func( <-limit wait.Done() }() - if err = handleFunc(m.Body); err != nil { + if err = handle.Run(m.Body); err != nil { logx.Error("failed to deal with MQ message:", string(m.Body)) return } diff --git a/server/websocket/consumer/consumer.go b/server/websocket/consumer/consumer.go new file mode 100644 index 00000000..69363bf0 --- /dev/null +++ b/server/websocket/consumer/consumer.go @@ -0,0 +1,16 @@ +package consumer + +import "fmt" + +type MqHandle interface { + Run(data []byte) error +} + +// 消费渲染结果数据 +type MqConsumerRenderResult struct { +} + +func (m *MqConsumerRenderResult) Run(data []byte) error { + fmt.Println("收到消息:" + string(data)) + return nil +} diff --git a/server/websocket/websocket.go b/server/websocket/websocket.go index b6c469b6..c62fc5ba 100644 --- a/server/websocket/websocket.go +++ b/server/websocket/websocket.go @@ -1,8 +1,11 @@ package main import ( + "context" "flag" "fmt" + "fusenapi/constants" + "fusenapi/server/websocket/consumer" "net/http" "fusenapi/utils/auth" @@ -27,6 +30,11 @@ func main() { defer server.Stop() ctx := svc.NewServiceContext(c) + //消费组装队列 + ctx1 := context.Background() + ctx2, cancel := context.WithCancel(ctx1) + defer cancel() + go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, &consumer.MqConsumerRenderResult{}) handler.RegisterHandlers(server, ctx) fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) server.Start() From a1060823642a696d258360def9421d186e658289 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 10:48:14 +0800 Subject: [PATCH 38/60] fix --- .../internal/logic/datatransferlogic.go | 8 +- .../internal/logic/rendernotifylogic.go | 13 ++-- .../internal/logic/ws_render_image_logic.go | 73 +++++++++---------- server/websocket/internal/types/types.go | 20 ++--- server_api/websocket.api | 20 ++--- 5 files changed, 55 insertions(+), 79 deletions(-) diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index cbd2a0c9..317a93ad 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -3,7 +3,6 @@ package logic import ( "bytes" "encoding/json" - "fmt" "fusenapi/constants" "fusenapi/initalize" "fusenapi/server/websocket/internal/types" @@ -108,7 +107,7 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp inChan: make(chan []byte, 1000), outChan: make(chan []byte, 1000), renderProperty: renderProperty{ - renderImageTask: make(map[string]struct{}), + renderImageTask: make(map[string]string), renderImageTaskCtlChan: make(chan renderImageControlChanItem, 100), }, } @@ -250,11 +249,6 @@ func (w *wsConnectItem) sendToOutChan(data []byte) { } } -// 获取需要渲染图片的map key -func (w *wsConnectItem) getRenderImageMapKey(productId, templateTagId, logoId int64, algorithmVersion string) string { - return fmt.Sprintf("%d-%d-%d-%s", productId, templateTagId, logoId, algorithmVersion) -} - // 格式化返回数据 func (w *wsConnectItem) respondDataFormat(msgType string, data interface{}) []byte { d := types.DataTransferData{ diff --git a/server/websocket/internal/logic/rendernotifylogic.go b/server/websocket/internal/logic/rendernotifylogic.go index 9e5e0c9e..f499157f 100644 --- a/server/websocket/internal/logic/rendernotifylogic.go +++ b/server/websocket/internal/logic/rendernotifylogic.go @@ -61,21 +61,20 @@ func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq) (resp *basi if ws.isClose { return true } - renderKey := ws.getRenderImageMapKey(req.Info.ProductId, req.Info.TemplateTagId, req.Info.LogoId, req.Info.AlgorithmVersion) //查询有无该渲染任务 - _, ok = ws.renderProperty.renderImageTask[renderKey] + renderId, ok := ws.renderProperty.renderImageTask[req.Info.TaskId] if !ok { return true } b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, types.RenderImageRspMsg{ - ProductId: req.Info.ProductId, - TemplateTagId: req.Info.TemplateTagId, - Image: req.Info.Image, + RenderId: renderId, + Image: req.Info.Image, }) //删除对应的需要渲染的图片map ws.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ - Option: 0, //0删除 1添加 - Key: renderKey, + Option: 0, //0删除 1添加 + TaskId: req.Info.TaskId, + RenderId: renderId, } //发送数据到out chan ws.sendToOutChan(b) diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index 7e969d40..3ba3fdd7 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -4,38 +4,21 @@ import ( "encoding/json" "fusenapi/constants" "fusenapi/server/websocket/internal/types" + "fusenapi/utils/hash" "github.com/zeromicro/go-zero/core/logx" ) // 云渲染属性 type renderProperty struct { - renderImageTask map[string]struct{} //需要渲染的图片任务 + renderImageTask map[string]string //需要渲染的图片任务 key是taskId val 是renderId renderImageTaskCtlChan chan renderImageControlChanItem //渲染任务新增移除的控制通道 } // 渲染任务新增移除的控制通道的数据 type renderImageControlChanItem struct { - Option int // 0删除 1添加 - Key string //map的key -} - -// 操作连接中渲染任务的增加/删除 -func (w *wsConnectItem) operationRenderTask() { - for { - select { - case <-w.closeChan: - return - case data := <-w.renderProperty.renderImageTaskCtlChan: - switch data.Option { - case 0: //删除任务 - delete(w.renderProperty.renderImageTask, data.Key) - case 1: //新增任务 - w.renderProperty.renderImageTask[data.Key] = struct{}{} - default: - - } - } - } + Option int // 0删除 1添加 + TaskId string //map的key + RenderId string // map的val } // 渲染请求数据处理发送云渲染服务处理 @@ -48,23 +31,39 @@ func (w *wsConnectItem) SendToCloudRender(data []byte) { } logx.Info("收到请求云渲染图片数据:", renderImageData) //把需要渲染的图片任务加进去 - for _, productId := range renderImageData.ProductIds { - select { - case <-w.closeChan: //连接关闭了 + select { + case <-w.closeChan: //连接关闭了 + return + default: + //加入渲染任务 + taskId := hash.JsonHashKey(renderImageData.RenderData) + w.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ + Option: 1, //0删除 1添加 + TaskId: taskId, + RenderId: renderImageData.RenderId, + } + //发送给对应的流水线组装数据 + if err := w.rabbitMq.SendMsg(constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, data); err != nil { + logx.Error("发送渲染任务数据到MQ失败:", string(data), "err:", err) return - default: - //加入渲染任务 - key := w.getRenderImageMapKey(productId, renderImageData.TemplateTagId, renderImageData.LogoId, renderImageData.AlgorithmVersion) - w.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ - Option: 1, //0删除 1添加 - Key: key, + } + logx.Info("发送渲染数据到rabbitmq成功:", string(data)) + } +} + +// 操作连接中渲染任务的增加/删除 +func (w *wsConnectItem) operationRenderTask() { + for { + select { + case <-w.closeChan: + return + case data := <-w.renderProperty.renderImageTaskCtlChan: + switch data.Option { + case 0: //删除任务 + delete(w.renderProperty.renderImageTask, data.TaskId) + case 1: //新增任务 + w.renderProperty.renderImageTask[data.TaskId] = data.RenderId } - //发送给对应的流水线组装数据 - if err := w.rabbitMq.SendMsg(constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, data); err != nil { - logx.Error("发送渲染任务数据到MQ失败:", string(data), "err:", err) - continue - } - logx.Info("发送渲染数据到rabbitmq成功:", string(data)) } } } diff --git a/server/websocket/internal/types/types.go b/server/websocket/internal/types/types.go index 901b8123..141d7e5e 100644 --- a/server/websocket/internal/types/types.go +++ b/server/websocket/internal/types/types.go @@ -11,18 +11,13 @@ type DataTransferData struct { } type RenderImageReqMsg struct { - ProductIds []int64 `json:"product_ids"` //产品 id - TemplateTagId int64 `json:"template_tag_id"` //模板标签id - LogoId int64 `json:"logo_id"` //logoid - AlgorithmVersion string `json:"algorithm_version,optional"` //算法版本 + RenderId string `json:"render_id"` //渲染id + RenderData interface{} `json:"render_data"` //参数数据 } type RenderImageRspMsg struct { - ProductId int64 `json:"product_id"` //产品 id - TemplateTagId int64 `json:"template_tag_id"` //模板标签id - AlgorithmVersion string `json:"algorithm_version,optional"` //算法版本 - LogoId int64 `json:"logo_id"` //logoid - Image string `json:"image"` //渲染后的图片 + RenderId string `json:"render_id"` //渲染id + Image string `json:"image"` //渲染结果图片 } type ThirdPartyLoginRspMsg struct { @@ -36,11 +31,8 @@ type RenderNotifyReq struct { } type NotifyInfo struct { - ProductId int64 `json:"product_id"` //产品id - TemplateTagId int64 `json:"template_tag_id"` //模板标签id - AlgorithmVersion string `json:"algorithm_version,optional"` //算法版本 - LogoId int64 `json:"logo_id"` //logoid - Image string `json:"image"` + TaskId string `json:"task_id"` //任务id + Image string `json:"image"` } type ThirdPartyLoginNotifyReq struct { diff --git a/server_api/websocket.api b/server_api/websocket.api index e24e2874..254e29a5 100644 --- a/server_api/websocket.api +++ b/server_api/websocket.api @@ -26,17 +26,12 @@ type DataTransferData { D interface{} `json:"d"` //传递的消息 } type RenderImageReqMsg { //websocket接受要云渲染处理的数据 - ProductIds []int64 `json:"product_ids"` //产品 id - TemplateTagId int64 `json:"template_tag_id"` //模板标签id - LogoId int64 `json:"logo_id"` //logoid - AlgorithmVersion string `json:"algorithm_version,optional"` //算法版本 + RenderId string `json:"render_id"` //渲染id + RenderData interface{} `json:"render_data"` //参数数据 } type RenderImageRspMsg { //websocket发送渲染完的数据 - ProductId int64 `json:"product_id"` //产品 id - TemplateTagId int64 `json:"template_tag_id"` //模板标签id - AlgorithmVersion string `json:"algorithm_version,optional"` //算法版本 - LogoId int64 `json:"logo_id"` //logoid - Image string `json:"image"` //渲染后的图片 + RenderId string `json:"render_id"` //渲染id + Image string `json:"image"` //渲染结果图片 } type ThirdPartyLoginRspMsg { //websocket三方登录的通知数据 Token string `json:"token"` @@ -48,11 +43,8 @@ type RenderNotifyReq { Info NotifyInfo `json:"info"` } type NotifyInfo { - ProductId int64 `json:"product_id"` //产品id - TemplateTagId int64 `json:"template_tag_id"` //模板标签id - AlgorithmVersion string `json:"algorithm_version,optional"` //算法版本 - LogoId int64 `json:"logo_id"` //logoid - Image string `json:"image"` + TaskId string `json:"task_id"` //任务id + Image string `json:"image"` } //第三方登录通知接口 type ThirdPartyLoginNotifyReq { From 8e4e1c1cfd18ff0b89c2e8c7005f7e55a5aed591 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 11:15:51 +0800 Subject: [PATCH 39/60] fix --- constants/websocket.go | 2 + .../internal/logic/datatransferlogic.go | 6 +-- .../internal/logic/ws_render_image_logic.go | 42 ++++++++++--------- server/websocket/websocket.go | 4 +- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/constants/websocket.go b/constants/websocket.go index 34e28eb7..be28eb32 100644 --- a/constants/websocket.go +++ b/constants/websocket.go @@ -8,6 +8,8 @@ const ( WEBSOCKET_UNAUTH = "WEBSOCKET_UNAUTH" //ws连接成功 WEBSOCKET_CONNECT_SUCCESS = "WEBSOCKET_CONNECT_SUCCESS" + //渲染前数据组装 + WEBSOCKET_RENDER_IMAGE_ASSEMBLE = "WEBSOCKET_RENDER_IMAGE_ASSEMBLE" //图片渲染 WEBSOCKET_RENDER_IMAGE = "WEBSOCKET_RENDER_IMAGE" //数据格式错误 diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index 317a93ad..1865300d 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -270,9 +270,9 @@ func (w *wsConnectItem) dealwithReciveData(data []byte) { d, _ := json.Marshal(parseInfo.D) //分消息类型给到不同逻辑处理,可扩展 switch parseInfo.T { - //图片渲染 - case constants.WEBSOCKET_RENDER_IMAGE: - w.SendToCloudRender(d) + //图片渲染数据组装 + case constants.WEBSOCKET_RENDER_IMAGE_ASSEMBLE: + w.assembleRenderData(d) default: } diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index 3ba3fdd7..ca93a6c7 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -21,8 +21,13 @@ type renderImageControlChanItem struct { RenderId string // map的val } -// 渲染请求数据处理发送云渲染服务处理 -func (w *wsConnectItem) SendToCloudRender(data []byte) { +// 渲染发送到组装数据组装数据 +type assembleRenderData struct { + TaskId string `json:"task_id"` + RenderData interface{} `json:"render_data"` +} + +func (w *wsConnectItem) assembleRenderData(data []byte) { var renderImageData types.RenderImageReqMsg if err := json.Unmarshal(data, &renderImageData); err != nil { w.outChan <- w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "invalid format of websocket render image message:"+string(data)) @@ -31,24 +36,23 @@ func (w *wsConnectItem) SendToCloudRender(data []byte) { } logx.Info("收到请求云渲染图片数据:", renderImageData) //把需要渲染的图片任务加进去 - select { - case <-w.closeChan: //连接关闭了 - return - default: - //加入渲染任务 - taskId := hash.JsonHashKey(renderImageData.RenderData) - w.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ - Option: 1, //0删除 1添加 - TaskId: taskId, - RenderId: renderImageData.RenderId, - } - //发送给对应的流水线组装数据 - if err := w.rabbitMq.SendMsg(constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, data); err != nil { - logx.Error("发送渲染任务数据到MQ失败:", string(data), "err:", err) - return - } - logx.Info("发送渲染数据到rabbitmq成功:", string(data)) + taskId := hash.JsonHashKey(renderImageData.RenderData) + w.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ + Option: 1, //0删除 1添加 + TaskId: taskId, + RenderId: renderImageData.RenderId, } + tmpData := assembleRenderData{ + TaskId: taskId, + 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(data), "err:", err) + return + } + logx.Info("发送渲染数据到rabbitmq成功:", string(data)) } // 操作连接中渲染任务的增加/删除 diff --git a/server/websocket/websocket.go b/server/websocket/websocket.go index c62fc5ba..01a9efb8 100644 --- a/server/websocket/websocket.go +++ b/server/websocket/websocket.go @@ -30,11 +30,11 @@ func main() { defer server.Stop() ctx := svc.NewServiceContext(c) - //消费组装队列 + //消费渲染结果队列 ctx1 := context.Background() ctx2, cancel := context.WithCancel(ctx1) defer cancel() - go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, &consumer.MqConsumerRenderResult{}) + go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_RENDER_RESULT_DATA, &consumer.MqConsumerRenderResult{}) handler.RegisterHandlers(server, ctx) fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) server.Start() From 36efad44dfc25c8330a3763dda8744cf2472f57a Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 11:25:06 +0800 Subject: [PATCH 40/60] fix --- .../internal/logic/datatransferlogic.go | 6 +++--- .../internal/logic/rendernotifylogic.go | 3 ++- .../logic/thirdpartyloginnotifylogic.go | 3 ++- .../internal/logic/ws_render_image_logic.go | 4 ++-- server/websocket/internal/types/types.go | 19 ----------------- server_api/websocket.api | 16 -------------- utils/websocket_data/render_data.go | 21 +++++++++++++++++++ 7 files changed, 30 insertions(+), 42 deletions(-) create mode 100644 utils/websocket_data/render_data.go diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index 1865300d..ab215c78 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -5,9 +5,9 @@ import ( "encoding/json" "fusenapi/constants" "fusenapi/initalize" - "fusenapi/server/websocket/internal/types" "fusenapi/utils/auth" "fusenapi/utils/id_generator" + "fusenapi/utils/websocket_data" "github.com/gorilla/websocket" "net/http" "sync" @@ -251,7 +251,7 @@ func (w *wsConnectItem) sendToOutChan(data []byte) { // 格式化返回数据 func (w *wsConnectItem) respondDataFormat(msgType string, data interface{}) []byte { - d := types.DataTransferData{ + d := websocket_data.DataTransferData{ T: msgType, D: data, } @@ -261,7 +261,7 @@ func (w *wsConnectItem) respondDataFormat(msgType string, data interface{}) []by // 处理接受到的数据 func (w *wsConnectItem) dealwithReciveData(data []byte) { - var parseInfo types.DataTransferData + var parseInfo websocket_data.DataTransferData if err := json.Unmarshal(data, &parseInfo); err != nil { logx.Error("invalid format of websocket message") w.outChan <- w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "invalid format of websocket message:"+string(data)) diff --git a/server/websocket/internal/logic/rendernotifylogic.go b/server/websocket/internal/logic/rendernotifylogic.go index f499157f..27b2002d 100644 --- a/server/websocket/internal/logic/rendernotifylogic.go +++ b/server/websocket/internal/logic/rendernotifylogic.go @@ -3,6 +3,7 @@ package logic import ( "fusenapi/constants" "fusenapi/utils/basic" + "fusenapi/utils/websocket_data" "time" "context" @@ -66,7 +67,7 @@ func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq) (resp *basi if !ok { return true } - b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, types.RenderImageRspMsg{ + b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{ RenderId: renderId, Image: req.Info.Image, }) diff --git a/server/websocket/internal/logic/thirdpartyloginnotifylogic.go b/server/websocket/internal/logic/thirdpartyloginnotifylogic.go index d363ffd9..d3639a95 100644 --- a/server/websocket/internal/logic/thirdpartyloginnotifylogic.go +++ b/server/websocket/internal/logic/thirdpartyloginnotifylogic.go @@ -4,6 +4,7 @@ import ( "fusenapi/constants" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/websocket_data" "time" "context" @@ -66,7 +67,7 @@ func (l *ThirdPartyLoginNotifyLogic) ThirdPartyLoginNotify(req *types.ThirdParty if !ok { return resp.SetStatusWithMessage(basic.CodeServiceErr, "type of websocket connect object is err") } - b := ws.respondDataFormat(constants.WEBSOCKET_THIRD_PARTY_LOGIN_NOTIFY, types.ThirdPartyLoginRspMsg{ + b := ws.respondDataFormat(constants.WEBSOCKET_THIRD_PARTY_LOGIN_NOTIFY, websocket_data.ThirdPartyLoginRspMsg{ Token: req.Info.Token, }) select { diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index ca93a6c7..5be69551 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -3,8 +3,8 @@ package logic import ( "encoding/json" "fusenapi/constants" - "fusenapi/server/websocket/internal/types" "fusenapi/utils/hash" + "fusenapi/utils/websocket_data" "github.com/zeromicro/go-zero/core/logx" ) @@ -28,7 +28,7 @@ type assembleRenderData struct { } func (w *wsConnectItem) assembleRenderData(data []byte) { - var renderImageData types.RenderImageReqMsg + var renderImageData websocket_data.RenderImageReqMsg if err := json.Unmarshal(data, &renderImageData); err != nil { w.outChan <- w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "invalid format of websocket render image message:"+string(data)) logx.Error("invalid format of websocket render image message", err) diff --git a/server/websocket/internal/types/types.go b/server/websocket/internal/types/types.go index 141d7e5e..67d38865 100644 --- a/server/websocket/internal/types/types.go +++ b/server/websocket/internal/types/types.go @@ -5,25 +5,6 @@ import ( "fusenapi/utils/basic" ) -type DataTransferData struct { - T string `json:"t"` //消息类型 - D interface{} `json:"d"` //传递的消息 -} - -type RenderImageReqMsg struct { - RenderId string `json:"render_id"` //渲染id - RenderData interface{} `json:"render_data"` //参数数据 -} - -type RenderImageRspMsg struct { - RenderId string `json:"render_id"` //渲染id - Image string `json:"image"` //渲染结果图片 -} - -type ThirdPartyLoginRspMsg struct { - Token string `json:"token"` -} - type RenderNotifyReq struct { Sign string `json:"sign"` Time int64 `json:"time"` diff --git a/server_api/websocket.api b/server_api/websocket.api index 254e29a5..22104825 100644 --- a/server_api/websocket.api +++ b/server_api/websocket.api @@ -20,22 +20,6 @@ service websocket { post /api/websocket/third_party_login_notify(ThirdPartyLoginNotifyReq) returns (response); } -//websocket数据交互 -type DataTransferData { - T string `json:"t"` //消息类型 - D interface{} `json:"d"` //传递的消息 -} -type RenderImageReqMsg { //websocket接受要云渲染处理的数据 - RenderId string `json:"render_id"` //渲染id - RenderData interface{} `json:"render_data"` //参数数据 -} -type RenderImageRspMsg { //websocket发送渲染完的数据 - RenderId string `json:"render_id"` //渲染id - Image string `json:"image"` //渲染结果图片 -} -type ThirdPartyLoginRspMsg { //websocket三方登录的通知数据 - Token string `json:"token"` -} //渲染完了通知接口 type RenderNotifyReq { Sign string `json:"sign"` diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go new file mode 100644 index 00000000..2e6c6a9e --- /dev/null +++ b/utils/websocket_data/render_data.go @@ -0,0 +1,21 @@ +package websocket_data + +// websocket数据交互 +type DataTransferData struct { + T string `json:"t"` //消息类型 + D interface{} `json:"d"` //传递的消息 +} +type RenderImageReqMsg struct { + //websocket接受要云渲染处理的数据 + RenderId string `json:"render_id"` //渲染id + RenderData interface{} `json:"render_data"` //参数数据 +} +type RenderImageRspMsg struct { + //websocket发送渲染完的数据 + RenderId string `json:"render_id"` //渲染id + Image string `json:"image"` //渲染结果图片 +} +type ThirdPartyLoginRspMsg struct { + //websocket三方登录的通知数据 + Token string `json:"token"` +} From 39fe427f8e46c924e46ea2b48f442dd449afc07b Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 11:34:22 +0800 Subject: [PATCH 41/60] =?UTF-8?q?fix:=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0-?= =?UTF-8?q?-base64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/upload/internal/handler/routes.go | 5 + .../internal/handler/uploadfilebasehandler.go | 35 ++++ .../internal/logic/uploadfilebaselogic.go | 156 ++++++++++++++++++ .../internal/logic/uploadfilesbackendlogic.go | 8 +- server/upload/internal/types/types.go | 10 ++ server_api/upload.api | 16 ++ 6 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 server/upload/internal/handler/uploadfilebasehandler.go create mode 100644 server/upload/internal/logic/uploadfilebaselogic.go diff --git a/server/upload/internal/handler/routes.go b/server/upload/internal/handler/routes.go index 8d5b0aa0..e33dc5a8 100644 --- a/server/upload/internal/handler/routes.go +++ b/server/upload/internal/handler/routes.go @@ -52,6 +52,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/upload/up-logo", Handler: UploadLogoHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/upload/upload-file-base", + Handler: UploadFileBaseHandler(serverCtx), + }, }, ) } diff --git a/server/upload/internal/handler/uploadfilebasehandler.go b/server/upload/internal/handler/uploadfilebasehandler.go new file mode 100644 index 00000000..21c9e02f --- /dev/null +++ b/server/upload/internal/handler/uploadfilebasehandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/upload/internal/logic" + "fusenapi/server/upload/internal/svc" + "fusenapi/server/upload/internal/types" +) + +func UploadFileBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.UploadFileBaseReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewUploadFileBaseLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.UploadFileBase(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/upload/internal/logic/uploadfilebaselogic.go b/server/upload/internal/logic/uploadfilebaselogic.go new file mode 100644 index 00000000..28a8ae1c --- /dev/null +++ b/server/upload/internal/logic/uploadfilebaselogic.go @@ -0,0 +1,156 @@ +package logic + +import ( + "encoding/base64" + "fmt" + "fusenapi/model/gmodel" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "fusenapi/utils/hash" + "strings" + "time" + + "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" +) + +type UploadFileBaseLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUploadFileBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadFileBaseLogic { + return &UploadFileBaseLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *UploadFileBaseLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *UploadFileBaseLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + // 定义用户ID和S3键名格式 + var uid int64 + var userId int64 + var guestId int64 + + // 检查用户是否是游客 + if userinfo.IsGuest() { + // 如果是,使用游客ID和游客键名格式 + guestId = userinfo.GuestId + uid = guestId + } else { + // 否则,使用用户ID和用户键名格式 + userId = userinfo.UserId + uid = userId + } + + guestId = req.GuestId + userId = req.UserId + + // 定义存储桶名称 + var bucketName *string + var apiType int64 = 2 + + // 根据类别选择存储桶 + switch req.UploadBucket { + case 2: + bucketName = basic.TempfileBucketName + default: + bucketName = basic.StorageBucketName + } + + // 设置AWS会话的区域 + l.svcCtx.AwsSession.Config.Region = aws.String("us-west-1") + + // 创建新的S3服务实例 + svc := s3.New(l.svcCtx.AwsSession) + + // 定义S3请求和当前时间 + var s3req *request.Request + + var resourceId string = hash.JsonHashKey(fmt.Sprintf("%s%d", req.FileKey, uid)) + + var uploadUrl = UploadUrl{} + resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) + resourceInfo, err := resourceModel.FindOneById(l.ctx, resourceId) + if err == nil && resourceInfo.ResourceId != "" { + uploadUrl.Status = 1 + uploadUrl.ResourceId = resourceId + uploadUrl.ResourceUrl = *resourceInfo.ResourceUrl + } else { + RBase64Point := strings.LastIndex(req.FileData, ";base64,") + 8 + req.FileData = req.FileData[RBase64Point:] + dist, err := base64.StdEncoding.DecodeString(req.FileData) + + if err != nil { + logx.Error(err) + } + + // 创建S3对象存储请求 + s3req, _ = svc.PutObjectRequest( + &s3.PutObjectInput{ + Bucket: bucketName, + Key: &resourceId, + }, + ) + + // 设置请求体为文件数据 + s3req.SetBufferBody(dist) + + // 发送请求 + err = s3req.Send() + + // 检查是否有错误 + if err != nil { + logx.Error(err) + uploadUrl.Status = 0 + } else { + var url = s3req.HTTPRequest.URL.String() + // 打印请求URL + logx.Info(url) + uploadUrl.Status = 1 + uploadUrl.ResourceId = resourceId + uploadUrl.ResourceUrl = url + var version string = "0.0.1" + var nowTime = time.Now() + _, err = resourceModel.Create(l.ctx, &gmodel.FsResource{ + ResourceId: resourceId, + UserId: &userId, + GuestId: &guestId, + ResourceType: &req.FileType, + ResourceUrl: &url, + Version: &version, + UploadedAt: &nowTime, + Metadata: &req.Metadata, + ApiType: &apiType, + }) + if err != nil { + logx.Error(err) + } + } + } + + // 返回成功的响应和上传URL + return resp.SetStatus(basic.CodeOK, map[string]interface{}{ + "upload_data": uploadUrl, + }) +} diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index 74a7ba00..9d30f2ae 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -233,9 +233,11 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, } type UploadInfo struct { - FileSize int64 `json:"file_size"` // 上传唯一标识信息 - FileKeys string `json:"file_keys"` // 上传唯一标识信息 - Metadata string `json:"meta_data"` // 上传文件额外信息 + FileSize int64 `json:"file_size"` // 上传文件大小 + FileKeys string `json:"file_keys"` // 上传文件唯一标识 + FileData *string `json:"file_data"` // 上传文件Base64 + Metadata string `json:"meta_data"` // 上传文件额外信息 + } type UploadData struct { diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index 8373d29c..c967bf42 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -5,6 +5,16 @@ import ( "fusenapi/utils/basic" ) +type UploadFileBaseReq struct { + FileType string `form:"file_type"` // 上传文件类型 + FileKey string `form:"file_key"` // 上传唯一标识信息 + FileData string `form:"file_data"` // 上传文件额外信息 + Metadata string `form:"meta_data,optional"` // 上传文件额外信息 + UserId int64 `form:"user_id,optional"` // 上传文件额外信息 + GuestId int64 `form:"guest_id,optional"` // 上传文件额外信息 + UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 +} + type UploadLogoReq struct { ResourceId string `form:"resource_id"` // 资源ID ResourceUrl string `form:"resource_url"` // 资源URL diff --git a/server_api/upload.api b/server_api/upload.api index 5524fead..a94830be 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -38,8 +38,24 @@ service upload { @handler UploadLogoHandler post /api/upload/up-logo(UploadLogoReq) returns (response); + // 上传文件发起--base64 + @handler UploadFileBaseHandler + post /api/upload/upload-file-base(UploadFileBaseReq) returns (response); + } +type ( + UploadFileBaseReq { + FileType string `form:"file_type"` // 上传文件类型 + FileKey string `form:"file_key"` // 上传唯一标识信息 + FileData string `form:"file_data"` // 上传文件额外信息 + Metadata string `form:"meta_data,optional"` // 上传文件额外信息 + UserId int64 `form:"user_id,optional"` // 上传文件额外信息 + GuestId int64 `form:"guest_id,optional"` // 上传文件额外信息 + UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 + } +) + type ( UploadLogoReq { ResourceId string `form:"resource_id"` // 资源ID From 315ad19dd4afb5c4c75498334d99db4c793f1235 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 11:44:54 +0800 Subject: [PATCH 42/60] fix --- initalize/rabbitmq.go | 7 +++---- server/render/consumer/assemble_render_data.go | 12 ++++++++++++ server/render/etc/render.yaml | 3 ++- server/render/internal/config/config.go | 6 +++--- server/render/internal/svc/servicecontext.go | 4 +++- server/render/render.go | 9 ++++++++- server/websocket/consumer/consumer.go | 4 ---- utils/mq_consumer_factory/mq.go | 6 ++++++ 8 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 server/render/consumer/assemble_render_data.go create mode 100644 utils/mq_consumer_factory/mq.go diff --git a/initalize/rabbitmq.go b/initalize/rabbitmq.go index 7fd3fd06..004524c0 100644 --- a/initalize/rabbitmq.go +++ b/initalize/rabbitmq.go @@ -5,7 +5,7 @@ import ( "crypto/tls" "errors" "fusenapi/constants" - "fusenapi/server/websocket/consumer" + "fusenapi/utils/mq_consumer_factory" "github.com/streadway/amqp" "github.com/zeromicro/go-zero/core/logx" "log" @@ -84,10 +84,10 @@ func (h *RabbitMqHandle) SendMsg(queueName constants.RABBIT_MQ, message []byte) } // 消费消息 -func (h *RabbitMqHandle) Consume(ctx context.Context, queueName constants.RABBIT_MQ, handle consumer.MqHandle) error { +func (h *RabbitMqHandle) Consume(ctx context.Context, queueName constants.RABBIT_MQ, handle mq_consumer_factory.MqHandle) { object, ok := mapMq[queueName] if !ok { - return errors.New("unknown queue") + panic("unknown queue") } go func() { select { @@ -135,5 +135,4 @@ func (h *RabbitMqHandle) Consume(ctx context.Context, queueName constants.RABBIT }(msg) } wait.Wait() - return nil } diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go new file mode 100644 index 00000000..9f3b6187 --- /dev/null +++ b/server/render/consumer/assemble_render_data.go @@ -0,0 +1,12 @@ +package consumer + +import "fmt" + +// 消费渲染需要组装的数据 +type MqConsumerRenderAssemble struct { +} + +func (m *MqConsumerRenderAssemble) Run(data []byte) error { + fmt.Println("收到消息:" + string(data)) + return nil +} diff --git a/server/render/etc/render.yaml b/server/render/etc/render.yaml index 2dba7dc7..30b4cdd7 100644 --- a/server/render/etc/render.yaml +++ b/server/render/etc/render.yaml @@ -5,4 +5,5 @@ SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest Auth: AccessSecret: fusen2023 AccessExpire: 2592000 - RefreshAfter: 1592000 \ No newline at end of file + RefreshAfter: 1592000 +SourceRabbitMq: amqp://rabbit001:rabbit001129@110.41.19.98:5672 \ No newline at end of file diff --git a/server/render/internal/config/config.go b/server/render/internal/config/config.go index 5f9c4816..fa950a01 100644 --- a/server/render/internal/config/config.go +++ b/server/render/internal/config/config.go @@ -2,12 +2,12 @@ package config import ( "fusenapi/server/render/internal/types" - "github.com/zeromicro/go-zero/rest" ) type Config struct { rest.RestConf - SourceMysql string - Auth types.Auth + SourceMysql string + Auth types.Auth + SourceRabbitMq string } diff --git a/server/render/internal/svc/servicecontext.go b/server/render/internal/svc/servicecontext.go index bd083461..79e04e0d 100644 --- a/server/render/internal/svc/servicecontext.go +++ b/server/render/internal/svc/servicecontext.go @@ -18,14 +18,16 @@ type ServiceContext struct { MysqlConn *gorm.DB AllModels *gmodel.AllModelsGen + RabbitMq *initalize.RabbitMqHandle } func NewServiceContext(c config.Config) *ServiceContext { - + initalize.InitRabbitMq(c.SourceRabbitMq, nil) return &ServiceContext{ Config: c, MysqlConn: initalize.InitMysql(c.SourceMysql), AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)), + RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil), } } diff --git a/server/render/render.go b/server/render/render.go index af3b93f1..2c052f37 100644 --- a/server/render/render.go +++ b/server/render/render.go @@ -1,8 +1,11 @@ package main import ( + "context" "flag" "fmt" + "fusenapi/constants" + "fusenapi/server/render/consumer" "net/http" "time" @@ -30,7 +33,11 @@ func main() { ctx := svc.NewServiceContext(c) handler.RegisterHandlers(server, ctx) - + //消费渲染前组装数据队列 + ctx1 := context.Background() + ctx2, cancel := context.WithCancel(ctx1) + defer cancel() + go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_ASSEMBLE_RENDER_DATA, &consumer.MqConsumerRenderAssemble{}) fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) server.Start() } diff --git a/server/websocket/consumer/consumer.go b/server/websocket/consumer/consumer.go index 69363bf0..16a7c8a9 100644 --- a/server/websocket/consumer/consumer.go +++ b/server/websocket/consumer/consumer.go @@ -2,10 +2,6 @@ package consumer import "fmt" -type MqHandle interface { - Run(data []byte) error -} - // 消费渲染结果数据 type MqConsumerRenderResult struct { } diff --git a/utils/mq_consumer_factory/mq.go b/utils/mq_consumer_factory/mq.go new file mode 100644 index 00000000..0f3bc97d --- /dev/null +++ b/utils/mq_consumer_factory/mq.go @@ -0,0 +1,6 @@ +package mq_consumer_factory + +// 消费mq消息要实现对应Run方法 +type MqHandle interface { + Run(data []byte) error +} From 31eb49efa305b35252833990af38f9ca2b2fc659 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 11:49:17 +0800 Subject: [PATCH 43/60] fix --- server/render/render.go | 2 +- server/websocket/internal/logic/ws_render_image_logic.go | 7 +------ utils/websocket_data/render_data.go | 6 ++++++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/server/render/render.go b/server/render/render.go index 2c052f37..1210715d 100644 --- a/server/render/render.go +++ b/server/render/render.go @@ -32,12 +32,12 @@ func main() { defer server.Stop() ctx := svc.NewServiceContext(c) - handler.RegisterHandlers(server, ctx) //消费渲染前组装数据队列 ctx1 := context.Background() ctx2, cancel := context.WithCancel(ctx1) 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() } diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index 5be69551..e4881bba 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -22,11 +22,6 @@ type renderImageControlChanItem struct { } // 渲染发送到组装数据组装数据 -type assembleRenderData struct { - TaskId string `json:"task_id"` - RenderData interface{} `json:"render_data"` -} - func (w *wsConnectItem) assembleRenderData(data []byte) { var renderImageData websocket_data.RenderImageReqMsg if err := json.Unmarshal(data, &renderImageData); err != nil { @@ -42,7 +37,7 @@ func (w *wsConnectItem) assembleRenderData(data []byte) { TaskId: taskId, RenderId: renderImageData.RenderId, } - tmpData := assembleRenderData{ + tmpData := websocket_data.AssembleRenderData{ TaskId: taskId, RenderData: renderImageData.RenderData, } diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go index 2e6c6a9e..3ec0067a 100644 --- a/utils/websocket_data/render_data.go +++ b/utils/websocket_data/render_data.go @@ -19,3 +19,9 @@ type ThirdPartyLoginRspMsg struct { //websocket三方登录的通知数据 Token string `json:"token"` } + +// 发送到渲染组装的mq数据 +type AssembleRenderData struct { + TaskId string `json:"task_id"` + RenderData interface{} `json:"render_data"` +} From 3d82709b7e35b18cefaa3a38f9e0c82ee59a97cb Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 12:02:11 +0800 Subject: [PATCH 44/60] =?UTF-8?q?fix:=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0-?= =?UTF-8?q?-base64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/logic/uploadfilebaselogic.go | 8 +++----- utils/file/base64.go | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 utils/file/base64.go diff --git a/server/upload/internal/logic/uploadfilebaselogic.go b/server/upload/internal/logic/uploadfilebaselogic.go index 28a8ae1c..46c210c0 100644 --- a/server/upload/internal/logic/uploadfilebaselogic.go +++ b/server/upload/internal/logic/uploadfilebaselogic.go @@ -1,13 +1,12 @@ package logic import ( - "encoding/base64" "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" + "fusenapi/utils/file" "fusenapi/utils/hash" - "strings" "time" "context" @@ -97,12 +96,11 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri uploadUrl.ResourceId = resourceId uploadUrl.ResourceUrl = *resourceInfo.ResourceUrl } else { - RBase64Point := strings.LastIndex(req.FileData, ";base64,") + 8 - req.FileData = req.FileData[RBase64Point:] - dist, err := base64.StdEncoding.DecodeString(req.FileData) + dist, err := file.FileBase64ToByte(req.FileData) if err != nil { logx.Error(err) + return resp.SetStatus(basic.CodeFileUploadErr, "file upload err,base64tobyte error") } // 创建S3对象存储请求 diff --git a/utils/file/base64.go b/utils/file/base64.go new file mode 100644 index 00000000..84825501 --- /dev/null +++ b/utils/file/base64.go @@ -0,0 +1,17 @@ +package file + +import ( + "encoding/base64" + "strings" +) + +func FileBase64ToByte(fileData string) ([]byte, error) { + RBase64Point := strings.LastIndex(fileData, ";base64,") + 8 + fileDataStr := fileData[RBase64Point:] + dist, err := base64.StdEncoding.DecodeString(fileDataStr) + + if err != nil { + return nil, err + } + return dist, nil +} From 7510b363d6e985e9d8c85ffb7f270acf67eadc5e Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 12:31:31 +0800 Subject: [PATCH 45/60] fix --- .../render/consumer/assemble_render_data.go | 2 +- ...mageshandler.go => rendernotifyhandler.go} | 8 +- server/render/internal/handler/routes.go | 11 +-- .../render/internal/handler/tounityhandler.go | 35 -------- .../render/internal/logic/readimageslogic.go | 42 ---------- .../internal/logic/rendernotifylogic.go | 47 ++++------- server/render/internal/logic/tounitylogic.go | 42 ---------- server/render/internal/types/types.go | 11 +++ server/websocket/consumer/consumer.go | 12 --- .../internal/handler/rendernotifyhandler.go | 31 -------- server/websocket/internal/handler/routes.go | 10 --- .../handler/thirdpartyloginnotifyhandler.go | 35 -------- .../websocket/internal/logic/mq_consumer.go | 52 ++++++++++++ .../logic/thirdpartyloginnotifylogic.go | 79 ------------------- server/websocket/internal/types/types.go | 22 ------ server/websocket/websocket.go | 4 +- server_api/render.api | 20 +++-- server_api/websocket.api | 27 ------- utils/websocket_data/render_data.go | 12 ++- 19 files changed, 111 insertions(+), 391 deletions(-) rename server/render/internal/handler/{readimageshandler.go => rendernotifyhandler.go} (72%) delete mode 100644 server/render/internal/handler/tounityhandler.go delete mode 100644 server/render/internal/logic/readimageslogic.go rename server/{websocket => render}/internal/logic/rendernotifylogic.go (61%) delete mode 100644 server/render/internal/logic/tounitylogic.go delete mode 100644 server/websocket/consumer/consumer.go delete mode 100644 server/websocket/internal/handler/rendernotifyhandler.go delete mode 100644 server/websocket/internal/handler/thirdpartyloginnotifyhandler.go create mode 100644 server/websocket/internal/logic/mq_consumer.go delete mode 100644 server/websocket/internal/logic/thirdpartyloginnotifylogic.go diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go index 9f3b6187..78aa193e 100644 --- a/server/render/consumer/assemble_render_data.go +++ b/server/render/consumer/assemble_render_data.go @@ -7,6 +7,6 @@ type MqConsumerRenderAssemble struct { } func (m *MqConsumerRenderAssemble) Run(data []byte) error { - fmt.Println("收到消息:" + string(data)) + fmt.Println("收到需要组装的消息:" + string(data)) return nil } diff --git a/server/render/internal/handler/readimageshandler.go b/server/render/internal/handler/rendernotifyhandler.go similarity index 72% rename from server/render/internal/handler/readimageshandler.go rename to server/render/internal/handler/rendernotifyhandler.go index 4156ab0f..a8d01c9c 100644 --- a/server/render/internal/handler/readimageshandler.go +++ b/server/render/internal/handler/rendernotifyhandler.go @@ -11,22 +11,22 @@ import ( "fusenapi/server/render/internal/types" ) -func ReadImagesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { +func RenderNotifyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req types.RequestReadImages + var req types.RenderNotifyReq userinfo, err := basic.RequestParse(w, r, svcCtx, &req) if err != nil { return } // 创建一个业务逻辑层实例 - l := logic.NewReadImagesLogic(r.Context(), svcCtx) + l := logic.NewRenderNotifyLogic(r.Context(), svcCtx) rl := reflect.ValueOf(l) basic.BeforeLogic(w, r, rl) - resp := l.ReadImages(&req, userinfo) + resp := l.RenderNotify(&req, userinfo) if !basic.AfterLogic(w, r, rl, resp) { basic.NormalAfterLogic(w, r, resp) diff --git a/server/render/internal/handler/routes.go b/server/render/internal/handler/routes.go index 46f97be9..0bbf0d3e 100644 --- a/server/render/internal/handler/routes.go +++ b/server/render/internal/handler/routes.go @@ -13,14 +13,9 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { server.AddRoutes( []rest.Route{ { - Method: http.MethodGet, - Path: "/api/render/to-unity", - Handler: ToUnityHandler(serverCtx), - }, - { - Method: http.MethodGet, - Path: "/api/render/read-images", - Handler: ReadImagesHandler(serverCtx), + Method: http.MethodPost, + Path: "/api/render/render_notify", + Handler: RenderNotifyHandler(serverCtx), }, }, ) diff --git a/server/render/internal/handler/tounityhandler.go b/server/render/internal/handler/tounityhandler.go deleted file mode 100644 index 80191459..00000000 --- a/server/render/internal/handler/tounityhandler.go +++ /dev/null @@ -1,35 +0,0 @@ -package handler - -import ( - "net/http" - "reflect" - - "fusenapi/utils/basic" - - "fusenapi/server/render/internal/logic" - "fusenapi/server/render/internal/svc" - "fusenapi/server/render/internal/types" -) - -func ToUnityHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - var req types.RequestToUnity - userinfo, err := basic.RequestParse(w, r, svcCtx, &req) - if err != nil { - return - } - - // 创建一个业务逻辑层实例 - l := logic.NewToUnityLogic(r.Context(), svcCtx) - - rl := reflect.ValueOf(l) - basic.BeforeLogic(w, r, rl) - - resp := l.ToUnity(&req, userinfo) - - if !basic.AfterLogic(w, r, rl, resp) { - basic.NormalAfterLogic(w, r, resp) - } - } -} diff --git a/server/render/internal/logic/readimageslogic.go b/server/render/internal/logic/readimageslogic.go deleted file mode 100644 index e7d36441..00000000 --- a/server/render/internal/logic/readimageslogic.go +++ /dev/null @@ -1,42 +0,0 @@ -package logic - -import ( - "fusenapi/utils/auth" - "fusenapi/utils/basic" - - "context" - - "fusenapi/server/render/internal/svc" - "fusenapi/server/render/internal/types" - - "github.com/zeromicro/go-zero/core/logx" -) - -type ReadImagesLogic struct { - logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext -} - -func NewReadImagesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ReadImagesLogic { - return &ReadImagesLogic{ - Logger: logx.WithContext(ctx), - ctx: ctx, - svcCtx: svcCtx, - } -} - -// 处理进入前逻辑w,r -// func (l *ReadImagesLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { -// } - -// 处理逻辑后 w,r 如:重定向 -// func (l *ReadImagesLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { -// } - -func (l *ReadImagesLogic) ReadImages(req *types.RequestReadImages, userinfo *auth.UserInfo) (resp *basic.Response) { - // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) - // userinfo 传入值时, 一定不为null - - return resp.SetStatus(basic.CodeOK) -} diff --git a/server/websocket/internal/logic/rendernotifylogic.go b/server/render/internal/logic/rendernotifylogic.go similarity index 61% rename from server/websocket/internal/logic/rendernotifylogic.go rename to server/render/internal/logic/rendernotifylogic.go index 27b2002d..aa735d6d 100644 --- a/server/websocket/internal/logic/rendernotifylogic.go +++ b/server/render/internal/logic/rendernotifylogic.go @@ -1,15 +1,17 @@ package logic import ( + "encoding/json" "fusenapi/constants" + "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/websocket_data" "time" "context" - "fusenapi/server/websocket/internal/svc" - "fusenapi/server/websocket/internal/types" + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" "github.com/zeromicro/go-zero/core/logx" ) @@ -37,7 +39,7 @@ func NewRenderNotifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Rend // // httpx.OkJsonCtx(r.Context(), w, resp) // } -func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq) (resp *basic.Response) { +func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq, userinfo *auth.UserInfo) (resp *basic.Response) { if time.Now().Unix()-120 > req.Time /*|| req.Time > time.Now().Unix() */ { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param time") } @@ -51,35 +53,14 @@ func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq) (resp *basi if req.Sign != sign { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid sign") }*/ - //遍历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.Info.TaskId] - if !ok { - return true - } - b := ws.respondDataFormat(constants.WEBSOCKET_RENDER_IMAGE, websocket_data.RenderImageRspMsg{ - RenderId: renderId, - Image: req.Info.Image, - }) - //删除对应的需要渲染的图片map - ws.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ - Option: 0, //0删除 1添加 - TaskId: req.Info.TaskId, - RenderId: renderId, - } - //发送数据到out chan - ws.sendToOutChan(b) - return true - }) + data := websocket_data.RenderImageNotify{ + TaskId: req.Info.TaskId, + Image: req.Info.Image, + } + d, _ := json.Marshal(data) + if err := l.svcCtx.RabbitMq.SendMsg(constants.RABBIT_MQ_RENDER_RESULT_DATA, d); err != nil { + logx.Error(err) + return resp.SetStatus(basic.CodeServiceErr, "failed to send data") + } return resp.SetStatus(basic.CodeOK) } diff --git a/server/render/internal/logic/tounitylogic.go b/server/render/internal/logic/tounitylogic.go deleted file mode 100644 index bacf7b98..00000000 --- a/server/render/internal/logic/tounitylogic.go +++ /dev/null @@ -1,42 +0,0 @@ -package logic - -import ( - "fusenapi/utils/auth" - "fusenapi/utils/basic" - - "context" - - "fusenapi/server/render/internal/svc" - "fusenapi/server/render/internal/types" - - "github.com/zeromicro/go-zero/core/logx" -) - -type ToUnityLogic struct { - logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext -} - -func NewToUnityLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ToUnityLogic { - return &ToUnityLogic{ - Logger: logx.WithContext(ctx), - ctx: ctx, - svcCtx: svcCtx, - } -} - -// 处理进入前逻辑w,r -// func (l *ToUnityLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { -// } - -// 处理逻辑后 w,r 如:重定向 -// func (l *ToUnityLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { -// } - -func (l *ToUnityLogic) ToUnity(req *types.RequestToUnity, userinfo *auth.UserInfo) (resp *basic.Response) { - // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) - // userinfo 传入值时, 一定不为null - - return resp.SetStatus(basic.CodeOK) -} diff --git a/server/render/internal/types/types.go b/server/render/internal/types/types.go index e2847118..91d3407f 100644 --- a/server/render/internal/types/types.go +++ b/server/render/internal/types/types.go @@ -11,6 +11,17 @@ 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"` +} + type Request struct { } diff --git a/server/websocket/consumer/consumer.go b/server/websocket/consumer/consumer.go deleted file mode 100644 index 16a7c8a9..00000000 --- a/server/websocket/consumer/consumer.go +++ /dev/null @@ -1,12 +0,0 @@ -package consumer - -import "fmt" - -// 消费渲染结果数据 -type MqConsumerRenderResult struct { -} - -func (m *MqConsumerRenderResult) Run(data []byte) error { - fmt.Println("收到消息:" + string(data)) - return nil -} diff --git a/server/websocket/internal/handler/rendernotifyhandler.go b/server/websocket/internal/handler/rendernotifyhandler.go deleted file mode 100644 index ab16cdad..00000000 --- a/server/websocket/internal/handler/rendernotifyhandler.go +++ /dev/null @@ -1,31 +0,0 @@ -package handler - -import ( - "fusenapi/server/websocket/internal/logic" - "fusenapi/server/websocket/internal/svc" - "fusenapi/server/websocket/internal/types" - "fusenapi/utils/basic" - "net/http" - "reflect" -) - -func RenderNotifyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req types.RenderNotifyReq - _, err := basic.RequestParse(w, r, svcCtx, &req) - if err != nil { - return - } - // 创建一个业务逻辑层实例 - l := logic.NewRenderNotifyLogic(r.Context(), svcCtx) - - rl := reflect.ValueOf(l) - basic.BeforeLogic(w, r, rl) - - resp := l.RenderNotify(&req) - - if !basic.AfterLogic(w, r, rl, resp) { - basic.NormalAfterLogic(w, r, resp) - } - } -} diff --git a/server/websocket/internal/handler/routes.go b/server/websocket/internal/handler/routes.go index 6649e3c3..fd3200e4 100644 --- a/server/websocket/internal/handler/routes.go +++ b/server/websocket/internal/handler/routes.go @@ -17,16 +17,6 @@ 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), - }, - { - Method: http.MethodPost, - Path: "/api/websocket/third_party_login_notify", - Handler: ThirdPartyLoginNotifyHandler(serverCtx), - }, }, ) } diff --git a/server/websocket/internal/handler/thirdpartyloginnotifyhandler.go b/server/websocket/internal/handler/thirdpartyloginnotifyhandler.go deleted file mode 100644 index ae16b24c..00000000 --- a/server/websocket/internal/handler/thirdpartyloginnotifyhandler.go +++ /dev/null @@ -1,35 +0,0 @@ -package handler - -import ( - "net/http" - "reflect" - - "fusenapi/utils/basic" - - "fusenapi/server/websocket/internal/logic" - "fusenapi/server/websocket/internal/svc" - "fusenapi/server/websocket/internal/types" -) - -func ThirdPartyLoginNotifyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - var req types.ThirdPartyLoginNotifyReq - userinfo, err := basic.RequestParse(w, r, svcCtx, &req) - if err != nil { - return - } - - // 创建一个业务逻辑层实例 - l := logic.NewThirdPartyLoginNotifyLogic(r.Context(), svcCtx) - - rl := reflect.ValueOf(l) - basic.BeforeLogic(w, r, rl) - - resp := l.ThirdPartyLoginNotify(&req, userinfo) - - if !basic.AfterLogic(w, r, rl, resp) { - basic.NormalAfterLogic(w, r, resp) - } - } -} diff --git a/server/websocket/internal/logic/mq_consumer.go b/server/websocket/internal/logic/mq_consumer.go new file mode 100644 index 00000000..c28ff2d6 --- /dev/null +++ b/server/websocket/internal/logic/mq_consumer.go @@ -0,0 +1,52 @@ +package logic + +import ( + "encoding/json" + "fusenapi/constants" + "fusenapi/utils/websocket_data" + "github.com/zeromicro/go-zero/core/logx" +) + +// 消费渲染结果数据 +type MqConsumerRenderResult struct { +} + +func (m *MqConsumerRenderResult) Run(data []byte) error { + 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 +} diff --git a/server/websocket/internal/logic/thirdpartyloginnotifylogic.go b/server/websocket/internal/logic/thirdpartyloginnotifylogic.go deleted file mode 100644 index d3639a95..00000000 --- a/server/websocket/internal/logic/thirdpartyloginnotifylogic.go +++ /dev/null @@ -1,79 +0,0 @@ -package logic - -import ( - "fusenapi/constants" - "fusenapi/utils/auth" - "fusenapi/utils/basic" - "fusenapi/utils/websocket_data" - "time" - - "context" - - "fusenapi/server/websocket/internal/svc" - "fusenapi/server/websocket/internal/types" - - "github.com/zeromicro/go-zero/core/logx" -) - -type ThirdPartyLoginNotifyLogic struct { - logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext -} - -func NewThirdPartyLoginNotifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ThirdPartyLoginNotifyLogic { - return &ThirdPartyLoginNotifyLogic{ - Logger: logx.WithContext(ctx), - ctx: ctx, - svcCtx: svcCtx, - } -} - -// 处理进入前逻辑w,r -// func (l *ThirdPartyLoginNotifyLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { -// } - -// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 -// func (l *ThirdPartyLoginNotifyLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { -// // httpx.OkJsonCtx(r.Context(), w, resp) -// } - -func (l *ThirdPartyLoginNotifyLogic) ThirdPartyLoginNotify(req *types.ThirdPartyLoginNotifyReq, userinfo *auth.UserInfo) (resp *basic.Response) { - if time.Now().Unix()-120 > req.Time /*|| req.Time > time.Now().Unix() */ { - return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param: time is invalid") - } - if req.Info.WebsocketId <= 0 { - return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:websocket_id is required") - } - if req.Info.Token == "" { - return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "err param:token is required") - } - //验证签名 sha256 - /*notifyByte, _ := json.Marshal(req.Info) - h := sha256.New() - h.Write([]byte(fmt.Sprintf(constants.THIRD_PARTY_LOGIN_NOTIFY_SIGN_KEY, string(notifyByte), req.Time))) - signHex := h.Sum(nil) - sign := hex.EncodeToString(signHex) - //fmt.Println(sign) - if req.Sign != sign { - return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid sign") - }*/ - //查询对应websocket连接 - val, ok := mapConnPool.Load(req.Info.WebsocketId) - if !ok { - return resp.SetStatusWithMessage(basic.CodeOK, "success:websocket connection is not exists") - } - ws, ok := val.(wsConnectItem) - if !ok { - return resp.SetStatusWithMessage(basic.CodeServiceErr, "type of websocket connect object is err") - } - b := ws.respondDataFormat(constants.WEBSOCKET_THIRD_PARTY_LOGIN_NOTIFY, websocket_data.ThirdPartyLoginRspMsg{ - Token: req.Info.Token, - }) - select { - case <-ws.closeChan: - return resp.SetStatusWithMessage(basic.CodeOK, "websocket connect object is closed") - case ws.outChan <- b: - return resp.SetStatusWithMessage(basic.CodeOK, "success") - } -} diff --git a/server/websocket/internal/types/types.go b/server/websocket/internal/types/types.go index 67d38865..70ec268a 100644 --- a/server/websocket/internal/types/types.go +++ b/server/websocket/internal/types/types.go @@ -5,28 +5,6 @@ import ( "fusenapi/utils/basic" ) -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"` -} - -type ThirdPartyLoginNotifyReq struct { - Sign string `json:"sign"` - Time int64 `json:"time"` - Info ThirdPartyLoginNotify `json:"info"` -} - -type ThirdPartyLoginNotify struct { - WebsocketId uint64 `json:"websocket_id"` - Token string `json:"token"` -} - type Request struct { } diff --git a/server/websocket/websocket.go b/server/websocket/websocket.go index 01a9efb8..202e57fd 100644 --- a/server/websocket/websocket.go +++ b/server/websocket/websocket.go @@ -5,7 +5,7 @@ import ( "flag" "fmt" "fusenapi/constants" - "fusenapi/server/websocket/consumer" + "fusenapi/server/websocket/internal/logic" "net/http" "fusenapi/utils/auth" @@ -34,7 +34,7 @@ func main() { ctx1 := context.Background() ctx2, cancel := context.WithCancel(ctx1) defer cancel() - go ctx.RabbitMq.Consume(ctx2, constants.RABBIT_MQ_RENDER_RESULT_DATA, &consumer.MqConsumerRenderResult{}) + 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() diff --git a/server_api/render.api b/server_api/render.api index ba162b18..f25d6ab3 100644 --- a/server_api/render.api +++ b/server_api/render.api @@ -16,10 +16,18 @@ type RequestReadImages { } service render { - // 发送数据到unity渲染 - @handler ToUnityHandler - get /api/render/to-unity(RequestToUnity) returns (response); - // 读图像 - @handler ReadImagesHandler - get /api/render/read-images(RequestReadImages) returns (response); + //云渲染完了通知接口 + @handler RenderNotifyHandler + post /api/render/render_notify(RenderNotifyReq) returns (response); +} + +//渲染完了通知接口 +type RenderNotifyReq { + Sign string `json:"sign"` + Time int64 `json:"time"` + Info NotifyInfo `json:"info"` +} +type NotifyInfo { + TaskId string `json:"task_id"` //任务id + Image string `json:"image"` } \ No newline at end of file diff --git a/server_api/websocket.api b/server_api/websocket.api index 22104825..ef24d79f 100644 --- a/server_api/websocket.api +++ b/server_api/websocket.api @@ -12,31 +12,4 @@ service websocket { //websocket数据交互 @handler DataTransferHandler get /api/websocket/data_transfer(request) returns (response); - //云渲染完了通知接口 - @handler RenderNotifyHandler - post /api/websocket/render_notify(RenderNotifyReq) returns (response); - //第三方登录通知接口 - @handler ThirdPartyLoginNotifyHandler - post /api/websocket/third_party_login_notify(ThirdPartyLoginNotifyReq) returns (response); -} - -//渲染完了通知接口 -type RenderNotifyReq { - Sign string `json:"sign"` - Time int64 `json:"time"` - Info NotifyInfo `json:"info"` -} -type NotifyInfo { - TaskId string `json:"task_id"` //任务id - Image string `json:"image"` -} -//第三方登录通知接口 -type ThirdPartyLoginNotifyReq { - Sign string `json:"sign"` - Time int64 `json:"time"` - Info ThirdPartyLoginNotify `json:"info"` -} -type ThirdPartyLoginNotify { - WebsocketId uint64 `json:"websocket_id"` - Token string `json:"token"` } \ No newline at end of file diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go index 3ec0067a..1add9d87 100644 --- a/utils/websocket_data/render_data.go +++ b/utils/websocket_data/render_data.go @@ -5,16 +5,24 @@ type DataTransferData struct { T string `json:"t"` //消息类型 D interface{} `json:"d"` //传递的消息 } + +// websocket接受要云渲染处理的数据 type RenderImageReqMsg struct { - //websocket接受要云渲染处理的数据 RenderId string `json:"render_id"` //渲染id RenderData interface{} `json:"render_data"` //参数数据 } + +// websocket发送渲染完的数据 type RenderImageRspMsg struct { - //websocket发送渲染完的数据 RenderId string `json:"render_id"` //渲染id Image string `json:"image"` //渲染结果图片 } + +// 渲染服务器回调数据 +type RenderImageNotify struct { + TaskId string `json:"task_id"` + Image string `json:"image"` +} type ThirdPartyLoginRspMsg struct { //websocket三方登录的通知数据 Token string `json:"token"` From e9c5e96c52e1444026bda0ac25f14847dde15fcb Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 13:17:23 +0800 Subject: [PATCH 46/60] fix --- server/render/etc/render.yaml | 2 +- server/websocket/internal/logic/datatransferlogic.go | 7 ++++--- server/websocket/internal/logic/ws_render_image_logic.go | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/server/render/etc/render.yaml b/server/render/etc/render.yaml index 30b4cdd7..d0f93153 100644 --- a/server/render/etc/render.yaml +++ b/server/render/etc/render.yaml @@ -1,6 +1,6 @@ Name: render Host: 0.0.0.0 -Port: 8888 +Port: 9919 SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest Auth: AccessSecret: fusen2023 diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index ab215c78..670d5938 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -270,9 +270,10 @@ func (w *wsConnectItem) dealwithReciveData(data []byte) { d, _ := json.Marshal(parseInfo.D) //分消息类型给到不同逻辑处理,可扩展 switch parseInfo.T { - //图片渲染数据组装 - case constants.WEBSOCKET_RENDER_IMAGE_ASSEMBLE: - w.assembleRenderData(d) + //图片渲染 + case constants.WEBSOCKET_RENDER_IMAGE: + //数据组装 + w.renderImage(d) default: } diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index e4881bba..0b750cfb 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -22,7 +22,7 @@ type renderImageControlChanItem struct { } // 渲染发送到组装数据组装数据 -func (w *wsConnectItem) assembleRenderData(data []byte) { +func (w *wsConnectItem) renderImage(data []byte) { var renderImageData websocket_data.RenderImageReqMsg if err := json.Unmarshal(data, &renderImageData); err != nil { w.outChan <- w.respondDataFormat(constants.WEBSOCKET_ERR_DATA_FORMAT, "invalid format of websocket render image message:"+string(data)) From 48e1093469892ab884b0dc1d3b257cf10677d897 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 13:18:20 +0800 Subject: [PATCH 47/60] fix --- server/websocket/internal/logic/datatransferlogic.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index 670d5938..66bb21b8 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -272,7 +272,6 @@ func (w *wsConnectItem) dealwithReciveData(data []byte) { switch parseInfo.T { //图片渲染 case constants.WEBSOCKET_RENDER_IMAGE: - //数据组装 w.renderImage(d) default: From 956b18a72e841f5a526d4a1a39e5aacda35ab647 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 13:20:18 +0800 Subject: [PATCH 48/60] fix --- server/render/consumer/assemble_render_data.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go index 78aa193e..dce9488a 100644 --- a/server/render/consumer/assemble_render_data.go +++ b/server/render/consumer/assemble_render_data.go @@ -1,12 +1,14 @@ package consumer -import "fmt" +import ( + "github.com/zeromicro/go-zero/core/logx" +) // 消费渲染需要组装的数据 type MqConsumerRenderAssemble struct { } func (m *MqConsumerRenderAssemble) Run(data []byte) error { - fmt.Println("收到需要组装的消息:" + string(data)) + logx.Info("收到需要组装的消息:", string(data)) return nil } From 156ec586f04fea6d6ca3dbc34432fc1c83f4c947 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 14:16:09 +0800 Subject: [PATCH 49/60] fix --- .../render/internal/logic/rendernotifylogic.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/server/render/internal/logic/rendernotifylogic.go b/server/render/internal/logic/rendernotifylogic.go index aa735d6d..af298155 100644 --- a/server/render/internal/logic/rendernotifylogic.go +++ b/server/render/internal/logic/rendernotifylogic.go @@ -1,14 +1,12 @@ package logic import ( + "context" "encoding/json" "fusenapi/constants" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/websocket_data" - "time" - - "context" "fusenapi/server/render/internal/svc" "fusenapi/server/render/internal/types" @@ -40,16 +38,24 @@ func NewRenderNotifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Rend // } func (l *RenderNotifyLogic) RenderNotify(req *types.RenderNotifyReq, userinfo *auth.UserInfo) (resp *basic.Response) { - if time.Now().Unix()-120 > req.Time /*|| req.Time > time.Now().Unix() */ { + /*if time.Now().Unix()-120 > req.Time || req.Time > time.Now().Unix() { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param time") + }*/ + if req.Info.TaskId == "" { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param task_id") } + if req.Info.Image == "" { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param image") + } + /* if req.Sign == "" { + return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid param sign") + }*/ //验证签名 sha256 /*notifyByte, _ := json.Marshal(req.Info) h := sha256.New() h.Write([]byte(fmt.Sprintf(constants.RENDER_NOTIFY_SIGN_KEY, string(notifyByte), req.Time))) signHex := h.Sum(nil) sign := hex.EncodeToString(signHex) - //fmt.Println(sign) if req.Sign != sign { return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid sign") }*/ From b13fb6d1e696cdab2d8e7e01819e68b4a84d90ca Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 16:19:54 +0800 Subject: [PATCH 50/60] =?UTF-8?q?fix:=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/upload/internal/logic/uploadfilesbackendlogic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index 9d30f2ae..e89c91aa 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -228,7 +228,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, // 返回成功的响应和上传URL return resp.SetStatus(basic.CodeOK, map[string]interface{}{ - "upload_urls": result, + "upload_data": result, }) } From 55d39ab3035ea10f1fced26f0a0bb6e27102ca20 Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 16:45:46 +0800 Subject: [PATCH 51/60] =?UTF-8?q?fix:=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/upload/internal/logic/uploadlogologic.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go index b5a4ede5..50415695 100644 --- a/server/upload/internal/logic/uploadlogologic.go +++ b/server/upload/internal/logic/uploadlogologic.go @@ -78,6 +78,7 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us logoHeight = 200 } var resultStr string + var err error // apiUrl := l.svcCtx.Config.BLMService.ImageProcess.Url // var onlyScale = true @@ -113,7 +114,7 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us var nowTime = time.Now().Unix() // 新增记录 userMaterialModel := gmodel.NewFsUserMaterialModel(l.svcCtx.MysqlConn) - _, err := userMaterialModel.CreateOrUpdate(l.ctx, &gmodel.FsUserMaterial{ + _, err = userMaterialModel.CreateOrUpdate(l.ctx, &gmodel.FsUserMaterial{ Module: &module, UserId: &userId, GuestId: &guestId, From e2e28805142d8095a178882d330203b787daa3a9 Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 17:10:09 +0800 Subject: [PATCH 52/60] =?UTF-8?q?fix:=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/gmodel/fs_product_template_v2_gen.go | 2 ++ model/gmodel/fs_resource_gen.go | 1 + model/gmodel/fs_user_material_gen.go | 2 +- .../internal/logic/uploadcallbacklogic.go | 26 +++++++++++++++++++ .../internal/logic/uploadfilebaselogic.go | 1 + .../internal/logic/uploadfilesbackendlogic.go | 1 + server/upload/internal/types/types.go | 11 ++++---- server_api/upload.api | 11 ++++---- 8 files changed, 44 insertions(+), 11 deletions(-) diff --git a/model/gmodel/fs_product_template_v2_gen.go b/model/gmodel/fs_product_template_v2_gen.go index 62b8bce3..5e14427f 100644 --- a/model/gmodel/fs_product_template_v2_gen.go +++ b/model/gmodel/fs_product_template_v2_gen.go @@ -22,6 +22,8 @@ type FsProductTemplateV2 struct { Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间 Tag *string `gorm:"default:'';" json:"tag"` // 标签(用户自填) IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除 1删除 + GroupOptions *string `gorm:"default:'';" json:"group_options"` // 颜色分组 + Version *int64 `gorm:"default:0;" json:"version"` // } type FsProductTemplateV2Model struct { db *gorm.DB diff --git a/model/gmodel/fs_resource_gen.go b/model/gmodel/fs_resource_gen.go index 4c7d2311..af635081 100644 --- a/model/gmodel/fs_resource_gen.go +++ b/model/gmodel/fs_resource_gen.go @@ -17,6 +17,7 @@ type FsResource struct { Metadata *string `gorm:"default:'';" json:"metadata"` // 元数据,json格式,存储图像分率 MetaKey1 *string `gorm:"index;default:'';" json:"meta_key1"` // 需要关键信息查询的自定义属性1,可以动态增加 ApiType *int64 `gorm:"default:1;" json:"api_type"` // 调用类型:1=对外,2=对内 + BucketName *string `gorm:"default:'';" json:"bucket_name"` // 存储桶名 } type FsResourceModel struct { db *gorm.DB diff --git a/model/gmodel/fs_user_material_gen.go b/model/gmodel/fs_user_material_gen.go index 5f880096..d5592001 100644 --- a/model/gmodel/fs_user_material_gen.go +++ b/model/gmodel/fs_user_material_gen.go @@ -7,7 +7,7 @@ import ( // fs_user_material 用户素材表 type FsUserMaterial struct { Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 用户 ID - Module *string `gorm:"default:'';" json:"module"` // 所属模块 + Module *string `gorm:"default:'';" json:"module"` // 所属模块:logo UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户 ID GuestId *int64 `gorm:"index;default:0;" json:"guest_id"` // 游客 ID ResourceId *string `gorm:"default:'';" json:"resource_id"` // 资源ID diff --git a/server/upload/internal/logic/uploadcallbacklogic.go b/server/upload/internal/logic/uploadcallbacklogic.go index 7c15d85f..f4e8b8e7 100644 --- a/server/upload/internal/logic/uploadcallbacklogic.go +++ b/server/upload/internal/logic/uploadcallbacklogic.go @@ -41,6 +41,29 @@ func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, useri // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null + var userId int64 + var guestId int64 + + // 检查用户是否是游客 + if userinfo.IsGuest() { + // 如果是,使用游客ID和游客键名格式 + guestId = userinfo.GuestId + } else { + // 否则,使用用户ID和用户键名格式 + userId = userinfo.UserId + } + + // 定义存储桶名称 + var bucketName *string + + // 根据类别选择存储桶 + switch req.UploadBucket { + case 2: + bucketName = basic.TempfileBucketName + default: + bucketName = basic.StorageBucketName + } + resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) err := resourceModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) { resourceModelTS := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) @@ -50,11 +73,14 @@ func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, useri } var fsResource = &gmodel.FsResource{} + fsResource.UserId = &userId + fsResource.GuestId = &guestId fsResource.ResourceId = req.ResourceId fsResource.ResourceType = &req.ResourceType fsResource.ResourceUrl = &req.ResourceUrl fsResource.Metadata = &req.Metadata fsResource.ApiType = &req.ApiType + fsResource.BucketName = bucketName if resourceInfo.ResourceId == "" { _, err = resourceModelTS.Create(ctx, fsResource) } else { diff --git a/server/upload/internal/logic/uploadfilebaselogic.go b/server/upload/internal/logic/uploadfilebaselogic.go index 46c210c0..62912c02 100644 --- a/server/upload/internal/logic/uploadfilebaselogic.go +++ b/server/upload/internal/logic/uploadfilebaselogic.go @@ -140,6 +140,7 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri UploadedAt: &nowTime, Metadata: &req.Metadata, ApiType: &apiType, + BucketName: bucketName, }) if err != nil { logx.Error(err) diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index e89c91aa..ac7f0e40 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -195,6 +195,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, UploadedAt: &nowTime, Metadata: &uploadDataInfo.Metadata, ApiType: &uploadDataInfo.ApiType, + BucketName: bucketName, }) if err != nil { logx.Error(err) diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index c967bf42..4f083802 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -36,11 +36,12 @@ type UploadFilesReq struct { } type UploadCallbackReq struct { - ResourceId string `form:"resource_id"` // 资源ID - ResourceType string `form:"resource_type"` // 资源类型 - ResourceUrl string `form:"resource_url"` // 资源URL - Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 - ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 + UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 + ResourceId string `form:"resource_id"` // 资源ID + ResourceType string `form:"resource_type"` // 资源类型 + ResourceUrl string `form:"resource_url"` // 资源URL + Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 } type RequestUpFile struct { diff --git a/server_api/upload.api b/server_api/upload.api index a94830be..a44c6aca 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -79,11 +79,12 @@ type ( UploadInfo string `form:"upload_info"` // 上传信息 json } UploadCallbackReq { - ResourceId string `form:"resource_id"` // 资源ID - ResourceType string `form:"resource_type"` // 资源类型 - ResourceUrl string `form:"resource_url"` // 资源URL - Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 - ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 + UploadBucket int64 `form:"upload_bucket,options=[1,2],default=1"` // 上传桶名:1=缓存,2=持久 + ResourceId string `form:"resource_id"` // 资源ID + ResourceType string `form:"resource_type"` // 资源类型 + ResourceUrl string `form:"resource_url"` // 资源URL + Metadata string `form:"metadata,optional"` // 元数据,json格式,存储图像分率 + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 } ) From 8b42c41bc5c3e7232ee47bc86465d1d0b826868b Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 17:12:01 +0800 Subject: [PATCH 53/60] =?UTF-8?q?fix:=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/upload/internal/logic/uploadcallbacklogic.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/upload/internal/logic/uploadcallbacklogic.go b/server/upload/internal/logic/uploadcallbacklogic.go index f4e8b8e7..a8b93eaf 100644 --- a/server/upload/internal/logic/uploadcallbacklogic.go +++ b/server/upload/internal/logic/uploadcallbacklogic.go @@ -72,6 +72,7 @@ func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, useri return err } + var version string = "0.0.1" var fsResource = &gmodel.FsResource{} fsResource.UserId = &userId fsResource.GuestId = &guestId @@ -81,6 +82,7 @@ func (l *UploadCallbackLogic) UploadCallback(req *types.UploadCallbackReq, useri fsResource.Metadata = &req.Metadata fsResource.ApiType = &req.ApiType fsResource.BucketName = bucketName + fsResource.Version = &version if resourceInfo.ResourceId == "" { _, err = resourceModelTS.Create(ctx, fsResource) } else { From 74708d3b21b7e6146e67fa688f7c8ee9235735f3 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 17:19:55 +0800 Subject: [PATCH 54/60] fix --- constants/render.go | 203 ++++++++++++++++++ model/gmodel/fs_user_material_logic.go | 15 ++ .../internal/handler/getfaceslicehandler.go | 35 +++ server/render/internal/handler/routes.go | 5 + .../internal/logic/getfaceslicelogic.go | 69 ++++++ server_api/render.api | 3 + 6 files changed, 330 insertions(+) create mode 100644 constants/render.go create mode 100644 server/render/internal/handler/getfaceslicehandler.go create mode 100644 server/render/internal/logic/getfaceslicelogic.go diff --git a/constants/render.go b/constants/render.go new file mode 100644 index 00000000..fe8b6a6f --- /dev/null +++ b/constants/render.go @@ -0,0 +1,203 @@ +package constants + +// 渲染要用到的面片模板 +const RENDER_FACE_SLICE_TEMPLATE_JSON = `[ + { + "id": "", + "tag": "MainColor", + "title": "", + "type": "color", + "text": "", + "fill": "{{MainColorFill}}", + "fontSize": 20, + "fontFamily": "Aqum2SmallCaps3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 1024, + "height": 1024, + "proportion": 60, + "x": 0, + "y": 0, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": true + } + ], + "zIndex": 1, + "svgPath": "", + "follow": { + "fill": "", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "id": "", + "tag": "SecondaryColor", + "title": "贴图3", + "type": "color", + "text": "", + "fill": "{{SecondaryColorFill}}", + "fontSize": 20, + "fontFamily": "Aqum2SmallCaps3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 1024, + "height": 1024, + "proportion": 60, + "x": 0, + "y": 0, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": true + } + ], + "zIndex": 2, + "svgPath": "", + "follow": { + "fill": "", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 0 + } + }, + { + "id": "569d7981-25c3-3c03-0e7e-800c14800362", + "tag": "Slogan", + "title": "贴图4", + "type": "text", + "text": "", + "fill": "", + "fontSize": 13, + "fontFamily": "MontserratBold3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 309.9999999999993, + "height": 11.999265664648076, + "proportion": 60, + "x": 97.0015259021898, + "y": 575.300725990631, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": true + } + ], + "zIndex": 3, + "svgPath": "", + "follow": { + "fill": "38c09538-937d-510c-bf32-bfb1ce90cafa", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 45 + } + }, + { + "id": "c466e27c-d48f-db86-b85f-3c4c51114046", + "tag": "Logo", + "title": "贴图8", + "type": "image", + "text": "", + "fill": "#0082ca", + "fontSize": 20, + "fontFamily": "Aqum2SmallCaps3", + "ifBr": false, + "ifShow": true, + "ifGroup": false, + "maxNum": 50, + "rotation": 0, + "lineHeight": 1, + "align": "center", + "verticalAlign": "middle", + "material": "{{LogoMaterial}}", + "materialTime": "", + "materialName": "", + "QRcodeType": "", + "width": 282.9999999999999, + "height": 95.99999999999933, + "proportion": 60, + "x": 110.99999999999982, + "y": 438.7192999999991, + "opacity": 1, + "optionalColor": [ + { + "color": "#000000", + "name": "Black", + "default": false + }, + { + "name": "MainColor", + "color": "#0082ca", + "default": true + } + ], + "zIndex": 7, + "svgPath": "", + "follow": { + "fill": "", + "ifShow": "", + "content": "" + }, + "group": [], + "cameraStand": { + "x": 0, + "y": 0, + "z": 0 + } + } +] +` diff --git a/model/gmodel/fs_user_material_logic.go b/model/gmodel/fs_user_material_logic.go index d8ecaaf4..134ced4b 100644 --- a/model/gmodel/fs_user_material_logic.go +++ b/model/gmodel/fs_user_material_logic.go @@ -55,3 +55,18 @@ func (m *FsUserMaterialModel) RowSelectBuilder(selectData []string) *gorm.DB { } return rowBuilder } + +// 获取最新记录 +func (m *FsUserMaterialModel) FindLatestOne(ctx context.Context, userId int64, guestId int64) (resp FsUserMaterial, err error) { + if userId == 0 && guestId == 0 { + return FsUserMaterial{}, nil + } + db := m.db.WithContext(ctx).Model(&FsUserMaterial{}).Order("id DESC") + if userId != 0 { + db = db.Where("`user_id` = ?", userId) + } else { + db = db.Where("`guest_id` = ?", guestId) + } + err = db.Take(&resp).Error + return resp, err +} diff --git a/server/render/internal/handler/getfaceslicehandler.go b/server/render/internal/handler/getfaceslicehandler.go new file mode 100644 index 00000000..ac337bb0 --- /dev/null +++ b/server/render/internal/handler/getfaceslicehandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/render/internal/logic" + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" +) + +func GetFaceSliceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.Request + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewGetFaceSliceLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.GetFaceSlice(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/render/internal/handler/routes.go b/server/render/internal/handler/routes.go index 0bbf0d3e..26ad8b15 100644 --- a/server/render/internal/handler/routes.go +++ b/server/render/internal/handler/routes.go @@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/render/render_notify", Handler: RenderNotifyHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/render/get_face_slice", + Handler: GetFaceSliceHandler(serverCtx), + }, }, ) } diff --git a/server/render/internal/logic/getfaceslicelogic.go b/server/render/internal/logic/getfaceslicelogic.go new file mode 100644 index 00000000..0afb49fb --- /dev/null +++ b/server/render/internal/logic/getfaceslicelogic.go @@ -0,0 +1,69 @@ +package logic + +import ( + "encoding/json" + "errors" + "fusenapi/constants" + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "gorm.io/gorm" + "strings" + + "context" + + "fusenapi/server/render/internal/svc" + "fusenapi/server/render/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type GetFaceSliceLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewGetFaceSliceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFaceSliceLogic { + return &GetFaceSliceLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *GetFaceSliceLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *GetFaceSliceLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } + +func (l *GetFaceSliceLogic) GetFaceSlice(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) { + if !userinfo.IsUser() && !userinfo.IsGuest() { + return resp.SetStatusWithMessage(basic.CodeUnAuth, "please login or access cookie") + } + //获取用户素材信息 + materialInfo, err := l.svcCtx.AllModels.FsUserMaterial.FindLatestOne(l.ctx, userinfo.UserId, userinfo.GuestId) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "user material info is not exists") + } + return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get user material info") + } + if materialInfo.Metadata == nil || *materialInfo.Metadata == "" { + return resp.SetStatusWithMessage(basic.CodeServiceErr, "user material info`Metadata is empty") + } + var info map[string]interface{} + if err = json.Unmarshal([]byte(*materialInfo.Metadata), &info); err != nil { + logx.Error(err) + return resp.SetStatusWithMessage(basic.CodeJsonErr, "invalid json format of metadata") + } + str := strings.ReplaceAll(constants.RENDER_FACE_SLICE_TEMPLATE_JSON, "{{MainColorFill}}", info["main_color_fill"].(string)) + str = strings.ReplaceAll(str, "{{SecondaryColorFill}}", info["secondary_color_fill"].(string)) + str = strings.ReplaceAll(str, "{{LogoMaterial}}", info["logo_material"].(string)) + var rspInfo interface{} + _ = json.Unmarshal([]byte(str), &rspInfo) + return resp.SetStatusWithMessage(basic.CodeOK, "success", rspInfo) +} diff --git a/server_api/render.api b/server_api/render.api index f25d6ab3..8dd06347 100644 --- a/server_api/render.api +++ b/server_api/render.api @@ -19,6 +19,9 @@ service render { //云渲染完了通知接口 @handler RenderNotifyHandler post /api/render/render_notify(RenderNotifyReq) returns (response); + //获取面片信息 + @handler GetFaceSliceHandler + post /api/render/get_face_slice(request) returns (response); } //渲染完了通知接口 From 84ac7d92b2460afd74c11d0969b4d002ab1c076c Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 18:37:33 +0800 Subject: [PATCH 55/60] fix --- utils/websocket_data/render_data.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go index 1add9d87..3adefdcf 100644 --- a/utils/websocket_data/render_data.go +++ b/utils/websocket_data/render_data.go @@ -8,8 +8,14 @@ type DataTransferData struct { // websocket接受要云渲染处理的数据 type RenderImageReqMsg struct { - RenderId string `json:"render_id"` //渲染id - RenderData interface{} `json:"render_data"` //参数数据 + RenderId string `json:"render_id"` //渲染id + RenderData RenderData `json:"render_data"` +} +type RenderData struct { + TemplateTagId int64 `json:"template_tag_id"` //模板标签id + ProductId int64 `json:"product_id"` //产品id + Data interface{} `json:"data"` //面片数据 + UserId int64 `json:"user_id"` //用户id } // websocket发送渲染完的数据 @@ -30,6 +36,6 @@ type ThirdPartyLoginRspMsg struct { // 发送到渲染组装的mq数据 type AssembleRenderData struct { - TaskId string `json:"task_id"` - RenderData interface{} `json:"render_data"` + TaskId string `json:"task_id"` + RenderData RenderData `json:"render_data"` } From 31a3966e39d114fda19d1a58ec45f246941c410c Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Mon, 7 Aug 2023 19:13:16 +0800 Subject: [PATCH 56/60] fix --- .../render/consumer/assemble_render_data.go | 8 ++++++ .../internal/logic/datatransferlogic.go | 28 +++++++++++++------ .../internal/logic/ws_render_image_logic.go | 1 + utils/websocket_data/render_data.go | 1 + 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go index dce9488a..6e6cc6a3 100644 --- a/server/render/consumer/assemble_render_data.go +++ b/server/render/consumer/assemble_render_data.go @@ -1,6 +1,8 @@ package consumer import ( + "encoding/json" + "fusenapi/utils/websocket_data" "github.com/zeromicro/go-zero/core/logx" ) @@ -10,5 +12,11 @@ type MqConsumerRenderAssemble struct { func (m *MqConsumerRenderAssemble) Run(data []byte) error { logx.Info("收到需要组装的消息:", string(data)) + var parseInfo websocket_data.AssembleRenderData + if err := json.Unmarshal(data, &parseInfo); err != nil { + logx.Error("MqConsumerRenderAssemble数据格式错误:", err) + return nil //不返回错误就删除消息 + } + return nil } diff --git a/server/websocket/internal/logic/datatransferlogic.go b/server/websocket/internal/logic/datatransferlogic.go index 66bb21b8..d999d8e3 100644 --- a/server/websocket/internal/logic/datatransferlogic.go +++ b/server/websocket/internal/logic/datatransferlogic.go @@ -65,12 +65,13 @@ var ( type wsConnectItem struct { conn *websocket.Conn //websocket的连接 rabbitMq *initalize.RabbitMqHandle - closeChan chan struct{} //ws连接关闭chan - isClose bool //是否已经关闭 - uniqueId uint64 //ws连接唯一标识 - inChan chan []byte //接受消息缓冲通道 - outChan chan []byte //发送回客户端的消息 - mutex sync.Mutex //互斥锁 + closeChan chan struct{} //ws连接关闭chan + isClose bool //是否已经关闭 + uniqueId uint64 //ws连接唯一标识 + inChan chan []byte //接受消息缓冲通道 + outChan chan []byte //发送回客户端的消息 + mutex sync.Mutex //互斥锁 + userId int64 renderProperty renderProperty //扩展云渲染属性 } @@ -83,10 +84,14 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp } defer conn.Close() //鉴权不成功10秒后断开 - /*isAuth, _ := l.checkAuth(svcCtx, r) + var ( + userInfo *auth.UserInfo + isAuth bool + ) + isAuth, userInfo = l.checkAuth(svcCtx, r) if !isAuth { time.Sleep(time.Second) //兼容下火狐 - rsp := types.DataTransferData{ + rsp := websocket_data.DataTransferData{ T: constants.WEBSOCKET_UNAUTH, D: nil, } @@ -96,7 +101,7 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp //发送关闭信息 _ = conn.WriteMessage(websocket.CloseMessage, nil) return - }*/ + } //生成连接唯一标识 uniqueId := websocketIdGenerator.Get() ws := wsConnectItem{ @@ -111,6 +116,11 @@ func (l *DataTransferLogic) DataTransfer(svcCtx *svc.ServiceContext, w http.Resp renderImageTaskCtlChan: make(chan renderImageControlChanItem, 100), }, } + if userInfo.UserId > 0 { + ws.userId = userInfo.UserId + } else { + ws.userId = userInfo.GuestId + } //保存连接 mapConnPool.Store(uniqueId, ws) defer ws.close() diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index 0b750cfb..d4974870 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -39,6 +39,7 @@ func (w *wsConnectItem) renderImage(data []byte) { } tmpData := websocket_data.AssembleRenderData{ TaskId: taskId, + UserId: w.userId, RenderData: renderImageData.RenderData, } d, _ := json.Marshal(tmpData) diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go index 3adefdcf..09a203da 100644 --- a/utils/websocket_data/render_data.go +++ b/utils/websocket_data/render_data.go @@ -37,5 +37,6 @@ type ThirdPartyLoginRspMsg struct { // 发送到渲染组装的mq数据 type AssembleRenderData struct { TaskId string `json:"task_id"` + UserId int64 `json:"user_id"` RenderData RenderData `json:"render_data"` } From f87842deb455a4cda0aaafc3dbcb8f30ca53c2d2 Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 19:41:44 +0800 Subject: [PATCH 57/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/upload/internal/logic/uploadfilebaselogic.go | 6 +++--- server/upload/internal/logic/uploadfilesbackendlogic.go | 3 ++- server/upload/internal/logic/uploadlogologic.go | 7 +++++++ server/upload/internal/types/types.go | 2 +- server_api/upload.api | 2 +- utils/file/base64.go | 9 +++++---- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/server/upload/internal/logic/uploadfilebaselogic.go b/server/upload/internal/logic/uploadfilebaselogic.go index 62912c02..2b1f5d93 100644 --- a/server/upload/internal/logic/uploadfilebaselogic.go +++ b/server/upload/internal/logic/uploadfilebaselogic.go @@ -67,7 +67,7 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri // 定义存储桶名称 var bucketName *string - var apiType int64 = 2 + var apiType int64 = req.ApiType // 根据类别选择存储桶 switch req.UploadBucket { @@ -96,7 +96,7 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri uploadUrl.ResourceId = resourceId uploadUrl.ResourceUrl = *resourceInfo.ResourceUrl } else { - dist, err := file.FileBase64ToByte(req.FileData) + dist, contentType, err := file.FileBase64ToByte(req.FileData) if err != nil { logx.Error(err) @@ -134,7 +134,7 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri ResourceId: resourceId, UserId: &userId, GuestId: &guestId, - ResourceType: &req.FileType, + ResourceType: &contentType, ResourceUrl: &url, Version: &version, UploadedAt: &nowTime, diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index ac7f0e40..e113c6e8 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -177,6 +177,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, logx.Error(err) uploadUrl.Status = 0 } else { + contentType := http.DetectContentType(uploadDataInfo.FileData) var url = s3req.HTTPRequest.URL.String() // 打印请求URL logx.Info(url) @@ -189,7 +190,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, ResourceId: resourceId, UserId: &userId, GuestId: &guestId, - ResourceType: &uploadDataInfo.FileType, + ResourceType: &contentType, ResourceUrl: &url, Version: &version, UploadedAt: &nowTime, diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go index 50415695..99084502 100644 --- a/server/upload/internal/logic/uploadlogologic.go +++ b/server/upload/internal/logic/uploadlogologic.go @@ -110,6 +110,13 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us // } // resultStr = string(b) + // 上传图片 + var reqs types.UploadFileBaseReq + // reqs.FileType = + + // 创建一个业务逻辑层实例 + NewUploadFileBaseLogic(l.ctx, l.svcCtx).UploadFileBase(&reqs, userinfo) + var module = "logo" var nowTime = time.Now().Unix() // 新增记录 diff --git a/server/upload/internal/types/types.go b/server/upload/internal/types/types.go index 4f083802..952e4282 100644 --- a/server/upload/internal/types/types.go +++ b/server/upload/internal/types/types.go @@ -6,7 +6,7 @@ import ( ) type UploadFileBaseReq struct { - FileType string `form:"file_type"` // 上传文件类型 + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 FileKey string `form:"file_key"` // 上传唯一标识信息 FileData string `form:"file_data"` // 上传文件额外信息 Metadata string `form:"meta_data,optional"` // 上传文件额外信息 diff --git a/server_api/upload.api b/server_api/upload.api index a44c6aca..d0bfdef2 100644 --- a/server_api/upload.api +++ b/server_api/upload.api @@ -46,7 +46,7 @@ service upload { type ( UploadFileBaseReq { - FileType string `form:"file_type"` // 上传文件类型 + ApiType int64 `form:"api_type,options=[1,2],default=1"` // 调用类型:1=对外,2=对内 FileKey string `form:"file_key"` // 上传唯一标识信息 FileData string `form:"file_data"` // 上传文件额外信息 Metadata string `form:"meta_data,optional"` // 上传文件额外信息 diff --git a/utils/file/base64.go b/utils/file/base64.go index 84825501..0548f6fc 100644 --- a/utils/file/base64.go +++ b/utils/file/base64.go @@ -2,16 +2,17 @@ package file import ( "encoding/base64" + "net/http" "strings" ) -func FileBase64ToByte(fileData string) ([]byte, error) { +func FileBase64ToByte(fileData string) ([]byte, string, error) { RBase64Point := strings.LastIndex(fileData, ";base64,") + 8 fileDataStr := fileData[RBase64Point:] dist, err := base64.StdEncoding.DecodeString(fileDataStr) - if err != nil { - return nil, err + return nil, "", err } - return dist, nil + contentType := http.DetectContentType(dist) + return dist, contentType, nil } From dcc3cc4a7d089e2f77af74576cf384399e715648 Mon Sep 17 00:00:00 2001 From: Hiven Date: Mon, 7 Aug 2023 19:51:12 +0800 Subject: [PATCH 58/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../upload/internal/logic/uploadfilebaselogic.go | 9 ++++++--- server/upload/internal/logic/uploadlogologic.go | 14 +++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/server/upload/internal/logic/uploadfilebaselogic.go b/server/upload/internal/logic/uploadfilebaselogic.go index 2b1f5d93..dbb0be24 100644 --- a/server/upload/internal/logic/uploadfilebaselogic.go +++ b/server/upload/internal/logic/uploadfilebaselogic.go @@ -61,9 +61,12 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri userId = userinfo.UserId uid = userId } - - guestId = req.GuestId - userId = req.UserId + if guestId == 0 { + guestId = req.GuestId + } + if userId == 0 { + userId = req.UserId + } // 定义存储桶名称 var bucketName *string diff --git a/server/upload/internal/logic/uploadlogologic.go b/server/upload/internal/logic/uploadlogologic.go index 99084502..f9babfb8 100644 --- a/server/upload/internal/logic/uploadlogologic.go +++ b/server/upload/internal/logic/uploadlogologic.go @@ -110,12 +110,16 @@ func (l *UploadLogoLogic) UploadLogo(req *types.UploadLogoReq, userinfo *auth.Us // } // resultStr = string(b) - // 上传图片 - var reqs types.UploadFileBaseReq - // reqs.FileType = + // // 上传图片 + // var reqs types.UploadFileBaseReq + // reqs.ApiType = 2 + // reqs.UploadBucket = 2 + // reqs.Metadata = "" + // reqs.FileData = "" + // reqs.FileKey = "" - // 创建一个业务逻辑层实例 - NewUploadFileBaseLogic(l.ctx, l.svcCtx).UploadFileBase(&reqs, userinfo) + // // 创建一个业务逻辑层实例 + // resUpload := NewUploadFileBaseLogic(l.ctx, l.svcCtx).UploadFileBase(&reqs, userinfo) var module = "logo" var nowTime = time.Now().Unix() From ff86cceb17479653c6c08b06ff4a8c8030bb9a80 Mon Sep 17 00:00:00 2001 From: Hiven Date: Tue, 8 Aug 2023 10:53:28 +0800 Subject: [PATCH 59/60] =?UTF-8?q?fix:=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/logic/uploadfilebaselogic.go | 6 +----- .../internal/logic/uploadfilesbackendlogic.go | 6 +----- .../internal/logic/uploadfilesfrontendlogic.go | 18 +----------------- utils/hash/hash.go | 11 +++++++++++ 4 files changed, 14 insertions(+), 27 deletions(-) diff --git a/server/upload/internal/logic/uploadfilebaselogic.go b/server/upload/internal/logic/uploadfilebaselogic.go index dbb0be24..ab38fe4c 100644 --- a/server/upload/internal/logic/uploadfilebaselogic.go +++ b/server/upload/internal/logic/uploadfilebaselogic.go @@ -1,7 +1,6 @@ package logic import ( - "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -47,7 +46,6 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null // 定义用户ID和S3键名格式 - var uid int64 var userId int64 var guestId int64 @@ -55,11 +53,9 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri if userinfo.IsGuest() { // 如果是,使用游客ID和游客键名格式 guestId = userinfo.GuestId - uid = guestId } else { // 否则,使用用户ID和用户键名格式 userId = userinfo.UserId - uid = userId } if guestId == 0 { guestId = req.GuestId @@ -89,7 +85,7 @@ func (l *UploadFileBaseLogic) UploadFileBase(req *types.UploadFileBaseReq, useri // 定义S3请求和当前时间 var s3req *request.Request - var resourceId string = hash.JsonHashKey(fmt.Sprintf("%s%d", req.FileKey, uid)) + var resourceId string = hash.JsonHashKey(req.FileKey) var uploadUrl = UploadUrl{} resourceModel := gmodel.NewFsResourceModel(l.svcCtx.MysqlConn) diff --git a/server/upload/internal/logic/uploadfilesbackendlogic.go b/server/upload/internal/logic/uploadfilesbackendlogic.go index e113c6e8..a0fba113 100644 --- a/server/upload/internal/logic/uploadfilesbackendlogic.go +++ b/server/upload/internal/logic/uploadfilesbackendlogic.go @@ -2,7 +2,6 @@ package logic import ( "encoding/json" - "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" @@ -57,7 +56,6 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, } // 定义用户ID和S3键名格式 - var uid int64 var userId int64 var guestId int64 @@ -65,11 +63,9 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, if userinfo.IsGuest() { // 如果是,使用游客ID和游客键名格式 guestId = userinfo.GuestId - uid = guestId } else { // 否则,使用用户ID和用户键名格式 userId = userinfo.UserId - uid = userId } var uploadInfoList []UploadInfo @@ -132,7 +128,7 @@ func (l *UploadFilesBackendLogic) UploadFilesBackend(req *types.UploadFilesReq, // 一系列业务逻辑....验证类型,文件大小 - var hashKey string = hash.JsonHashKey(fmt.Sprintf("%s%d", info.FileKeys, uid)) + var hashKey string = hash.JsonHashKey(info.FileKeys) source <- UploadData{ FileKey: info.FileKeys, FileType: fileType, diff --git a/server/upload/internal/logic/uploadfilesfrontendlogic.go b/server/upload/internal/logic/uploadfilesfrontendlogic.go index 6ca20550..e0a9d6e2 100644 --- a/server/upload/internal/logic/uploadfilesfrontendlogic.go +++ b/server/upload/internal/logic/uploadfilesfrontendlogic.go @@ -2,7 +2,6 @@ package logic import ( "encoding/json" - "fmt" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/hash" @@ -45,21 +44,6 @@ func NewUploadFilesFrontendLogic(ctx context.Context, svcCtx *svc.ServiceContext func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null - // 定义用户ID和S3键名格式 - var uid int64 - var userId int64 - var guestId int64 - - // 检查用户是否是游客 - if userinfo.IsGuest() { - // 如果是,使用游客ID和游客键名格式 - guestId = userinfo.GuestId - uid = guestId - } else { - // 否则,使用用户ID和用户键名格式 - userId = userinfo.UserId - uid = userId - } var uploadInfoList []UploadInfo err := json.Unmarshal([]byte(req.UploadInfo), &uploadInfoList) @@ -98,7 +82,7 @@ func (l *UploadFilesFrontendLogic) UploadFilesFrontend(req *types.UploadFilesReq for _, info := range uploadInfoList { if info.FileSize <= 1024*1024*500 { // 一系列业务逻辑....验证类型,文件大小 - var hashKey string = hash.JsonHashKey(fmt.Sprintf("%s%d", info.FileKeys, uid)) + var hashKey string = hash.JsonHashKey(info.FileKeys) source <- UploadData{ FileKey: info.FileKeys, FileSize: info.FileSize, diff --git a/utils/hash/hash.go b/utils/hash/hash.go index 37ea1c00..968decf1 100644 --- a/utils/hash/hash.go +++ b/utils/hash/hash.go @@ -5,10 +5,21 @@ import ( "crypto/sha256" "encoding/json" "fmt" + "reflect" "sort" ) func JsonHashKey(v interface{}) string { + + if reflect.TypeOf(v).Kind() == reflect.String { + var obj interface{} + err := json.Unmarshal([]byte(v.(string)), &obj) + if err == nil { + // 反序列化成功,直接替换v + v = obj + } + } + h := sha256.New() h.Write(marshalOrdered(v)) return fmt.Sprintf("%x", h.Sum(nil)) From 93191d3bebb564b2155c5b7c47a800fc5a539232 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Tue, 8 Aug 2023 12:22:15 +0800 Subject: [PATCH 60/60] fix --- initalize/rabbitmq.go | 2 +- model/gmodel/fs_cloud_render_log_logic.go | 6 + model/gmodel/fs_product_model3d_logic.go | 8 + model/gmodel/fs_product_template_v2_logic.go | 13 ++ .../render/consumer/assemble_render_data.go | 218 +++++++++++++++++- server/render/render.go | 1 + .../websocket/internal/logic/mq_consumer.go | 3 +- .../internal/logic/ws_render_image_logic.go | 3 +- server/websocket/websocket.go | 1 + utils/mq_consumer_factory/mq.go | 4 +- utils/websocket_data/render_data.go | 2 +- 11 files changed, 255 insertions(+), 6 deletions(-) diff --git a/initalize/rabbitmq.go b/initalize/rabbitmq.go index 004524c0..da7f4e7f 100644 --- a/initalize/rabbitmq.go +++ b/initalize/rabbitmq.go @@ -123,7 +123,7 @@ func (h *RabbitMqHandle) Consume(ctx context.Context, queueName constants.RABBIT <-limit wait.Done() }() - if err = handle.Run(m.Body); err != nil { + if err = handle.Run(ctx, m.Body); err != nil { logx.Error("failed to deal with MQ message:", string(m.Body)) return } diff --git a/model/gmodel/fs_cloud_render_log_logic.go b/model/gmodel/fs_cloud_render_log_logic.go index 35237a04..92f12587 100644 --- a/model/gmodel/fs_cloud_render_log_logic.go +++ b/model/gmodel/fs_cloud_render_log_logic.go @@ -1,3 +1,9 @@ package gmodel +import "context" + // TODO: 使用model的属性做你想做的 + +func (r *FsCloudRenderLogModel) Create(ctx context.Context, data *FsCloudRenderLog) error { + return r.db.WithContext(ctx).Model(&FsCloudRenderLog{}).Create(data).Error +} diff --git a/model/gmodel/fs_product_model3d_logic.go b/model/gmodel/fs_product_model3d_logic.go index 35270c57..9cb2fe91 100755 --- a/model/gmodel/fs_product_model3d_logic.go +++ b/model/gmodel/fs_product_model3d_logic.go @@ -93,3 +93,11 @@ func (d *FsProductModel3dModel) GetGroupPartListByProductIds(ctx context.Context Group("product_id").Find(&resp).Error return resp, err } +func (d *FsProductModel3dModel) FindOneJoinSize(ctx context.Context, productId int64) (resp FsProductModel3d, err error) { + err = d.db.WithContext(ctx).Table(d.name+"as m").Joins("left join fs_product_size as s on m.size_id = s.id"). + Select("m.*"). + Where("m.product_id = ?", productId). + Where("(s.status= ? and m.tag = ?)", 1, 1). + Order("s.sort ASC").Take(&resp).Error + return resp, err +} diff --git a/model/gmodel/fs_product_template_v2_logic.go b/model/gmodel/fs_product_template_v2_logic.go index 76bf7bf0..dc8a1b02 100755 --- a/model/gmodel/fs_product_template_v2_logic.go +++ b/model/gmodel/fs_product_template_v2_logic.go @@ -106,3 +106,16 @@ func (t *FsProductTemplateV2Model) GetProductTemplateListByParams(ctx context.Co err = db.Find(&resp).Error return resp, err } + +// 获取第一个尺寸下的模板 +func (t *FsProductTemplateV2Model) FindOneByProductIdTagIdWithSizeTable(ctx context.Context, productId int64, tagId string) (resp *FsProductTemplateV2, err error) { + err = t.db.WithContext(ctx).Table(t.name+" as t"). + Joins("left join fs_product_size as s on t.product_id = s.product_id"). + Select("t.*"). + Where("t.product_id = ? and t.tag = ? ", productId, tagId). + Where("t.status = ? and t.is_del = ?", 1, 0). + Where("s.status = ?", 1). + Order("s.sort ASC"). + Take(&resp).Error + return resp, err +} diff --git a/server/render/consumer/assemble_render_data.go b/server/render/consumer/assemble_render_data.go index 6e6cc6a3..4a1c6f75 100644 --- a/server/render/consumer/assemble_render_data.go +++ b/server/render/consumer/assemble_render_data.go @@ -1,22 +1,238 @@ package consumer import ( + "bytes" + "context" "encoding/json" + "errors" + "fmt" + "fusenapi/model/gmodel" "fusenapi/utils/websocket_data" "github.com/zeromicro/go-zero/core/logx" + "gorm.io/gorm" + "io/ioutil" + "net/http" + "time" ) +// 这里请求的py接口返回数据 +type pythonApiRsp struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data []struct { + Tid int64 `json:"tid"` + Imgurl string `json:"imgurl"` + Costtime int64 `json:"costtime"` + } `json:"data"` +} + // 消费渲染需要组装的数据 type MqConsumerRenderAssemble struct { } -func (m *MqConsumerRenderAssemble) Run(data []byte) error { +func (m *MqConsumerRenderAssemble) Run(ctx context.Context, data []byte) error { 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("allmodels") + if val == nil { + return errors.New("allmodels is nil") + } + allmodels, ok := val.(*gmodel.AllModelsGen) + if !ok { + return errors.New("allmodels is nil!!") + } + timeSearchBegin := time.Now().UnixMilli() + //获取模板 + templateInfo, err := 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") + return nil + } + logx.Error("failed to get template info:", err) + return err + } + renderLogTime := time.Now().UnixMilli() - timeSearchBegin + now := time.Now().Unix() + title := "1-组装模板数据" + //云渲染日志 + err = allmodels.FsCloudRenderLog.Create(ctx, &gmodel.FsCloudRenderLog{ + UserId: &parseInfo.RenderData.UserId, + Title: &title, + Time: &renderLogTime, + Tag: &parseInfo.RenderId, + Ctime: &now, + }) + if err != nil { + logx.Error(err) + } + pyapiBeginTime := time.Now().UnixMilli() + //这里curl post请求数据。获取处理好的贴图数据,用于贴model的贴图 + pythonPostData := map[string]interface{}{ + "tids": templateInfo.Id, + "data": parseInfo.RenderData.Data, + } + pyPostBytes, _ := json.Marshal(pythonPostData) + url := "http://110.41.19.98:8867/imgRender" + pyRsp, err := http.Post(url, "application/json;charset=UTF-8", bytes.NewReader(pyPostBytes)) + if err != nil { + logx.Error("request python render api err:", err) + return err + } + defer pyRsp.Body.Close() + pyRspBytes, err := ioutil.ReadAll(pyRsp.Body) + if err != nil { + logx.Error("failed to read python api rsp body,err=", err) + return err + } + var rspInfo pythonApiRsp + if err = json.Unmarshal(pyRspBytes, &rspInfo); err != nil { + logx.Error("failed to unmarshal python api rsp:", err) + return err + } + if rspInfo.Code != 200 { + logx.Error("python api 接口请求错误:", rspInfo.Msg) + return err + } + if len(rspInfo.Data) == 0 { + logx.Error("python api 接口没有数据:") + return err + } + //云渲染日志 + title = "2-请求->接收python合成刀版图接口" + now = time.Now().Unix() + pyRequestTime := time.Now().UnixMilli() - pyapiBeginTime + err = allmodels.FsCloudRenderLog.Create(ctx, &gmodel.FsCloudRenderLog{ + UserId: &parseInfo.RenderData.UserId, + Title: &title, + Time: &pyRequestTime, + Tag: &parseInfo.RenderId, + Ctime: &now, + }) + if err != nil { + logx.Error(err) + } + incTime := int64(0) + mapCurlData := make(map[int64]int) + for k, v := range rspInfo.Data { + mapCurlData[v.Tid] = k + incTime += v.Costtime + } + //云渲染日志 + title = "3-python合成刀版图" + now = time.Now().Unix() + postData := string(pyPostBytes) + pyRspStr := string(pyRspBytes) + err = allmodels.FsCloudRenderLog.Create(ctx, &gmodel.FsCloudRenderLog{ + UserId: &parseInfo.RenderData.UserId, + PostUrl: &url, + PostData: &postData, + Result: &pyRspStr, + Title: &title, + Time: &incTime, + Tag: &parseInfo.RenderId, + Ctime: &now, + }) + if err != nil { + logx.Error(err) + } + //获取渲染设置信息 + //element, err := allmodels.FsProductTemplateElement + /* + $element = ProductTemplateElement::find() + ->andFilterWhere(['in', 'product_template_id', $mids]) + ->asArray() + ->all(); + + $element = array_column($element, null, 'product_template_id'); + $elementTitles = array_column($element, 'title'); + + $result = []; + + $time_pinjie_begin = $render->getMillisecond(); + foreach ($templates as $key => $val) { + if(!isset($element[$val['model_id']]) || !isset($imageData[$val['id']])){ + continue; + } + //数据拼装 + $item = []; + + $item['light'] = $element[$val['model_id']]['light']; + $item['refletion'] = $element[$val['model_id']]['refletion'] == '' ? -1 : (int)$element[$val['model_id']]['refletion']; + $item['scale'] = $element[$val['model_id']]['scale']; + $item['sku_id'] = $val['product_id']; + $item['tid'] = $element[$val['model_id']]['title']; + $item['rotation'] = $element[$val['model_id']]['rotation']; + $item['filePath'] = '';//todo 文件路径,针对千人千面 + + //组装data数据 + $tempData = []; + //获取材质模式对应关系 + $mode = $element[$val['model_id']]['mode'] ? json_decode($element[$val['model_id']]['mode'], true) : []; + // $base_img = (new ImageService())->base64EncodeImageNoHeader(\Yii::$app->params['baseurl'].$imageData[$val['id']]['imgurl']); + $base_img = \Yii::$app->params['h5Url'].'/storage'.$imageData[$val['id']]['imgurl']; + //判断是否包含base数据 即对应建模那边的model + if($element[$val['model_id']]['base']){ + $tempData[] = [ + 'name' => 'model', + 'data' => '0,'.$base_img.','.$element[$val['model_id']]['base'], + 'type' => 'other', + 'layer' => '0', + 'is_update' => 1, + 'mode' => $mode['model'], + ]; + } + if($element[$val['model_id']]['shadow']){ + $tempData[] = [ + 'name' => 'shadow', + 'data' => $element[$val['model_id']]['shadow'], + 'type' => 'other', + 'layer' => '0', + 'is_update' => 0, + 'mode' => $mode['shadow'], + ]; + } + if($element[$val['model_id']]['model_p']){ + $tempData[] = [ + 'name' => 'model_P', + 'data' => '0,'.$element[$val['model_id']]['model_p'], + 'type' => 'other', + 'layer' => '0', + 'is_update' => 0, + 'mode' => $mode['model_P'], + ]; + } + $item['data'] = $tempData; + $result[] = $item; + + } + $log = new CloudRenderLog(); + $log->title = '接收到python刀版图 -> 3-组装MQ渲染任务队列'; + $log->time = $render->getMillisecond() - $time_pinjie_begin; + $log->user_id = $user_id; + $log->post_data = ''; + $log->post_url = ''; + $log->result = $res; + $log->tag = $inputData['id']; + $log->ctime = time(); + $log->save(false); + } + + $sendData = [ + 'id' => $inputData['id'], + 'order_id' => 0, + 'user_id' => \Yii::$app->user->id, + 'sku_ids' => $inputData['sku_ids'], + 'tids' => $elementTitles, + 'data' => $result, + 'is_thousand_face' => 0, + 'folder' => '',//todo 千人千面需要使用 + ]; + return $sendData;*/ return nil } diff --git a/server/render/render.go b/server/render/render.go index 1210715d..acb9d019 100644 --- a/server/render/render.go +++ b/server/render/render.go @@ -35,6 +35,7 @@ func main() { //消费渲染前组装数据队列 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_ASSEMBLE_RENDER_DATA, &consumer.MqConsumerRenderAssemble{}) handler.RegisterHandlers(server, ctx) diff --git a/server/websocket/internal/logic/mq_consumer.go b/server/websocket/internal/logic/mq_consumer.go index c28ff2d6..7488e229 100644 --- a/server/websocket/internal/logic/mq_consumer.go +++ b/server/websocket/internal/logic/mq_consumer.go @@ -1,6 +1,7 @@ package logic import ( + "context" "encoding/json" "fusenapi/constants" "fusenapi/utils/websocket_data" @@ -11,7 +12,7 @@ import ( type MqConsumerRenderResult struct { } -func (m *MqConsumerRenderResult) Run(data []byte) error { +func (m *MqConsumerRenderResult) Run(ctx context.Context, data []byte) error { logx.Info("接收到MqConsumerRenderResult数据:", string(data)) var parseInfo websocket_data.RenderImageNotify if err := json.Unmarshal(data, &parseInfo); err != nil { diff --git a/server/websocket/internal/logic/ws_render_image_logic.go b/server/websocket/internal/logic/ws_render_image_logic.go index d4974870..978154d0 100644 --- a/server/websocket/internal/logic/ws_render_image_logic.go +++ b/server/websocket/internal/logic/ws_render_image_logic.go @@ -30,6 +30,7 @@ func (w *wsConnectItem) renderImage(data []byte) { return } logx.Info("收到请求云渲染图片数据:", renderImageData) + renderImageData.RenderData.UserId = w.userId //把需要渲染的图片任务加进去 taskId := hash.JsonHashKey(renderImageData.RenderData) w.renderProperty.renderImageTaskCtlChan <- renderImageControlChanItem{ @@ -39,7 +40,7 @@ func (w *wsConnectItem) renderImage(data []byte) { } tmpData := websocket_data.AssembleRenderData{ TaskId: taskId, - UserId: w.userId, + RenderId: renderImageData.RenderId, RenderData: renderImageData.RenderData, } d, _ := json.Marshal(tmpData) diff --git a/server/websocket/websocket.go b/server/websocket/websocket.go index 202e57fd..cfc775f7 100644 --- a/server/websocket/websocket.go +++ b/server/websocket/websocket.go @@ -33,6 +33,7 @@ func main() { //消费渲染结果队列 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) diff --git a/utils/mq_consumer_factory/mq.go b/utils/mq_consumer_factory/mq.go index 0f3bc97d..d2b7e1d8 100644 --- a/utils/mq_consumer_factory/mq.go +++ b/utils/mq_consumer_factory/mq.go @@ -1,6 +1,8 @@ package mq_consumer_factory +import "context" + // 消费mq消息要实现对应Run方法 type MqHandle interface { - Run(data []byte) error + Run(ctx context.Context, data []byte) error } diff --git a/utils/websocket_data/render_data.go b/utils/websocket_data/render_data.go index 09a203da..5ec90785 100644 --- a/utils/websocket_data/render_data.go +++ b/utils/websocket_data/render_data.go @@ -37,6 +37,6 @@ type ThirdPartyLoginRspMsg struct { // 发送到渲染组装的mq数据 type AssembleRenderData struct { TaskId string `json:"task_id"` - UserId int64 `json:"user_id"` + RenderId string `json:"render_id"` RenderData RenderData `json:"render_data"` }