From ee0433464ffae17d1464a8cd7d777bdf9f84e014 Mon Sep 17 00:00:00 2001 From: zerosaturation Date: Fri, 22 May 2026 00:14:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E9=93=B8=E9=80=A0?= =?UTF-8?q?=E6=B6=88=E8=80=97=E7=A1=AE=E8=AE=A4=E6=A1=86=E5=92=8C=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=89=B9=E9=87=8F=E8=B4=AD=E4=B9=B0=E9=81=93=E5=85=B7?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BF=AE=E6=94=B9=E5=9B=9E?= =?UTF-8?q?=E9=80=80=E6=8C=89=E9=92=AE=E7=9A=84=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gateway/controller/activity_controller.go | 145 +++++ .../gateway/controller/asset_controller.go | 2 +- backend/gateway/router/router.go | 3 +- backend/pkg/proto/activity/activity.pb.go | 497 ++++++++++++++---- backend/pkg/proto/activity/activity.triple.go | 29 +- backend/pkg/proto/asset/asset.pb.go | 10 +- backend/pkg/proto/asset/asset.triple.go | 64 ++- backend/proto/activity.proto | 40 ++ backend/proto/asset.proto | 2 +- backend/scripts/compile-proto.sh | 22 + .../provider/activity_provider.go | 32 ++ .../service/activity_service.go | 219 ++++++++ .../assetService/provider/asset_provider.go | 2 +- .../assetService/service/mint_service.go | 56 +- frontend/components/ConfirmModal.vue | 189 +++++-- frontend/pages/ai-dazi/index.vue | 17 +- .../castlove/lenticular/lenticular-result.vue | 256 +++++---- .../lenticular/lenticular-thinking.vue | 23 +- frontend/pages/components/CastloveContent.vue | 1 + frontend/pages/components/Header.vue | 1 + frontend/pages/discover/discover.vue | 1 + frontend/pages/profile/hisWorks.vue | 1 + frontend/pages/profile/myWorks.vue | 1 + frontend/pages/profile/selectRole.vue | 15 +- frontend/pages/profile/setNickname.vue | 2 +- .../support-activity/components/ActionBar.vue | 79 +-- frontend/pages/tasks/daily-tasks.vue | 1 + .../icon/{confimbj.png => confirmbj.png} | Bin frontend/utils/api.js | 11 + 29 files changed, 1307 insertions(+), 414 deletions(-) rename frontend/static/icon/{confimbj.png => confirmbj.png} (100%) diff --git a/backend/gateway/controller/activity_controller.go b/backend/gateway/controller/activity_controller.go index 22fd5f2..16bf983 100644 --- a/backend/gateway/controller/activity_controller.go +++ b/backend/gateway/controller/activity_controller.go @@ -343,6 +343,131 @@ func (ctrl *ActivityController) PurchaseItem(c *gin.Context) { response.Success(c, data) } +// BatchPurchaseItem 批量购买道具 +// @Summary 批量购买道具 +// @Description 批量购买活动道具 +// @Tags activities +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param activity_id path int64 true "活动ID" +// @Param request body pbActivity.BatchPurchaseItemRequest true "批量购买请求" +// @Success 200 {object} response.Response +// @Router /api/v1/activities/{activity_id}/batch-purchase [post] +func (ctrl *ActivityController) BatchPurchaseItem(c *gin.Context) { + // 从上下文获取用户信息 + userID, exists := c.Get("user_id") + if !exists { + response.Error(c, http.StatusUnauthorized, "未授权") + return + } + starID, exists := c.Get("star_id") + if !exists { + response.Error(c, http.StatusUnauthorized, "未授权") + return + } + + // 解析路径参数 + activityIDStr := c.Param("id") + activityID, err := strconv.ParseInt(activityIDStr, 10, 64) + if err != nil { + response.Error(c, http.StatusBadRequest, "活动ID参数错误") + return + } + + // 解析请求体 + var req struct { + Items []struct { + ItemType string `json:"item_type"` + Quantity int `json:"quantity"` + } `json:"items"` + } + if err := c.ShouldBindJSON(&req); err != nil { + response.Error(c, http.StatusBadRequest, "请求参数错误") + return + } + + if len(req.Items) == 0 { + response.Error(c, http.StatusBadRequest, "items 是必填参数") + return + } + + logger.Logger.Info("BatchPurchaseItem request", + zap.Int64("user_id", userID.(int64)), + zap.Int64("star_id", starID.(int64)), + zap.Int64("activity_id", activityID), + zap.Int("items_count", len(req.Items)), + ) + + // 设置上下文 + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{ + "user_id": strconv.FormatInt(userID.(int64), 10), + "star_id": strconv.FormatInt(starID.(int64), 10), + }) + + // 转换请求 + pbItems := make([]*pbActivity.PurchaseItem, len(req.Items)) + for i, item := range req.Items { + quantity := int32(item.Quantity) + if quantity <= 0 { + quantity = 1 + } + pbItems[i] = &pbActivity.PurchaseItem{ + ItemType: item.ItemType, + Quantity: quantity, + } + } + + // 调用 RPC + resp, err := ctrl.activityService.BatchPurchaseItem(ctx, &pbActivity.BatchPurchaseItemRequest{ + ActivityId: activityID, + Items: pbItems, + StarId: starID.(int64), + UserId: userID.(int64), + }) + + if err != nil { + logger.Logger.Error("BatchPurchaseItem RPC failed", zap.Error(err)) + response.Error(c, http.StatusInternalServerError, "批量购买道具失败") + return + } + + if resp.Base.Code != pbCommon.StatusCode_STATUS_OK { + response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message) + return + } + + // 非 active 阶段:通过 message 信号返回 200 + activity_status + activityStatusMap := map[string]string{ + "activity:expired": "expired", + "activity:pending": "pending", + "activity:completed": "completed", + "activity:incomplete": "incomplete", + "activity:active": "active", + } + activityMessageMap := map[string]string{ + "expired": "活动已结束", + "pending": "活动未开始", + "completed": "活动已完成", + "incomplete": "活动未完成", + "active": "活动进行中", + } + if status, ok := activityStatusMap[resp.Base.Message]; ok { + response.Success(c, map[string]interface{}{ + "activity_status": status, + "message": activityMessageMap[status], + }) + return + } + + // 正常购买成功 + data := convertBatchPurchaseResponse(resp) + response.Success(c, data) +} + // GetContributionRanking 获取贡献点排名 // @Summary 获取贡献点排名 // @Description 获取活动贡献点排名 @@ -742,6 +867,26 @@ func convertPurchaseResponse(resp *pbActivity.PurchaseItemResponse) map[string]i } } +// convertBatchPurchaseResponse 转换批量购买响应 +func convertBatchPurchaseResponse(resp *pbActivity.BatchPurchaseItemResponse) map[string]interface{} { + fails := make([]map[string]interface{}, 0, len(resp.Fails)) + for _, fail := range resp.Fails { + fails = append(fails, map[string]interface{}{ + "item_type": fail.ItemType, + "reason": fail.Reason, + }) + } + return map[string]interface{}{ + "total_crystal_spent": resp.TotalCrystalSpent, + "total_contribution": resp.TotalContribution, + "current_progress": resp.CurrentProgress, + "remaining_balance": resp.RemainingBalance, + "success_count": resp.SuccessCount, + "fail_count": resp.FailCount, + "fails": fails, + } +} + // convertContributionRankingResponse 转换排名响应 func convertContributionRankingResponse(resp *pbActivity.ContributionRankingResponse) map[string]interface{} { items := make([]map[string]interface{}, 0, len(resp.Items)) diff --git a/backend/gateway/controller/asset_controller.go b/backend/gateway/controller/asset_controller.go index ace8372..170f090 100644 --- a/backend/gateway/controller/asset_controller.go +++ b/backend/gateway/controller/asset_controller.go @@ -286,7 +286,7 @@ func (ctrl *AssetController) EstimateMintCost(c *gin.Context) { "current_balance": resp.CurrentBalance, "balance_after": resp.BalanceAfter, "mint_count": resp.MintCount, - "next_tier_hint": resp.NextTierHint, + "next_tier_cost": resp.NextTierCost, } response.Success(c, data) } diff --git a/backend/gateway/router/router.go b/backend/gateway/router/router.go index 2d632e2..ba78a78 100644 --- a/backend/gateway/router/router.go +++ b/backend/gateway/router/router.go @@ -248,7 +248,8 @@ func SetupRouter(userClient *client.Client, socialClient *client.Client, assetCl activities.GET("/:id", activityCtrl.GetActivity) // 获取活动详情 activities.GET("/:id/items", activityCtrl.GetActivityItems) // 获取活动道具列表 activities.GET("/:id/progress", activityCtrl.GetProgress) // 获取活动进度 - activities.POST("/:id/purchase", activityCtrl.PurchaseItem) // 购买道具 + activities.POST("/:id/purchase", activityCtrl.PurchaseItem) // 购买道具 + activities.POST("/:id/batch-purchase", activityCtrl.BatchPurchaseItem) // 批量购买道具 activities.GET("/:id/ranking", activityCtrl.GetContributionRanking) // 获取贡献点排名 activities.GET("/:id/contributions/latest", activityCtrl.GetLatestContributions) // 获取最新贡献记录 } diff --git a/backend/pkg/proto/activity/activity.pb.go b/backend/pkg/proto/activity/activity.pb.go index d64a75c..590c45e 100644 --- a/backend/pkg/proto/activity/activity.pb.go +++ b/backend/pkg/proto/activity/activity.pb.go @@ -496,6 +496,282 @@ func (x *PurchaseItemResponse) GetRemainingBalance() int64 { return 0 } +// 单个购买项(用于批量购买) +type PurchaseItem struct { + state protoimpl.MessageState `protogen:"open.v1"` + ItemType string `protobuf:"bytes,1,opt,name=item_type,json=itemType,proto3" json:"item_type,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PurchaseItem) Reset() { + *x = PurchaseItem{} + mi := &file_activity_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PurchaseItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PurchaseItem) ProtoMessage() {} + +func (x *PurchaseItem) ProtoReflect() protoreflect.Message { + mi := &file_activity_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PurchaseItem.ProtoReflect.Descriptor instead. +func (*PurchaseItem) Descriptor() ([]byte, []int) { + return file_activity_proto_rawDescGZIP(), []int{5} +} + +func (x *PurchaseItem) GetItemType() string { + if x != nil { + return x.ItemType + } + return "" +} + +func (x *PurchaseItem) GetQuantity() int32 { + if x != nil { + return x.Quantity + } + return 0 +} + +// 批量购买道具请求 +type BatchPurchaseItemRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ActivityId int64 `protobuf:"varint,1,opt,name=activity_id,json=activityId,proto3" json:"activity_id,omitempty"` + Items []*PurchaseItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"` // 购买项列表 + StarId int64 `protobuf:"varint,3,opt,name=star_id,json=starId,proto3" json:"star_id,omitempty"` + UserId int64 `protobuf:"varint,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 当前用户ID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BatchPurchaseItemRequest) Reset() { + *x = BatchPurchaseItemRequest{} + mi := &file_activity_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BatchPurchaseItemRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchPurchaseItemRequest) ProtoMessage() {} + +func (x *BatchPurchaseItemRequest) ProtoReflect() protoreflect.Message { + mi := &file_activity_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchPurchaseItemRequest.ProtoReflect.Descriptor instead. +func (*BatchPurchaseItemRequest) Descriptor() ([]byte, []int) { + return file_activity_proto_rawDescGZIP(), []int{6} +} + +func (x *BatchPurchaseItemRequest) GetActivityId() int64 { + if x != nil { + return x.ActivityId + } + return 0 +} + +func (x *BatchPurchaseItemRequest) GetItems() []*PurchaseItem { + if x != nil { + return x.Items + } + return nil +} + +func (x *BatchPurchaseItemRequest) GetStarId() int64 { + if x != nil { + return x.StarId + } + return 0 +} + +func (x *BatchPurchaseItemRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +// 批量购买道具响应 +type BatchPurchaseItemResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"` + TotalCrystalSpent int64 `protobuf:"varint,2,opt,name=total_crystal_spent,json=totalCrystalSpent,proto3" json:"total_crystal_spent,omitempty"` // 本次消费水晶 + TotalContribution int64 `protobuf:"varint,3,opt,name=total_contribution,json=totalContribution,proto3" json:"total_contribution,omitempty"` // 本次获得贡献点 + CurrentProgress int64 `protobuf:"varint,4,opt,name=current_progress,json=currentProgress,proto3" json:"current_progress,omitempty"` // 当前活动进度 + RemainingBalance int64 `protobuf:"varint,5,opt,name=remaining_balance,json=remainingBalance,proto3" json:"remaining_balance,omitempty"` // 剩余水晶余额 + SuccessCount int32 `protobuf:"varint,6,opt,name=success_count,json=successCount,proto3" json:"success_count,omitempty"` // 成功购买数量 + FailCount int32 `protobuf:"varint,7,opt,name=fail_count,json=failCount,proto3" json:"fail_count,omitempty"` // 失败购买数量 + Fails []*PurchaseFailItem `protobuf:"bytes,8,rep,name=fails,proto3" json:"fails,omitempty"` // 失败的项 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BatchPurchaseItemResponse) Reset() { + *x = BatchPurchaseItemResponse{} + mi := &file_activity_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BatchPurchaseItemResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchPurchaseItemResponse) ProtoMessage() {} + +func (x *BatchPurchaseItemResponse) ProtoReflect() protoreflect.Message { + mi := &file_activity_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchPurchaseItemResponse.ProtoReflect.Descriptor instead. +func (*BatchPurchaseItemResponse) Descriptor() ([]byte, []int) { + return file_activity_proto_rawDescGZIP(), []int{7} +} + +func (x *BatchPurchaseItemResponse) GetBase() *common.BaseResponse { + if x != nil { + return x.Base + } + return nil +} + +func (x *BatchPurchaseItemResponse) GetTotalCrystalSpent() int64 { + if x != nil { + return x.TotalCrystalSpent + } + return 0 +} + +func (x *BatchPurchaseItemResponse) GetTotalContribution() int64 { + if x != nil { + return x.TotalContribution + } + return 0 +} + +func (x *BatchPurchaseItemResponse) GetCurrentProgress() int64 { + if x != nil { + return x.CurrentProgress + } + return 0 +} + +func (x *BatchPurchaseItemResponse) GetRemainingBalance() int64 { + if x != nil { + return x.RemainingBalance + } + return 0 +} + +func (x *BatchPurchaseItemResponse) GetSuccessCount() int32 { + if x != nil { + return x.SuccessCount + } + return 0 +} + +func (x *BatchPurchaseItemResponse) GetFailCount() int32 { + if x != nil { + return x.FailCount + } + return 0 +} + +func (x *BatchPurchaseItemResponse) GetFails() []*PurchaseFailItem { + if x != nil { + return x.Fails + } + return nil +} + +// 购买失败的项 +type PurchaseFailItem struct { + state protoimpl.MessageState `protogen:"open.v1"` + ItemType string `protobuf:"bytes,1,opt,name=item_type,json=itemType,proto3" json:"item_type,omitempty"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PurchaseFailItem) Reset() { + *x = PurchaseFailItem{} + mi := &file_activity_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PurchaseFailItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PurchaseFailItem) ProtoMessage() {} + +func (x *PurchaseFailItem) ProtoReflect() protoreflect.Message { + mi := &file_activity_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PurchaseFailItem.ProtoReflect.Descriptor instead. +func (*PurchaseFailItem) Descriptor() ([]byte, []int) { + return file_activity_proto_rawDescGZIP(), []int{8} +} + +func (x *PurchaseFailItem) GetItemType() string { + if x != nil { + return x.ItemType + } + return "" +} + +func (x *PurchaseFailItem) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + // 贡献点排名请求 type ContributionRankingRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -510,7 +786,7 @@ type ContributionRankingRequest struct { func (x *ContributionRankingRequest) Reset() { *x = ContributionRankingRequest{} - mi := &file_activity_proto_msgTypes[5] + mi := &file_activity_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -522,7 +798,7 @@ func (x *ContributionRankingRequest) String() string { func (*ContributionRankingRequest) ProtoMessage() {} func (x *ContributionRankingRequest) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[5] + mi := &file_activity_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -535,7 +811,7 @@ func (x *ContributionRankingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ContributionRankingRequest.ProtoReflect.Descriptor instead. func (*ContributionRankingRequest) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{5} + return file_activity_proto_rawDescGZIP(), []int{9} } func (x *ContributionRankingRequest) GetActivityId() int64 { @@ -588,7 +864,7 @@ type ContributionRankingItem struct { func (x *ContributionRankingItem) Reset() { *x = ContributionRankingItem{} - mi := &file_activity_proto_msgTypes[6] + mi := &file_activity_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -600,7 +876,7 @@ func (x *ContributionRankingItem) String() string { func (*ContributionRankingItem) ProtoMessage() {} func (x *ContributionRankingItem) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[6] + mi := &file_activity_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -613,7 +889,7 @@ func (x *ContributionRankingItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ContributionRankingItem.ProtoReflect.Descriptor instead. func (*ContributionRankingItem) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{6} + return file_activity_proto_rawDescGZIP(), []int{10} } func (x *ContributionRankingItem) GetRank() int32 { @@ -673,7 +949,7 @@ type ContributionRankingResponse struct { func (x *ContributionRankingResponse) Reset() { *x = ContributionRankingResponse{} - mi := &file_activity_proto_msgTypes[7] + mi := &file_activity_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -685,7 +961,7 @@ func (x *ContributionRankingResponse) String() string { func (*ContributionRankingResponse) ProtoMessage() {} func (x *ContributionRankingResponse) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[7] + mi := &file_activity_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -698,7 +974,7 @@ func (x *ContributionRankingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ContributionRankingResponse.ProtoReflect.Descriptor instead. func (*ContributionRankingResponse) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{7} + return file_activity_proto_rawDescGZIP(), []int{11} } func (x *ContributionRankingResponse) GetBase() *common.BaseResponse { @@ -758,7 +1034,7 @@ type MyContribution struct { func (x *MyContribution) Reset() { *x = MyContribution{} - mi := &file_activity_proto_msgTypes[8] + mi := &file_activity_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -770,7 +1046,7 @@ func (x *MyContribution) String() string { func (*MyContribution) ProtoMessage() {} func (x *MyContribution) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[8] + mi := &file_activity_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -783,7 +1059,7 @@ func (x *MyContribution) ProtoReflect() protoreflect.Message { // Deprecated: Use MyContribution.ProtoReflect.Descriptor instead. func (*MyContribution) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{8} + return file_activity_proto_rawDescGZIP(), []int{12} } func (x *MyContribution) GetRank() int32 { @@ -841,7 +1117,7 @@ type GetActivityListRequest struct { func (x *GetActivityListRequest) Reset() { *x = GetActivityListRequest{} - mi := &file_activity_proto_msgTypes[9] + mi := &file_activity_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -853,7 +1129,7 @@ func (x *GetActivityListRequest) String() string { func (*GetActivityListRequest) ProtoMessage() {} func (x *GetActivityListRequest) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[9] + mi := &file_activity_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -866,7 +1142,7 @@ func (x *GetActivityListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActivityListRequest.ProtoReflect.Descriptor instead. func (*GetActivityListRequest) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{9} + return file_activity_proto_rawDescGZIP(), []int{13} } func (x *GetActivityListRequest) GetStarId() int64 { @@ -911,7 +1187,7 @@ type GetActivityListResponse struct { func (x *GetActivityListResponse) Reset() { *x = GetActivityListResponse{} - mi := &file_activity_proto_msgTypes[10] + mi := &file_activity_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -923,7 +1199,7 @@ func (x *GetActivityListResponse) String() string { func (*GetActivityListResponse) ProtoMessage() {} func (x *GetActivityListResponse) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[10] + mi := &file_activity_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -936,7 +1212,7 @@ func (x *GetActivityListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActivityListResponse.ProtoReflect.Descriptor instead. func (*GetActivityListResponse) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{10} + return file_activity_proto_rawDescGZIP(), []int{14} } func (x *GetActivityListResponse) GetBase() *common.BaseResponse { @@ -984,7 +1260,7 @@ type GetProgressRequest struct { func (x *GetProgressRequest) Reset() { *x = GetProgressRequest{} - mi := &file_activity_proto_msgTypes[11] + mi := &file_activity_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -996,7 +1272,7 @@ func (x *GetProgressRequest) String() string { func (*GetProgressRequest) ProtoMessage() {} func (x *GetProgressRequest) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[11] + mi := &file_activity_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1009,7 +1285,7 @@ func (x *GetProgressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProgressRequest.ProtoReflect.Descriptor instead. func (*GetProgressRequest) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{11} + return file_activity_proto_rawDescGZIP(), []int{15} } func (x *GetProgressRequest) GetActivityId() int64 { @@ -1035,7 +1311,7 @@ type GetProgressResponse struct { func (x *GetProgressResponse) Reset() { *x = GetProgressResponse{} - mi := &file_activity_proto_msgTypes[12] + mi := &file_activity_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1047,7 +1323,7 @@ func (x *GetProgressResponse) String() string { func (*GetProgressResponse) ProtoMessage() {} func (x *GetProgressResponse) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[12] + mi := &file_activity_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1060,7 +1336,7 @@ func (x *GetProgressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProgressResponse.ProtoReflect.Descriptor instead. func (*GetProgressResponse) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{12} + return file_activity_proto_rawDescGZIP(), []int{16} } func (x *GetProgressResponse) GetBase() *common.BaseResponse { @@ -1130,7 +1406,7 @@ type MintingActivity struct { func (x *MintingActivity) Reset() { *x = MintingActivity{} - mi := &file_activity_proto_msgTypes[13] + mi := &file_activity_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1142,7 +1418,7 @@ func (x *MintingActivity) String() string { func (*MintingActivity) ProtoMessage() {} func (x *MintingActivity) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[13] + mi := &file_activity_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1155,7 +1431,7 @@ func (x *MintingActivity) ProtoReflect() protoreflect.Message { // Deprecated: Use MintingActivity.ProtoReflect.Descriptor instead. func (*MintingActivity) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{13} + return file_activity_proto_rawDescGZIP(), []int{17} } func (x *MintingActivity) GetId() int64 { @@ -1233,7 +1509,7 @@ type GetMintingActivitiesRequest struct { func (x *GetMintingActivitiesRequest) Reset() { *x = GetMintingActivitiesRequest{} - mi := &file_activity_proto_msgTypes[14] + mi := &file_activity_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1245,7 +1521,7 @@ func (x *GetMintingActivitiesRequest) String() string { func (*GetMintingActivitiesRequest) ProtoMessage() {} func (x *GetMintingActivitiesRequest) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[14] + mi := &file_activity_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1258,7 +1534,7 @@ func (x *GetMintingActivitiesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMintingActivitiesRequest.ProtoReflect.Descriptor instead. func (*GetMintingActivitiesRequest) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{14} + return file_activity_proto_rawDescGZIP(), []int{18} } func (x *GetMintingActivitiesRequest) GetStarId() int64 { @@ -1296,7 +1572,7 @@ type GetMintingActivitiesResponse struct { func (x *GetMintingActivitiesResponse) Reset() { *x = GetMintingActivitiesResponse{} - mi := &file_activity_proto_msgTypes[15] + mi := &file_activity_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1308,7 +1584,7 @@ func (x *GetMintingActivitiesResponse) String() string { func (*GetMintingActivitiesResponse) ProtoMessage() {} func (x *GetMintingActivitiesResponse) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[15] + mi := &file_activity_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1321,7 +1597,7 @@ func (x *GetMintingActivitiesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMintingActivitiesResponse.ProtoReflect.Descriptor instead. func (*GetMintingActivitiesResponse) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{15} + return file_activity_proto_rawDescGZIP(), []int{19} } func (x *GetMintingActivitiesResponse) GetBase() *common.BaseResponse { @@ -1372,7 +1648,7 @@ type GetLatestContributionsRequest struct { func (x *GetLatestContributionsRequest) Reset() { *x = GetLatestContributionsRequest{} - mi := &file_activity_proto_msgTypes[16] + mi := &file_activity_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1384,7 +1660,7 @@ func (x *GetLatestContributionsRequest) String() string { func (*GetLatestContributionsRequest) ProtoMessage() {} func (x *GetLatestContributionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[16] + mi := &file_activity_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1397,7 +1673,7 @@ func (x *GetLatestContributionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLatestContributionsRequest.ProtoReflect.Descriptor instead. func (*GetLatestContributionsRequest) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{16} + return file_activity_proto_rawDescGZIP(), []int{20} } func (x *GetLatestContributionsRequest) GetActivityId() int64 { @@ -1449,7 +1725,7 @@ type ContributionRecord struct { func (x *ContributionRecord) Reset() { *x = ContributionRecord{} - mi := &file_activity_proto_msgTypes[17] + mi := &file_activity_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1461,7 +1737,7 @@ func (x *ContributionRecord) String() string { func (*ContributionRecord) ProtoMessage() {} func (x *ContributionRecord) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[17] + mi := &file_activity_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1474,7 +1750,7 @@ func (x *ContributionRecord) ProtoReflect() protoreflect.Message { // Deprecated: Use ContributionRecord.ProtoReflect.Descriptor instead. func (*ContributionRecord) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{17} + return file_activity_proto_rawDescGZIP(), []int{21} } func (x *ContributionRecord) GetId() int64 { @@ -1572,7 +1848,7 @@ type GetLatestContributionsResponse struct { func (x *GetLatestContributionsResponse) Reset() { *x = GetLatestContributionsResponse{} - mi := &file_activity_proto_msgTypes[18] + mi := &file_activity_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1584,7 +1860,7 @@ func (x *GetLatestContributionsResponse) String() string { func (*GetLatestContributionsResponse) ProtoMessage() {} func (x *GetLatestContributionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_activity_proto_msgTypes[18] + mi := &file_activity_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1597,7 +1873,7 @@ func (x *GetLatestContributionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLatestContributionsResponse.ProtoReflect.Descriptor instead. func (*GetLatestContributionsResponse) Descriptor() ([]byte, []int) { - return file_activity_proto_rawDescGZIP(), []int{18} + return file_activity_proto_rawDescGZIP(), []int{22} } func (x *GetLatestContributionsResponse) GetBase() *common.BaseResponse { @@ -1663,7 +1939,29 @@ const file_activity_proto_rawDesc = "" + "\x13total_crystal_spent\x18\x02 \x01(\x03R\x11totalCrystalSpent\x12-\n" + "\x12total_contribution\x18\x03 \x01(\x03R\x11totalContribution\x12)\n" + "\x10current_progress\x18\x04 \x01(\x03R\x0fcurrentProgress\x12+\n" + - "\x11remaining_balance\x18\x05 \x01(\x03R\x10remainingBalance\"\xa0\x01\n" + + "\x11remaining_balance\x18\x05 \x01(\x03R\x10remainingBalance\"G\n" + + "\fPurchaseItem\x12\x1b\n" + + "\titem_type\x18\x01 \x01(\tR\bitemType\x12\x1a\n" + + "\bquantity\x18\x02 \x01(\x05R\bquantity\"\xa3\x01\n" + + "\x18BatchPurchaseItemRequest\x12\x1f\n" + + "\vactivity_id\x18\x01 \x01(\x03R\n" + + "activityId\x124\n" + + "\x05items\x18\x02 \x03(\v2\x1e.topfans.activity.PurchaseItemR\x05items\x12\x17\n" + + "\astar_id\x18\x03 \x01(\x03R\x06starId\x12\x17\n" + + "\auser_id\x18\x04 \x01(\x03R\x06userId\"\x82\x03\n" + + "\x19BatchPurchaseItemResponse\x120\n" + + "\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12.\n" + + "\x13total_crystal_spent\x18\x02 \x01(\x03R\x11totalCrystalSpent\x12-\n" + + "\x12total_contribution\x18\x03 \x01(\x03R\x11totalContribution\x12)\n" + + "\x10current_progress\x18\x04 \x01(\x03R\x0fcurrentProgress\x12+\n" + + "\x11remaining_balance\x18\x05 \x01(\x03R\x10remainingBalance\x12#\n" + + "\rsuccess_count\x18\x06 \x01(\x05R\fsuccessCount\x12\x1d\n" + + "\n" + + "fail_count\x18\a \x01(\x05R\tfailCount\x128\n" + + "\x05fails\x18\b \x03(\v2\".topfans.activity.PurchaseFailItemR\x05fails\"G\n" + + "\x10PurchaseFailItem\x12\x1b\n" + + "\titem_type\x18\x01 \x01(\tR\bitemType\x12\x16\n" + + "\x06reason\x18\x02 \x01(\tR\x06reason\"\xa0\x01\n" + "\x1aContributionRankingRequest\x12\x1f\n" + "\vactivity_id\x18\x01 \x01(\x03R\n" + "activityId\x12\x17\n" + @@ -1769,13 +2067,15 @@ const file_activity_proto_rawDesc = "" + "created_at\x18\f \x01(\x03R\tcreatedAt\"\x92\x01\n" + "\x1eGetLatestContributionsResponse\x120\n" + "\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12>\n" + - "\arecords\x18\x02 \x03(\v2$.topfans.activity.ContributionRecordR\arecords2\xce\t\n" + + "\arecords\x18\x02 \x03(\v2$.topfans.activity.ContributionRecordR\arecords2\xf9\n" + + "\n" + "\x0fActivityService\x12\x82\x01\n" + "\x0fGetActivityList\x12(.topfans.activity.GetActivityListRequest\x1a).topfans.activity.GetActivityListResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\x12\x12/api/v1/activities\x12y\n" + "\vGetActivity\x12$.topfans.activity.GetProgressRequest\x1a\x1a.topfans.activity.Activity\"(\x82\xd3\xe4\x93\x02\"\x12 /api/v1/activities/{activity_id}\x12\x91\x01\n" + "\x10GetActivityItems\x12$.topfans.activity.GetProgressRequest\x1a'.topfans.activity.ActivityItemsResponse\".\x82\xd3\xe4\x93\x02(\x12&/api/v1/activities/{activity_id}/items\x12\x8d\x01\n" + "\vGetProgress\x12$.topfans.activity.GetProgressRequest\x1a%.topfans.activity.GetProgressResponse\"1\x82\xd3\xe4\x93\x02+\x12)/api/v1/activities/{activity_id}/progress\x12\x93\x01\n" + - "\fPurchaseItem\x12%.topfans.activity.PurchaseItemRequest\x1a&.topfans.activity.PurchaseItemResponse\"4\x82\xd3\xe4\x93\x02.:\x01*\")/api/v1/activities/{activity_id}/purchase\x12\xa7\x01\n" + + "\fPurchaseItem\x12%.topfans.activity.PurchaseItemRequest\x1a&.topfans.activity.PurchaseItemResponse\"4\x82\xd3\xe4\x93\x02.:\x01*\")/api/v1/activities/{activity_id}/purchase\x12\xa8\x01\n" + + "\x11BatchPurchaseItem\x12*.topfans.activity.BatchPurchaseItemRequest\x1a+.topfans.activity.BatchPurchaseItemResponse\":\x82\xd3\xe4\x93\x024:\x01*\"//api/v1/activities/{activity_id}/batch-purchase\x12\xa7\x01\n" + "\x16GetContributionRanking\x12,.topfans.activity.ContributionRankingRequest\x1a-.topfans.activity.ContributionRankingResponse\"0\x82\xd3\xe4\x93\x02*\x12(/api/v1/activities/{activity_id}/ranking\x12\x99\x01\n" + "\x14GetMintingActivities\x12-.topfans.activity.GetMintingActivitiesRequest\x1a..topfans.activity.GetMintingActivitiesResponse\"\"\x82\xd3\xe4\x93\x02\x1c\x12\x1a/api/v1/minting-activities\x12\xba\x01\n" + "\x16GetLatestContributions\x12/.topfans.activity.GetLatestContributionsRequest\x1a0.topfans.activity.GetLatestContributionsResponse\"=\x82\xd3\xe4\x93\x027\x125/api/v1/activities/{activity_id}/contributions/latestB8Z6github.com/topfans/backend/pkg/proto/activity;activityb\x06proto3" @@ -1792,64 +2092,73 @@ func file_activity_proto_rawDescGZIP() []byte { return file_activity_proto_rawDescData } -var file_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_activity_proto_goTypes = []any{ (*Activity)(nil), // 0: topfans.activity.Activity (*ActivityItem)(nil), // 1: topfans.activity.ActivityItem (*ActivityItemsResponse)(nil), // 2: topfans.activity.ActivityItemsResponse (*PurchaseItemRequest)(nil), // 3: topfans.activity.PurchaseItemRequest (*PurchaseItemResponse)(nil), // 4: topfans.activity.PurchaseItemResponse - (*ContributionRankingRequest)(nil), // 5: topfans.activity.ContributionRankingRequest - (*ContributionRankingItem)(nil), // 6: topfans.activity.ContributionRankingItem - (*ContributionRankingResponse)(nil), // 7: topfans.activity.ContributionRankingResponse - (*MyContribution)(nil), // 8: topfans.activity.MyContribution - (*GetActivityListRequest)(nil), // 9: topfans.activity.GetActivityListRequest - (*GetActivityListResponse)(nil), // 10: topfans.activity.GetActivityListResponse - (*GetProgressRequest)(nil), // 11: topfans.activity.GetProgressRequest - (*GetProgressResponse)(nil), // 12: topfans.activity.GetProgressResponse - (*MintingActivity)(nil), // 13: topfans.activity.MintingActivity - (*GetMintingActivitiesRequest)(nil), // 14: topfans.activity.GetMintingActivitiesRequest - (*GetMintingActivitiesResponse)(nil), // 15: topfans.activity.GetMintingActivitiesResponse - (*GetLatestContributionsRequest)(nil), // 16: topfans.activity.GetLatestContributionsRequest - (*ContributionRecord)(nil), // 17: topfans.activity.ContributionRecord - (*GetLatestContributionsResponse)(nil), // 18: topfans.activity.GetLatestContributionsResponse - (*common.BaseResponse)(nil), // 19: topfans.common.BaseResponse + (*PurchaseItem)(nil), // 5: topfans.activity.PurchaseItem + (*BatchPurchaseItemRequest)(nil), // 6: topfans.activity.BatchPurchaseItemRequest + (*BatchPurchaseItemResponse)(nil), // 7: topfans.activity.BatchPurchaseItemResponse + (*PurchaseFailItem)(nil), // 8: topfans.activity.PurchaseFailItem + (*ContributionRankingRequest)(nil), // 9: topfans.activity.ContributionRankingRequest + (*ContributionRankingItem)(nil), // 10: topfans.activity.ContributionRankingItem + (*ContributionRankingResponse)(nil), // 11: topfans.activity.ContributionRankingResponse + (*MyContribution)(nil), // 12: topfans.activity.MyContribution + (*GetActivityListRequest)(nil), // 13: topfans.activity.GetActivityListRequest + (*GetActivityListResponse)(nil), // 14: topfans.activity.GetActivityListResponse + (*GetProgressRequest)(nil), // 15: topfans.activity.GetProgressRequest + (*GetProgressResponse)(nil), // 16: topfans.activity.GetProgressResponse + (*MintingActivity)(nil), // 17: topfans.activity.MintingActivity + (*GetMintingActivitiesRequest)(nil), // 18: topfans.activity.GetMintingActivitiesRequest + (*GetMintingActivitiesResponse)(nil), // 19: topfans.activity.GetMintingActivitiesResponse + (*GetLatestContributionsRequest)(nil), // 20: topfans.activity.GetLatestContributionsRequest + (*ContributionRecord)(nil), // 21: topfans.activity.ContributionRecord + (*GetLatestContributionsResponse)(nil), // 22: topfans.activity.GetLatestContributionsResponse + (*common.BaseResponse)(nil), // 23: topfans.common.BaseResponse } var file_activity_proto_depIdxs = []int32{ 1, // 0: topfans.activity.Activity.items:type_name -> topfans.activity.ActivityItem 1, // 1: topfans.activity.ActivityItemsResponse.items:type_name -> topfans.activity.ActivityItem - 19, // 2: topfans.activity.PurchaseItemResponse.base:type_name -> topfans.common.BaseResponse - 19, // 3: topfans.activity.ContributionRankingResponse.base:type_name -> topfans.common.BaseResponse - 6, // 4: topfans.activity.ContributionRankingResponse.items:type_name -> topfans.activity.ContributionRankingItem - 8, // 5: topfans.activity.ContributionRankingResponse.my_contribution:type_name -> topfans.activity.MyContribution - 19, // 6: topfans.activity.GetActivityListResponse.base:type_name -> topfans.common.BaseResponse - 0, // 7: topfans.activity.GetActivityListResponse.activities:type_name -> topfans.activity.Activity - 19, // 8: topfans.activity.GetProgressResponse.base:type_name -> topfans.common.BaseResponse - 19, // 9: topfans.activity.GetMintingActivitiesResponse.base:type_name -> topfans.common.BaseResponse - 13, // 10: topfans.activity.GetMintingActivitiesResponse.activities:type_name -> topfans.activity.MintingActivity - 19, // 11: topfans.activity.GetLatestContributionsResponse.base:type_name -> topfans.common.BaseResponse - 17, // 12: topfans.activity.GetLatestContributionsResponse.records:type_name -> topfans.activity.ContributionRecord - 9, // 13: topfans.activity.ActivityService.GetActivityList:input_type -> topfans.activity.GetActivityListRequest - 11, // 14: topfans.activity.ActivityService.GetActivity:input_type -> topfans.activity.GetProgressRequest - 11, // 15: topfans.activity.ActivityService.GetActivityItems:input_type -> topfans.activity.GetProgressRequest - 11, // 16: topfans.activity.ActivityService.GetProgress:input_type -> topfans.activity.GetProgressRequest - 3, // 17: topfans.activity.ActivityService.PurchaseItem:input_type -> topfans.activity.PurchaseItemRequest - 5, // 18: topfans.activity.ActivityService.GetContributionRanking:input_type -> topfans.activity.ContributionRankingRequest - 14, // 19: topfans.activity.ActivityService.GetMintingActivities:input_type -> topfans.activity.GetMintingActivitiesRequest - 16, // 20: topfans.activity.ActivityService.GetLatestContributions:input_type -> topfans.activity.GetLatestContributionsRequest - 10, // 21: topfans.activity.ActivityService.GetActivityList:output_type -> topfans.activity.GetActivityListResponse - 0, // 22: topfans.activity.ActivityService.GetActivity:output_type -> topfans.activity.Activity - 2, // 23: topfans.activity.ActivityService.GetActivityItems:output_type -> topfans.activity.ActivityItemsResponse - 12, // 24: topfans.activity.ActivityService.GetProgress:output_type -> topfans.activity.GetProgressResponse - 4, // 25: topfans.activity.ActivityService.PurchaseItem:output_type -> topfans.activity.PurchaseItemResponse - 7, // 26: topfans.activity.ActivityService.GetContributionRanking:output_type -> topfans.activity.ContributionRankingResponse - 15, // 27: topfans.activity.ActivityService.GetMintingActivities:output_type -> topfans.activity.GetMintingActivitiesResponse - 18, // 28: topfans.activity.ActivityService.GetLatestContributions:output_type -> topfans.activity.GetLatestContributionsResponse - 21, // [21:29] is the sub-list for method output_type - 13, // [13:21] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 23, // 2: topfans.activity.PurchaseItemResponse.base:type_name -> topfans.common.BaseResponse + 5, // 3: topfans.activity.BatchPurchaseItemRequest.items:type_name -> topfans.activity.PurchaseItem + 23, // 4: topfans.activity.BatchPurchaseItemResponse.base:type_name -> topfans.common.BaseResponse + 8, // 5: topfans.activity.BatchPurchaseItemResponse.fails:type_name -> topfans.activity.PurchaseFailItem + 23, // 6: topfans.activity.ContributionRankingResponse.base:type_name -> topfans.common.BaseResponse + 10, // 7: topfans.activity.ContributionRankingResponse.items:type_name -> topfans.activity.ContributionRankingItem + 12, // 8: topfans.activity.ContributionRankingResponse.my_contribution:type_name -> topfans.activity.MyContribution + 23, // 9: topfans.activity.GetActivityListResponse.base:type_name -> topfans.common.BaseResponse + 0, // 10: topfans.activity.GetActivityListResponse.activities:type_name -> topfans.activity.Activity + 23, // 11: topfans.activity.GetProgressResponse.base:type_name -> topfans.common.BaseResponse + 23, // 12: topfans.activity.GetMintingActivitiesResponse.base:type_name -> topfans.common.BaseResponse + 17, // 13: topfans.activity.GetMintingActivitiesResponse.activities:type_name -> topfans.activity.MintingActivity + 23, // 14: topfans.activity.GetLatestContributionsResponse.base:type_name -> topfans.common.BaseResponse + 21, // 15: topfans.activity.GetLatestContributionsResponse.records:type_name -> topfans.activity.ContributionRecord + 13, // 16: topfans.activity.ActivityService.GetActivityList:input_type -> topfans.activity.GetActivityListRequest + 15, // 17: topfans.activity.ActivityService.GetActivity:input_type -> topfans.activity.GetProgressRequest + 15, // 18: topfans.activity.ActivityService.GetActivityItems:input_type -> topfans.activity.GetProgressRequest + 15, // 19: topfans.activity.ActivityService.GetProgress:input_type -> topfans.activity.GetProgressRequest + 3, // 20: topfans.activity.ActivityService.PurchaseItem:input_type -> topfans.activity.PurchaseItemRequest + 6, // 21: topfans.activity.ActivityService.BatchPurchaseItem:input_type -> topfans.activity.BatchPurchaseItemRequest + 9, // 22: topfans.activity.ActivityService.GetContributionRanking:input_type -> topfans.activity.ContributionRankingRequest + 18, // 23: topfans.activity.ActivityService.GetMintingActivities:input_type -> topfans.activity.GetMintingActivitiesRequest + 20, // 24: topfans.activity.ActivityService.GetLatestContributions:input_type -> topfans.activity.GetLatestContributionsRequest + 14, // 25: topfans.activity.ActivityService.GetActivityList:output_type -> topfans.activity.GetActivityListResponse + 0, // 26: topfans.activity.ActivityService.GetActivity:output_type -> topfans.activity.Activity + 2, // 27: topfans.activity.ActivityService.GetActivityItems:output_type -> topfans.activity.ActivityItemsResponse + 16, // 28: topfans.activity.ActivityService.GetProgress:output_type -> topfans.activity.GetProgressResponse + 4, // 29: topfans.activity.ActivityService.PurchaseItem:output_type -> topfans.activity.PurchaseItemResponse + 7, // 30: topfans.activity.ActivityService.BatchPurchaseItem:output_type -> topfans.activity.BatchPurchaseItemResponse + 11, // 31: topfans.activity.ActivityService.GetContributionRanking:output_type -> topfans.activity.ContributionRankingResponse + 19, // 32: topfans.activity.ActivityService.GetMintingActivities:output_type -> topfans.activity.GetMintingActivitiesResponse + 22, // 33: topfans.activity.ActivityService.GetLatestContributions:output_type -> topfans.activity.GetLatestContributionsResponse + 25, // [25:34] is the sub-list for method output_type + 16, // [16:25] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_activity_proto_init() } @@ -1863,7 +2172,7 @@ func file_activity_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_activity_proto_rawDesc), len(file_activity_proto_rawDesc)), NumEnums: 0, - NumMessages: 19, + NumMessages: 23, NumExtensions: 0, NumServices: 1, }, diff --git a/backend/pkg/proto/activity/activity.triple.go b/backend/pkg/proto/activity/activity.triple.go index 4e6dcc4..54c4030 100644 --- a/backend/pkg/proto/activity/activity.triple.go +++ b/backend/pkg/proto/activity/activity.triple.go @@ -46,6 +46,8 @@ const ( ActivityServiceGetProgressProcedure = "/topfans.activity.ActivityService/GetProgress" // ActivityServicePurchaseItemProcedure is the fully-qualified name of the ActivityService's PurchaseItem RPC. ActivityServicePurchaseItemProcedure = "/topfans.activity.ActivityService/PurchaseItem" + // ActivityServiceBatchPurchaseItemProcedure is the fully-qualified name of the ActivityService's BatchPurchaseItem RPC. + ActivityServiceBatchPurchaseItemProcedure = "/topfans.activity.ActivityService/BatchPurchaseItem" // ActivityServiceGetContributionRankingProcedure is the fully-qualified name of the ActivityService's GetContributionRanking RPC. ActivityServiceGetContributionRankingProcedure = "/topfans.activity.ActivityService/GetContributionRanking" // ActivityServiceGetMintingActivitiesProcedure is the fully-qualified name of the ActivityService's GetMintingActivities RPC. @@ -65,6 +67,7 @@ type ActivityService interface { GetActivityItems(ctx context.Context, req *GetProgressRequest, opts ...client.CallOption) (*ActivityItemsResponse, error) GetProgress(ctx context.Context, req *GetProgressRequest, opts ...client.CallOption) (*GetProgressResponse, error) PurchaseItem(ctx context.Context, req *PurchaseItemRequest, opts ...client.CallOption) (*PurchaseItemResponse, error) + BatchPurchaseItem(ctx context.Context, req *BatchPurchaseItemRequest, opts ...client.CallOption) (*BatchPurchaseItemResponse, error) GetContributionRanking(ctx context.Context, req *ContributionRankingRequest, opts ...client.CallOption) (*ContributionRankingResponse, error) GetMintingActivities(ctx context.Context, req *GetMintingActivitiesRequest, opts ...client.CallOption) (*GetMintingActivitiesResponse, error) GetLatestContributions(ctx context.Context, req *GetLatestContributionsRequest, opts ...client.CallOption) (*GetLatestContributionsResponse, error) @@ -130,6 +133,14 @@ func (c *ActivityServiceImpl) PurchaseItem(ctx context.Context, req *PurchaseIte return resp, nil } +func (c *ActivityServiceImpl) BatchPurchaseItem(ctx context.Context, req *BatchPurchaseItemRequest, opts ...client.CallOption) (*BatchPurchaseItemResponse, error) { + resp := new(BatchPurchaseItemResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "BatchPurchaseItem", opts...); err != nil { + return nil, err + } + return resp, nil +} + func (c *ActivityServiceImpl) GetContributionRanking(ctx context.Context, req *ContributionRankingRequest, opts ...client.CallOption) (*ContributionRankingResponse, error) { resp := new(ContributionRankingResponse) if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetContributionRanking", opts...); err != nil { @@ -156,7 +167,7 @@ func (c *ActivityServiceImpl) GetLatestContributions(ctx context.Context, req *G var ActivityService_ClientInfo = client.ClientInfo{ InterfaceName: "topfans.activity.ActivityService", - MethodNames: []string{"GetActivityList", "GetActivity", "GetActivityItems", "GetProgress", "PurchaseItem", "GetContributionRanking", "GetMintingActivities", "GetLatestContributions"}, + MethodNames: []string{"GetActivityList", "GetActivity", "GetActivityItems", "GetProgress", "PurchaseItem", "BatchPurchaseItem", "GetContributionRanking", "GetMintingActivities", "GetLatestContributions"}, ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { dubboCli := dubboCliRaw.(*ActivityServiceImpl) dubboCli.conn = conn @@ -170,6 +181,7 @@ type ActivityServiceHandler interface { GetActivityItems(context.Context, *GetProgressRequest) (*ActivityItemsResponse, error) GetProgress(context.Context, *GetProgressRequest) (*GetProgressResponse, error) PurchaseItem(context.Context, *PurchaseItemRequest) (*PurchaseItemResponse, error) + BatchPurchaseItem(context.Context, *BatchPurchaseItemRequest) (*BatchPurchaseItemResponse, error) GetContributionRanking(context.Context, *ContributionRankingRequest) (*ContributionRankingResponse, error) GetMintingActivities(context.Context, *GetMintingActivitiesRequest) (*GetMintingActivitiesResponse, error) GetLatestContributions(context.Context, *GetLatestContributionsRequest) (*GetLatestContributionsResponse, error) @@ -262,6 +274,21 @@ var ActivityService_ServiceInfo = server.ServiceInfo{ return triple_protocol.NewResponse(res), nil }, }, + { + Name: "BatchPurchaseItem", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(BatchPurchaseItemRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*BatchPurchaseItemRequest) + res, err := handler.(ActivityServiceHandler).BatchPurchaseItem(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, { Name: "GetContributionRanking", Type: constant.CallUnary, diff --git a/backend/pkg/proto/asset/asset.pb.go b/backend/pkg/proto/asset/asset.pb.go index eef9ae4..cb43c99 100644 --- a/backend/pkg/proto/asset/asset.pb.go +++ b/backend/pkg/proto/asset/asset.pb.go @@ -951,7 +951,7 @@ type EstimateMintCostResponse struct { CurrentBalance int64 `protobuf:"varint,3,opt,name=current_balance,json=currentBalance,proto3" json:"current_balance,omitempty"` // 当前余额(铸造前) BalanceAfter int64 `protobuf:"varint,4,opt,name=balance_after,json=balanceAfter,proto3" json:"balance_after,omitempty"` // 铸造后余额 MintCount int32 `protobuf:"varint,5,opt,name=mint_count,json=mintCount,proto3" json:"mint_count,omitempty"` // 本次是第几次铸造 - NextTierHint string `protobuf:"bytes,6,opt,name=next_tier_hint,json=nextTierHint,proto3" json:"next_tier_hint,omitempty"` // 下一阶梯提示 + NextTierCost int64 `protobuf:"varint,6,opt,name=next_tier_cost,json=nextTierCost,proto3" json:"next_tier_cost,omitempty"` // 下一阶梯费用 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1021,11 +1021,11 @@ func (x *EstimateMintCostResponse) GetMintCount() int32 { return 0 } -func (x *EstimateMintCostResponse) GetNextTierHint() string { +func (x *EstimateMintCostResponse) GetNextTierCost() int64 { if x != nil { - return x.NextTierHint + return x.NextTierCost } - return "" + return 0 } // 获取我的藏品列表请求 @@ -3736,7 +3736,7 @@ const file_asset_proto_rawDesc = "" + "\rbalance_after\x18\x04 \x01(\x03R\fbalanceAfter\x12\x1d\n" + "\n" + "mint_count\x18\x05 \x01(\x05R\tmintCount\x12$\n" + - "\x0enext_tier_hint\x18\x06 \x01(\tR\fnextTierHint\"\x8b\x01\n" + + "\x0enext_tier_cost\x18\x06 \x01(\x03R\fnextTierCost\"\x8b\x01\n" + "\x12GetMyAssetsRequest\x12\x12\n" + "\x04page\x18\x01 \x01(\x05R\x04page\x12\x1b\n" + "\tpage_size\x18\x02 \x01(\x05R\bpageSize\x12\x16\n" + diff --git a/backend/pkg/proto/asset/asset.triple.go b/backend/pkg/proto/asset/asset.triple.go index 249ea37..fcf6803 100644 --- a/backend/pkg/proto/asset/asset.triple.go +++ b/backend/pkg/proto/asset/asset.triple.go @@ -42,6 +42,8 @@ const ( AssetServicePreCreateMintOrderProcedure = "/topfans.asset.AssetService/PreCreateMintOrder" // AssetServiceCreateMintOrderProcedure is the fully-qualified name of the AssetService's CreateMintOrder RPC. AssetServiceCreateMintOrderProcedure = "/topfans.asset.AssetService/CreateMintOrder" + // AssetServiceEstimateMintCostProcedure is the fully-qualified name of the AssetService's EstimateMintCost RPC. + AssetServiceEstimateMintCostProcedure = "/topfans.asset.AssetService/EstimateMintCost" // AssetServiceGetMyAssetsProcedure is the fully-qualified name of the AssetService's GetMyAssets RPC. AssetServiceGetMyAssetsProcedure = "/topfans.asset.AssetService/GetMyAssets" // AssetServiceGetAssetProcedure is the fully-qualified name of the AssetService's GetAsset RPC. @@ -64,6 +66,16 @@ const ( AssetServiceGetAssetLikesProcedure = "/topfans.asset.AssetService/GetAssetLikes" // AssetServiceClearAssetLikeRecordsProcedure is the fully-qualified name of the AssetService's ClearAssetLikeRecords RPC. AssetServiceClearAssetLikeRecordsProcedure = "/topfans.asset.AssetService/ClearAssetLikeRecords" + // AssetServiceUploadMaterialProcedure is the fully-qualified name of the AssetService's UploadMaterial RPC. + AssetServiceUploadMaterialProcedure = "/topfans.asset.AssetService/UploadMaterial" + // AssetServiceBindAssetMaterialsProcedure is the fully-qualified name of the AssetService's BindAssetMaterials RPC. + AssetServiceBindAssetMaterialsProcedure = "/topfans.asset.AssetService/BindAssetMaterials" + // AssetServiceGetAssetMaterialsProcedure is the fully-qualified name of the AssetService's GetAssetMaterials RPC. + AssetServiceGetAssetMaterialsProcedure = "/topfans.asset.AssetService/GetAssetMaterials" + // AssetServiceUpdateMaterialLayerOrderProcedure is the fully-qualified name of the AssetService's UpdateMaterialLayerOrder RPC. + AssetServiceUpdateMaterialLayerOrderProcedure = "/topfans.asset.AssetService/UpdateMaterialLayerOrder" + // AssetServiceUnbindAssetMaterialProcedure is the fully-qualified name of the AssetService's UnbindAssetMaterial RPC. + AssetServiceUnbindAssetMaterialProcedure = "/topfans.asset.AssetService/UnbindAssetMaterial" ) var ( @@ -75,6 +87,7 @@ type AssetService interface { InitMintOrder(ctx context.Context, req *InitMintOrderRequest, opts ...client.CallOption) (*InitMintOrderResponse, error) PreCreateMintOrder(ctx context.Context, req *PreCreateMintOrderRequest, opts ...client.CallOption) (*PreCreateMintOrderResponse, error) CreateMintOrder(ctx context.Context, req *CreateMintOrderRequest, opts ...client.CallOption) (*CreateMintOrderResponse, error) + EstimateMintCost(ctx context.Context, req *EstimateMintCostRequest, opts ...client.CallOption) (*EstimateMintCostResponse, error) GetMyAssets(ctx context.Context, req *GetMyAssetsRequest, opts ...client.CallOption) (*GetMyAssetsResponse, error) GetAsset(ctx context.Context, req *GetAssetRequest, opts ...client.CallOption) (*GetAssetResponse, error) GetAssetStatus(ctx context.Context, req *GetAssetStatusRequest, opts ...client.CallOption) (*GetAssetStatusResponse, error) @@ -91,7 +104,6 @@ type AssetService interface { GetAssetMaterials(ctx context.Context, req *GetAssetMaterialsRequest, opts ...client.CallOption) (*GetAssetMaterialsResponse, error) UpdateMaterialLayerOrder(ctx context.Context, req *UpdateMaterialLayerOrderRequest, opts ...client.CallOption) (*UpdateMaterialLayerOrderResponse, error) UnbindAssetMaterial(ctx context.Context, req *UnbindAssetMaterialRequest, opts ...client.CallOption) (*UnbindAssetMaterialResponse, error) - EstimateMintCost(ctx context.Context, req *EstimateMintCostRequest, opts ...client.CallOption) (*EstimateMintCostResponse, error) } // NewAssetService constructs a client for the asset.AssetService service. @@ -138,6 +150,14 @@ func (c *AssetServiceImpl) CreateMintOrder(ctx context.Context, req *CreateMintO return resp, nil } +func (c *AssetServiceImpl) EstimateMintCost(ctx context.Context, req *EstimateMintCostRequest, opts ...client.CallOption) (*EstimateMintCostResponse, error) { + resp := new(EstimateMintCostResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "EstimateMintCost", opts...); err != nil { + return nil, err + } + return resp, nil +} + func (c *AssetServiceImpl) GetMyAssets(ctx context.Context, req *GetMyAssetsRequest, opts ...client.CallOption) (*GetMyAssetsResponse, error) { resp := new(GetMyAssetsResponse) if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyAssets", opts...); err != nil { @@ -266,17 +286,9 @@ func (c *AssetServiceImpl) UnbindAssetMaterial(ctx context.Context, req *UnbindA return resp, nil } -func (c *AssetServiceImpl) EstimateMintCost(ctx context.Context, req *EstimateMintCostRequest, opts ...client.CallOption) (*EstimateMintCostResponse, error) { - resp := new(EstimateMintCostResponse) - if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "EstimateMintCost", opts...); err != nil { - return nil, err - } - return resp, nil -} - var AssetService_ClientInfo = client.ClientInfo{ InterfaceName: "topfans.asset.AssetService", - MethodNames: []string{"InitMintOrder", "PreCreateMintOrder", "CreateMintOrder", "GetMyAssets", "GetAsset", "GetAssetStatus", "GetMintOrder", "CancelMintOrder", "GetAssetForRPC", "LikeAsset", "UnlikeAsset", "CheckAssetLike", "GetAssetLikes", "ClearAssetLikeRecords", "UploadMaterial", "BindAssetMaterials", "GetAssetMaterials", "UpdateMaterialLayerOrder", "UnbindAssetMaterial", "EstimateMintCost"}, + MethodNames: []string{"InitMintOrder", "PreCreateMintOrder", "CreateMintOrder", "EstimateMintCost", "GetMyAssets", "GetAsset", "GetAssetStatus", "GetMintOrder", "CancelMintOrder", "GetAssetForRPC", "LikeAsset", "UnlikeAsset", "CheckAssetLike", "GetAssetLikes", "ClearAssetLikeRecords", "UploadMaterial", "BindAssetMaterials", "GetAssetMaterials", "UpdateMaterialLayerOrder", "UnbindAssetMaterial"}, ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { dubboCli := dubboCliRaw.(*AssetServiceImpl) dubboCli.conn = conn @@ -288,6 +300,7 @@ type AssetServiceHandler interface { InitMintOrder(context.Context, *InitMintOrderRequest) (*InitMintOrderResponse, error) PreCreateMintOrder(context.Context, *PreCreateMintOrderRequest) (*PreCreateMintOrderResponse, error) CreateMintOrder(context.Context, *CreateMintOrderRequest) (*CreateMintOrderResponse, error) + EstimateMintCost(context.Context, *EstimateMintCostRequest) (*EstimateMintCostResponse, error) GetMyAssets(context.Context, *GetMyAssetsRequest) (*GetMyAssetsResponse, error) GetAsset(context.Context, *GetAssetRequest) (*GetAssetResponse, error) GetAssetStatus(context.Context, *GetAssetStatusRequest) (*GetAssetStatusResponse, error) @@ -304,7 +317,6 @@ type AssetServiceHandler interface { GetAssetMaterials(context.Context, *GetAssetMaterialsRequest) (*GetAssetMaterialsResponse, error) UpdateMaterialLayerOrder(context.Context, *UpdateMaterialLayerOrderRequest) (*UpdateMaterialLayerOrderResponse, error) UnbindAssetMaterial(context.Context, *UnbindAssetMaterialRequest) (*UnbindAssetMaterialResponse, error) - EstimateMintCost(context.Context, *EstimateMintCostRequest) (*EstimateMintCostResponse, error) } func RegisterAssetServiceHandler(srv *server.Server, hdlr AssetServiceHandler, opts ...server.ServiceOption) error { @@ -364,6 +376,21 @@ var AssetService_ServiceInfo = server.ServiceInfo{ return triple_protocol.NewResponse(res), nil }, }, + { + Name: "EstimateMintCost", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(EstimateMintCostRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*EstimateMintCostRequest) + res, err := handler.(AssetServiceHandler).EstimateMintCost(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, { Name: "GetMyAssets", Type: constant.CallUnary, @@ -604,20 +631,5 @@ var AssetService_ServiceInfo = server.ServiceInfo{ return triple_protocol.NewResponse(res), nil }, }, - { - Name: "EstimateMintCost", - Type: constant.CallUnary, - ReqInitFunc: func() interface{} { - return new(EstimateMintCostRequest) - }, - MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { - req := args[0].(*EstimateMintCostRequest) - res, err := handler.(AssetServiceHandler).EstimateMintCost(ctx, req) - if err != nil { - return nil, err - } - return triple_protocol.NewResponse(res), nil - }, - }, }, } diff --git a/backend/proto/activity.proto b/backend/proto/activity.proto index d7798a5..0a3a271 100644 --- a/backend/proto/activity.proto +++ b/backend/proto/activity.proto @@ -65,6 +65,38 @@ message PurchaseItemResponse { int64 remaining_balance = 5; // 剩余水晶余额 } +// 单个购买项(用于批量购买) +message PurchaseItem { + string item_type = 1; + int32 quantity = 2; +} + +// 批量购买道具请求 +message BatchPurchaseItemRequest { + int64 activity_id = 1; + repeated PurchaseItem items = 2; // 购买项列表 + int64 star_id = 3; + int64 user_id = 4; // 当前用户ID +} + +// 批量购买道具响应 +message BatchPurchaseItemResponse { + topfans.common.BaseResponse base = 1; + int64 total_crystal_spent = 2; // 本次消费水晶 + int64 total_contribution = 3; // 本次获得贡献点 + int64 current_progress = 4; // 当前活动进度 + int64 remaining_balance = 5; // 剩余水晶余额 + int32 success_count = 6; // 成功购买数量 + int32 fail_count = 7; // 失败购买数量 + repeated PurchaseFailItem fails = 8; // 失败的项 +} + +// 购买失败的项 +message PurchaseFailItem { + string item_type = 1; + string reason = 2; +} + // 贡献点排名请求 message ContributionRankingRequest { int64 activity_id = 1; @@ -237,6 +269,14 @@ service ActivityService { }; } + // 批量购买道具 + rpc BatchPurchaseItem(BatchPurchaseItemRequest) returns (BatchPurchaseItemResponse) { + option (google.api.http) = { + post: "/api/v1/activities/{activity_id}/batch-purchase" + body: "*" + }; + } + // 获取贡献点排名 rpc GetContributionRanking(ContributionRankingRequest) returns (ContributionRankingResponse) { option (google.api.http) = { diff --git a/backend/proto/asset.proto b/backend/proto/asset.proto index 655213c..dac2372 100644 --- a/backend/proto/asset.proto +++ b/backend/proto/asset.proto @@ -129,7 +129,7 @@ message EstimateMintCostResponse { int64 current_balance = 3; // 当前余额(铸造前) int64 balance_after = 4; // 铸造后余额 int32 mint_count = 5; // 本次是第几次铸造 - string next_tier_hint = 6; // 下一阶梯提示 + int64 next_tier_cost = 6; // 下一阶梯费用 } // ==================== 资产查询相关消息 ==================== diff --git a/backend/scripts/compile-proto.sh b/backend/scripts/compile-proto.sh index 4797312..eb50999 100755 --- a/backend/scripts/compile-proto.sh +++ b/backend/scripts/compile-proto.sh @@ -51,6 +51,20 @@ fi echo "✅ 所有必需插件已安装" echo "" +# 辅助函数:移动 protoc-gen-go-triple v3 生成的文件到正确位置 +# v3 插件根据 go_package 路径生成文件到 github.com/ 目录,需要手动移动 +move_triple_files() { + local module_path="$1" + local target_dir="$2" + local triple_file=$(basename "$module_path").triple.go + local src_file="github.com/$module_path/$triple_file" + if [ -f "$src_file" ]; then + mv "$src_file" "$target_dir/" + rm -rf "github.com/$module_path" + echo " ✅ $triple_file 已移动到正确位置" + fi +} + # 预先创建目标目录 echo "📁 创建目标目录..." for name in common user social asset gallery ranking activity task starbook; do @@ -77,6 +91,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/user \ --go-triple_opt=paths=source_relative \ user.proto +move_triple_files "topfans/backend/pkg/proto/user" "pkg/proto/user" echo "✅ user.proto 编译完成" echo "" @@ -90,6 +105,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/social \ --go-triple_opt=paths=source_relative \ social.proto +move_triple_files "topfans/backend/pkg/proto/social" "pkg/proto/social" echo "✅ social.proto 编译完成" echo "" @@ -103,6 +119,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/asset \ --go-triple_opt=paths=source_relative \ asset.proto +move_triple_files "topfans/backend/pkg/proto/asset" "pkg/proto/asset" echo "✅ asset.proto 编译完成" echo "" @@ -116,6 +133,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/gallery \ --go-triple_opt=paths=source_relative \ gallery.proto +move_triple_files "topfans/backend/pkg/proto/gallery" "pkg/proto/gallery" echo "✅ gallery.proto 编译完成" echo "" @@ -129,6 +147,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/ranking \ --go-triple_opt=paths=source_relative \ ranking.proto +move_triple_files "topfans/backend/pkg/proto/ranking" "pkg/proto/ranking" echo "✅ ranking.proto 编译完成" echo "" @@ -142,6 +161,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/activity \ --go-triple_opt=paths=source_relative \ activity.proto +move_triple_files "topfans/backend/pkg/proto/activity" "pkg/proto/activity" echo "✅ activity.proto 编译完成" echo "" @@ -155,6 +175,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/task \ --go-triple_opt=paths=source_relative \ task.proto +move_triple_files "topfans/backend/pkg/proto/task" "pkg/proto/task" echo "✅ task.proto 编译完成" echo "" @@ -168,6 +189,7 @@ protoc --proto_path=proto \ --go-triple_out=pkg/proto/starbook \ --go-triple_opt=paths=source_relative \ starbook.proto +move_triple_files "topfans/backend/pkg/proto/starbook" "pkg/proto/starbook" echo "✅ starbook.proto 编译完成" echo "" diff --git a/backend/services/activityService/provider/activity_provider.go b/backend/services/activityService/provider/activity_provider.go index 2935ccb..f6a0f1d 100644 --- a/backend/services/activityService/provider/activity_provider.go +++ b/backend/services/activityService/provider/activity_provider.go @@ -162,6 +162,38 @@ func (p *ActivityProvider) PurchaseItem(ctx context.Context, req *pb.PurchaseIte return resp, nil } +// BatchPurchaseItem 批量购买道具 +func (p *ActivityProvider) BatchPurchaseItem(ctx context.Context, req *pb.BatchPurchaseItemRequest) (*pb.BatchPurchaseItemResponse, error) { + logger.Logger.Info("Received BatchPurchaseItem request", + zap.Int64("activity_id", req.ActivityId), + zap.Int("items_count", len(req.Items)), + zap.Int64("star_id", req.StarId), + ) + + // 调用Service层 + resp, err := p.activityService.BatchPurchaseItem(ctx, req) + if err != nil { + logger.Logger.Error("BatchPurchaseItem failed", zap.Error(err)) + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: appErrors.ToStatusCode(err), + Message: err.Error(), + Timestamp: time.Now().UnixMilli(), + }, + }, err + } + + logger.Logger.Info("BatchPurchaseItem successful", + zap.Int64("total_crystal_spent", resp.TotalCrystalSpent), + zap.Int64("total_contribution", resp.TotalContribution), + zap.Int64("remaining_balance", resp.RemainingBalance), + zap.Int32("success_count", resp.SuccessCount), + zap.Int32("fail_count", resp.FailCount), + ) + + return resp, nil +} + // GetContributionRanking 获取贡献点排名 func (p *ActivityProvider) GetContributionRanking(ctx context.Context, req *pb.ContributionRankingRequest) (*pb.ContributionRankingResponse, error) { logger.Logger.Info("Received GetContributionRanking request", diff --git a/backend/services/activityService/service/activity_service.go b/backend/services/activityService/service/activity_service.go index bd79bec..70c61fc 100644 --- a/backend/services/activityService/service/activity_service.go +++ b/backend/services/activityService/service/activity_service.go @@ -32,6 +32,9 @@ type ActivityService interface { // PurchaseItem 购买道具 PurchaseItem(ctx context.Context, req *pb.PurchaseItemRequest) (*pb.PurchaseItemResponse, error) + // BatchPurchaseItem 批量购买道具 + BatchPurchaseItem(ctx context.Context, req *pb.BatchPurchaseItemRequest) (*pb.BatchPurchaseItemResponse, error) + // GetContributionRanking 获取贡献点排名 GetContributionRanking(ctx context.Context, req *pb.ContributionRankingRequest) (*pb.ContributionRankingResponse, error) @@ -411,6 +414,222 @@ func (s *activityService) PurchaseItem(ctx context.Context, req *pb.PurchaseItem }, nil } +// BatchPurchaseItem 批量购买道具 +func (s *activityService) BatchPurchaseItem(ctx context.Context, req *pb.BatchPurchaseItemRequest) (*pb.BatchPurchaseItemResponse, error) { + logger.Logger.Info("BatchPurchaseItem request", + zap.Int64("activity_id", req.ActivityId), + zap.Int("items_count", len(req.Items)), + zap.Int64("star_id", req.StarId), + ) + + // 参数校验 + if req.ActivityId <= 0 { + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 400, + Message: "activity_id is required", + }, + }, nil + } + + if len(req.Items) == 0 { + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 400, + Message: "items 是必填参数", + }, + }, nil + } + + userID := req.UserId + + // 获取活动 + activity, err := s.activityRepo.GetActivityByID(req.ActivityId) + if err != nil { + logger.Logger.Error("GetActivity failed", zap.Error(err)) + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 500, + Message: "获取活动失败: " + err.Error(), + }, + }, nil + } + + if activity == nil { + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 404, + Message: "活动不存在", + }, + }, nil + } + + // 检查活动状态 + currentStatus := activity.GetCurrentStatus() + if currentStatus != "active" { + var message string + switch currentStatus { + case "expired": + message = "activity:expired" + case "pending": + message = "activity:pending" + case "completed": + message = "activity:completed" + default: + message = "activity:expired" + } + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: pbCommon.StatusCode_STATUS_OK, + Message: message, + }, + }, nil + } + + // 通过RPC获取用户当前水晶余额(只调用一次) + profile, err := s.userRPCClient.GetFanProfile(userID, req.StarId) + if err != nil { + logger.Logger.Error("GetFanProfile failed", zap.Error(err)) + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 500, + Message: "获取粉丝档案失败: " + err.Error(), + }, + }, nil + } + + if profile == nil { + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 404, + Message: "粉丝档案不存在", + }, + }, nil + } + + // 计算总消费水晶和贡献点(先计算,用于校验余额) + var totalCost int64 + var totalContribution int64 + itemInfoMap := make(map[string]*models.ActivityItem) + + for _, item := range req.Items { + if item.Quantity <= 0 { + continue + } + + activityItem, err := s.activityRepo.GetActivityItemByType(req.ActivityId, item.ItemType) + if err != nil || activityItem == nil { + logger.Logger.Warn("GetActivityItemByType failed or item not found", + zap.String("item_type", item.ItemType), + zap.Error(err), + ) + continue + } + + itemInfoMap[item.ItemType] = activityItem + totalCost += int64(activityItem.CrystalCost) * int64(item.Quantity) + totalContribution += int64(activityItem.ContributionPoints) * int64(item.Quantity) + } + + // 检查水晶余额是否足够 + if profile.CrystalBalance < totalCost { + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 400, + Message: "水晶余额不足", + }, + }, nil + } + + // 通过RPC扣减水晶 + newBalance, err := s.userRPCClient.UpdateCrystalBalance(userID, req.StarId, -totalCost) + if err != nil { + logger.Logger.Error("UpdateCrystalBalance failed", zap.Error(err)) + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 500, + Message: "扣减水晶失败: " + err.Error(), + }, + }, nil + } + + // 更新活动进度 + newProgress := activity.CurrentProgress + totalContribution + if newProgress > activity.TargetProgress { + newProgress = activity.TargetProgress + } + + err = s.activityRepo.UpdateActivityProgress(req.ActivityId, newProgress) + if err != nil { + logger.Logger.Error("UpdateActivityProgress failed", zap.Error(err)) + } + + // 创建贡献记录(合并为一个记录) + now := time.Now().UnixMilli() + contribution := &models.ActivityContribution{ + ActivityID: req.ActivityId, + UserID: userID, + StarID: req.StarId, + Quantity: 0, // 批量购买不记录单数量 + CrystalSpent: totalCost, + ContributionPoints: totalContribution, + CreatedAt: now, + } + + err = s.activityRepo.CreateContribution(contribution) + if err != nil { + logger.Logger.Error("CreateContribution failed", zap.Error(err)) + } + + // 更新用户统计 + stats, _ := s.activityRepo.GetUserStats(req.ActivityId, userID, req.StarId) + if stats == nil { + stats = &models.ActivityUserStats{ + ActivityID: req.ActivityId, + UserID: userID, + StarID: req.StarId, + TotalContribution: 0, + TotalCrystalSpent: 0, + TotalItems: 0, + LastContributeAt: now, + CreatedAt: now, + UpdatedAt: now, + } + } + + stats.TotalContribution += totalContribution + stats.TotalCrystalSpent += totalCost + stats.TotalItems += len(req.Items) + stats.LastContributeAt = now + stats.UpdatedAt = now + + err = s.activityRepo.UpdateUserStats(stats) + if err != nil { + logger.Logger.Error("UpdateUserStats failed", zap.Error(err)) + } + + logger.Logger.Info("BatchPurchaseItem success", + zap.Int64("user_id", userID), + zap.Int64("total_cost", totalCost), + zap.Int64("total_contribution", totalContribution), + zap.Int64("new_progress", newProgress), + ) + + return &pb.BatchPurchaseItemResponse{ + Base: &pbCommon.BaseResponse{ + Code: 200, + Message: "ok", + }, + TotalCrystalSpent: totalCost, + TotalContribution: totalContribution, + CurrentProgress: newProgress, + RemainingBalance: newBalance, + SuccessCount: int32(len(req.Items)), + FailCount: 0, + Fails: []*pb.PurchaseFailItem{}, + }, nil +} + // GetContributionRanking 获取贡献点排名 func (s *activityService) GetContributionRanking(ctx context.Context, req *pb.ContributionRankingRequest) (*pb.ContributionRankingResponse, error) { logger.Logger.Info("GetContributionRanking request", diff --git a/backend/services/assetService/provider/asset_provider.go b/backend/services/assetService/provider/asset_provider.go index c2d5e1b..35e623a 100644 --- a/backend/services/assetService/provider/asset_provider.go +++ b/backend/services/assetService/provider/asset_provider.go @@ -853,6 +853,6 @@ func (p *AssetProvider) EstimateMintCost(ctx context.Context, req *pb.EstimateMi CurrentBalance: estimate.CurrentBalance, BalanceAfter: estimate.AfterBalance, MintCount: estimate.MintCount, - NextTierHint: estimate.NextTierHint, + NextTierCost: estimate.NextTierCost, }, nil } diff --git a/backend/services/assetService/service/mint_service.go b/backend/services/assetService/service/mint_service.go index f2f8dac..377cc8d 100644 --- a/backend/services/assetService/service/mint_service.go +++ b/backend/services/assetService/service/mint_service.go @@ -59,14 +59,14 @@ type MintService interface { // mintService 铸造服务实现 type mintService struct { - assetRepo repository.AssetRepository - mintOrderRepo repository.MintOrderRepository - userClient client.UserServiceClient - db *gorm.DB - config *config.AssetConfig - registryRepo starbookRepo.AssetRegistryRepository // 资产索引仓库(用于星册体系) - localMintCostRepo repository.MintCostRepository // 铸造消耗配置仓库 - userMintCountRepo repository.UserMintCountRepository // 用户铸爱累计仓库 + assetRepo repository.AssetRepository + mintOrderRepo repository.MintOrderRepository + userClient client.UserServiceClient + db *gorm.DB + config *config.AssetConfig + registryRepo starbookRepo.AssetRegistryRepository // 资产索引仓库(用于星册体系) + localMintCostRepo repository.MintCostRepository // 铸造消耗配置仓库 + userMintCountRepo repository.UserMintCountRepository // 用户铸爱累计仓库 } // NewMintService 创建铸造服务实例 @@ -81,13 +81,13 @@ func NewMintService( userMintCountRepo repository.UserMintCountRepository, ) MintService { return &mintService{ - assetRepo: assetRepo, - mintOrderRepo: mintOrderRepo, - userClient: userClient, - db: db, - config: cfg, - registryRepo: registryRepo, - localMintCostRepo: localMintCostRepo, + assetRepo: assetRepo, + mintOrderRepo: mintOrderRepo, + userClient: userClient, + db: db, + config: cfg, + registryRepo: registryRepo, + localMintCostRepo: localMintCostRepo, userMintCountRepo: userMintCountRepo, } } @@ -346,11 +346,11 @@ func (s *mintService) CreateMintOrder(req *pb.CreateMintOrderRequest, userID, st OwnerUID: userID, StarID: starID, Name: getStringValue(mintOrder.Name), - CoverURL: materialURLValue, // 直接使用素材图作为封面 - MaterialURL: &materialURLValue, // 使用指针 + CoverURL: materialURLValue, // 直接使用素材图作为封面 + MaterialURL: &materialURLValue, // 使用指针 Description: mintOrder.Description, Visibility: models.AssetVisibilityPrivate, - Status: models.AssetStatusActive, // 直接设为 Active + Status: models.AssetStatusActive, // 直接设为 Active LikeCount: 0, Info: getStringValue(mintOrder.Info), TxHash: &mockTxHash, @@ -856,32 +856,32 @@ func (s *mintService) EstimateMintCost(userID, starID int64) (*MintCostEstimate, afterBalance = 0 } - // 下一阶梯费用提示 - var nextTierHint string + // 下一阶梯费用 + var nextTierCost int64 nextMintCount := currentMintCount + 2 // 下一次铸造的次数 if nextMintCount <= 10 { nextCost, err := s.GetMintCost(nextMintCount) if err == nil { - nextTierHint = fmt.Sprintf("下一阶梯 %d 水晶", nextCost.CostCrystal) + nextTierCost = nextCost.CostCrystal } } return &MintCostEstimate{ - CostCrystal: localMintCost.CostCrystal, + CostCrystal: localMintCost.CostCrystal, CurrentBalance: currentBalance, AfterBalance: afterBalance, MintCount: currentMintCount + 1, // 本次将是第几次铸造 - NextTierHint: nextTierHint, + NextTierCost: nextTierCost, }, nil } // MintCostEstimate 铸造费用估算结果 type MintCostEstimate struct { - CostCrystal int64 // 本次铸造消耗水晶 - CurrentBalance int64 // 当前余额(铸造前) - AfterBalance int64 // 铸造后余额 - MintCount int32 // 本次铸造是第几次 - NextTierHint string // 下一阶梯提示 + CostCrystal int64 // 本次铸造消耗水晶 + CurrentBalance int64 // 当前余额(铸造前) + AfterBalance int64 // 铸造后余额 + MintCount int32 // 本次铸造是第几次 + NextTierCost int64 // 下一阶梯费用 } // UpdateMintCountAndBoost 更新铸爱次数和收益提升 diff --git a/frontend/components/ConfirmModal.vue b/frontend/components/ConfirmModal.vue index 70c4947..1e16e5e 100644 --- a/frontend/components/ConfirmModal.vue +++ b/frontend/components/ConfirmModal.vue @@ -1,34 +1,43 @@ @@ -74,14 +87,6 @@ const props = defineProps({ type: String, default: '确认' }, - cancelText: { - type: String, - default: '取消' - }, - showCancel: { - type: Boolean, - default: true - }, // 铸造费用信息 costCrystal: { type: Number, @@ -91,17 +96,13 @@ const props = defineProps({ type: Number, default: 0 }, - balanceAfter: { - type: Number, - default: 0 - }, mintCount: { type: Number, default: 0 }, - nextTierHint: { - type: String, - default: '' + nextTierCost: { + type: Number, + default: 0 } }) @@ -119,7 +120,10 @@ function handleCancel() { diff --git a/frontend/pages/ai-dazi/index.vue b/frontend/pages/ai-dazi/index.vue index 880a218..2ba1a17 100644 --- a/frontend/pages/ai-dazi/index.vue +++ b/frontend/pages/ai-dazi/index.vue @@ -5,7 +5,7 @@ - + @@ -144,13 +144,18 @@ const handleAdd = () => { /* 关闭按钮 */ .close-btn { - font-size: 48rpx; - font-weight: bold; -} - -.nav-back-icon { width: 80rpx; height: 80rpx; + display: flex; + align-items: center; + justify-content: center; + +} + +.nav-back { + font-size: 48rpx; + font-weight: bold; + color: #fff; } /* 浮动装饰物 */ diff --git a/frontend/pages/castlove/lenticular/lenticular-result.vue b/frontend/pages/castlove/lenticular/lenticular-result.vue index 5f3c6fa..6411889 100644 --- a/frontend/pages/castlove/lenticular/lenticular-result.vue +++ b/frontend/pages/castlove/lenticular/lenticular-result.vue @@ -2,12 +2,12 @@ - + - + - + - + - + - + @@ -53,46 +39,24 @@ - - + + - + - + 重新生成 - + 开始铸造 - + @@ -129,11 +93,10 @@ const resultMeta = ref('lenticular'); // 确认铸造弹窗 const showConfirmModal = ref(false); const confirmCostInfo = ref({ - costCrystal: 0, - currentBalance: 0, - balanceAfter: 0, - mintCount: 0, - nextTierHint: '', + costCrystal: 0, + currentBalance: 0, + mintCount: 0, + nextTierCost: 0, }); const lenticularLayers = ref([]); @@ -181,7 +144,7 @@ const getStarStyle = (index) => { const top = Math.random() * 100; const size = Math.random() * 3 + 1; const delay = Math.random() * 3; - + return { left: `${left}%`, top: `${top}%`, @@ -199,11 +162,11 @@ const base64ToBlob = (base64Data) => { const raw = atob(parts[1]); const rawLength = raw.length; const uInt8Array = new Uint8Array(rawLength); - + for (let i = 0; i < rawLength; i++) { uInt8Array[i] = raw.charCodeAt(i); } - + return new Blob([uInt8Array], { type: contentType }); }; @@ -211,35 +174,35 @@ const base64ToBlob = (base64Data) => { const uploadImageToOss = async (base64Image) => { console.log('[GenerationResult] uploadImageToOss 开始'); isUploading.value = true; - + try { uni.showLoading({ title: '上传中...', mask: true }); - + // 1. 获取OSS签名 const signRes = await getOssSignatureApi('asset'); console.log('[GenerationResult] 获取签名结果:', signRes); - + if (signRes.code !== 200) { throw new Error(signRes.message || '获取签名失败'); } - + // 保存order_id currentOrderId.value = signRes.data.order_id || ''; console.log('[GenerationResult] order_id:', currentOrderId.value); - + // 2. 生成文件名 const timestamp = Date.now(); const randomStr = Math.random().toString(36).substring(2, 8); const fileName = `ai_generated_${timestamp}_${randomStr}.png`; - + let imageUrl; - + // #ifdef H5 // H5环境:使用FormData + Blob console.log('[GenerationResult] H5环境,使用Blob上传'); const blob = base64ToBlob(base64Image); console.log('[GenerationResult] Blob创建成功,大小:', blob.size); - + const formData = new FormData(); formData.append('key', signRes.data.dir + fileName); formData.append('policy', signRes.data.policy); @@ -250,34 +213,34 @@ const uploadImageToOss = async (base64Image) => { formData.append('x-oss-signature', signRes.data.signature); formData.append('x-oss-signature-version', signRes.data.x_oss_signature_version); formData.append('file', blob, fileName); - + const response = await fetch(signRes.data.host, { method: 'POST', body: formData }); - + console.log('[GenerationResult] OSS响应状态:', response.status); - + if (response.ok || response.status === 204) { imageUrl = `${signRes.data.host}/${signRes.data.dir}${fileName}`; } else { throw new Error(`上传失败,状态码: ${response.status}`); } // #endif - + // #ifndef H5 // App/小程序环境:使用uni.uploadFile console.log('[GenerationResult] 非H5环境,使用uni.uploadFile'); - + let tempFilePath; // 声明临时文件路径变量 - + // #ifdef APP-PLUS // App环境:直接使用base64上传(通过临时文件) console.log('[GenerationResult] App环境,使用base64临时文件'); - + // 使用uni.saveFile保存base64为临时文件 const base64Data = base64Image.replace(/^data:image\/\w+;base64,/, ''); - + // 先转换为临时文件路径 tempFilePath = await new Promise((resolve, reject) => { // 使用uni的base64ToTempFilePath(如果可用) @@ -316,21 +279,21 @@ const uploadImageToOss = async (base64Image) => { } }); // #endif - + // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ // 小程序环境:使用FileSystemManager console.log('[GenerationResult] 小程序环境'); const base64Data = base64Image.replace(/^data:image\/\w+;base64,/, ''); - + // #ifdef MP-WEIXIN tempFilePath = `${wx.env.USER_DATA_PATH}/${fileName}`; // #endif // #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ tempFilePath = `${uni.env.USER_DATA_PATH}/${fileName}`; // #endif - + console.log('[GenerationResult] 临时文件路径:', tempFilePath); - + const fs = uni.getFileSystemManager(); await new Promise((resolve, reject) => { fs.writeFile({ @@ -348,9 +311,9 @@ const uploadImageToOss = async (base64Image) => { }); }); // #endif - + console.log('[GenerationResult] 开始上传到OSS,文件路径:', tempFilePath); - + // 上传到OSS imageUrl = await new Promise((resolve, reject) => { uni.uploadFile({ @@ -370,7 +333,7 @@ const uploadImageToOss = async (base64Image) => { success: (uploadRes) => { console.log('[GenerationResult] OSS上传响应:', uploadRes.statusCode); console.log('[GenerationResult] OSS上传完整响应:', uploadRes); - + if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) { const url = `${signRes.data.host}/${signRes.data.dir}${fileName}`; console.log('[GenerationResult] 上传成功,URL:', url); @@ -386,7 +349,7 @@ const uploadImageToOss = async (base64Image) => { }); }); // #endif - + console.log('[GenerationResult] 上传成功,URL:', imageUrl); uni.hideLoading(); uni.showToast({ @@ -396,7 +359,7 @@ const uploadImageToOss = async (base64Image) => { }); isUploading.value = false; return imageUrl; - + } catch (error) { console.error('[GenerationResult] 上传失败:', error); uni.hideLoading(); @@ -416,7 +379,7 @@ const uploadToOssH5 = async (base64Image, fileName, ossData) => { try { // 将base64转换为Blob const blob = base64ToBlob(base64Image); - + // 构建FormData const formData = new FormData(); formData.append('key', ossData.dir + fileName); @@ -428,32 +391,32 @@ const uploadToOssH5 = async (base64Image, fileName, ossData) => { formData.append('x-oss-signature', ossData.signature); formData.append('x-oss-signature-version', ossData.x_oss_signature_version); formData.append('file', blob, fileName); - + // 使用fetch上传 fetch(resolveH5OssPostUrl(ossData.host), { method: 'POST', body: formData }) - .then(response => { - if (response.ok) { - const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`; + .then(response => { + if (response.ok) { + const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`; + uni.hideLoading(); + uni.showToast({ + title: '上传成功', + icon: 'success', + duration: 1500 + }); + isUploading.value = false; + resolve(imageUrl); // 只返回URL + } else { + throw new Error(`上传失败,状态码: ${response.status}`); + } + }) + .catch(error => { uni.hideLoading(); - uni.showToast({ - title: '上传成功', - icon: 'success', - duration: 1500 - }); isUploading.value = false; - resolve(imageUrl); // 只返回URL - } else { - throw new Error(`上传失败,状态码: ${response.status}`); - } - }) - .catch(error => { - uni.hideLoading(); - isUploading.value = false; - reject(error); - }); + reject(error); + }); } catch (error) { uni.hideLoading(); isUploading.value = false; @@ -466,20 +429,20 @@ const uploadToOssH5 = async (base64Image, fileName, ossData) => { const uploadToOssNative = async (base64Image, fileName, ossData) => { console.log('[GenerationResult] uploadToOssNative 开始'); console.log('[GenerationResult] fileName:', fileName); - + return new Promise((resolve, reject) => { try { // 去掉base64前缀 const base64Data = base64Image.replace(/^data:image\/\w+;base64,/, ''); console.log('[GenerationResult] base64数据长度:', base64Data.length); - + // #ifdef MP-WEIXIN // 微信小程序环境 console.log('[GenerationResult] 使用微信小程序环境'); const fs = uni.getFileSystemManager(); const tempFilePath = `${wx.env.USER_DATA_PATH}/${fileName}`; console.log('[GenerationResult] 临时文件路径:', tempFilePath); - + fs.writeFile({ filePath: tempFilePath, data: base64Data, @@ -496,19 +459,19 @@ const uploadToOssNative = async (base64Image, fileName, ossData) => { } }); // #endif - + // #ifdef APP-PLUS // App环境 console.log('[GenerationResult] 使用App环境'); const fs = plus.io.getFileSystemManager ? uni.getFileSystemManager() : null; console.log('[GenerationResult] FileSystemManager:', fs ? '可用' : '不可用'); - + if (!fs) { // 使用plus.io API console.log('[GenerationResult] 使用plus.io API'); const tempFilePath = `_doc/${fileName}`; console.log('[GenerationResult] 临时文件路径:', tempFilePath); - + plus.io.resolveLocalFileSystemURL('_doc', (entry) => { console.log('[GenerationResult] 获取文件系统成功'); entry.getFile(fileName, { create: true }, (fileEntry) => { @@ -554,7 +517,7 @@ const uploadToOssNative = async (base64Image, fileName, ossData) => { console.log('[GenerationResult] 使用FileSystemManager API'); const tempFilePath = `${plus.io.getStorageRootPath()}${fileName}`; console.log('[GenerationResult] 临时文件路径:', tempFilePath); - + fs.writeFile({ filePath: tempFilePath, data: base64Data, @@ -572,7 +535,7 @@ const uploadToOssNative = async (base64Image, fileName, ossData) => { }); } // #endif - + } catch (error) { console.error('[GenerationResult] uploadToOssNative异常:', error); uni.hideLoading(); @@ -587,7 +550,7 @@ const uploadFileToOss = (tempFilePath, fileName, ossData, resolve, reject, fs) = console.log('[GenerationResult] uploadFileToOss 开始'); console.log('[GenerationResult] tempFilePath:', tempFilePath); console.log('[GenerationResult] OSS host:', ossData.host); - + uni.uploadFile({ url: ossData.host, filePath: tempFilePath, @@ -605,11 +568,11 @@ const uploadFileToOss = (tempFilePath, fileName, ossData, resolve, reject, fs) = success: (uploadRes) => { console.log('[GenerationResult] OSS上传响应:', uploadRes); console.log('[GenerationResult] 状态码:', uploadRes.statusCode); - + if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) { const imageUrl = `${ossData.host}/${ossData.dir}${fileName}`; console.log('[GenerationResult] 上传成功,图片URL:', imageUrl); - + // 删除临时文件 if (fs) { fs.unlink({ @@ -618,7 +581,7 @@ const uploadFileToOss = (tempFilePath, fileName, ossData, resolve, reject, fs) = fail: (err) => console.error('[GenerationResult] 删除临时文件失败:', err) }); } - + resolve(imageUrl); } else { console.error('[GenerationResult] 上传失败,状态码:', uploadRes.statusCode); @@ -673,18 +636,16 @@ const selectAsset = async () => { confirmCostInfo.value = { costCrystal: costRes.data.cost_crystal || 0, currentBalance: costRes.data.current_balance || 0, - balanceAfter: costRes.data.balance_after || 0, mintCount: costRes.data.mint_count || 0, - nextTierHint: costRes.data.next_tier_hint || '', + nextTierCost: costRes.data.next_tier_cost || '', }; - + } else { confirmCostInfo.value = { costCrystal: 100, currentBalance: 0, - balanceAfter: 0, mintCount: 0, - nextTierHint: '', + nextTierCost: 0, }; } } catch (e) { @@ -693,9 +654,8 @@ const selectAsset = async () => { confirmCostInfo.value = { costCrystal: 100, currentBalance: 0, - balanceAfter: 0, mintCount: 0, - nextTierHint: '', + nextTierCost: 0, }; } @@ -775,7 +735,9 @@ onMounted(() => { const imagesData = uni.getStorageSync(GENERATED_IMAGES_KEY); if (!imagesData) { uni.showToast({ title: '未找到生成的图片', icon: 'none' }); - setTimeout(() => uni.navigateBack(), 1500); + setTimeout(() => uni.navigateTo({ + url: '/pages/castlove/lenticular/lenticular-create' + }), 1500); return; } const parsed = JSON.parse(imagesData); @@ -796,7 +758,9 @@ onMounted(() => { } catch (e) { console.error('[GenerationResult] 读取图片数据失败:', e); uni.showToast({ title: '数据错误', icon: 'none' }); - setTimeout(() => uni.navigateBack(), 1500); + setTimeout(() => uni.navigateTo({ + url: '/pages/castlove/lenticular/lenticular-create' + }), 1500); } }); @@ -817,7 +781,7 @@ onUnmounted(() => {