feat: 经济系统重构 - 任务服务与画廊服务解耦
- galleryService 独立启动,配置 task-service-url - 新增 taskService 到 galleryService 的 RPC 调用 - 更新 proto 文件并重新生成代码 - 新增展览唯一约束迁移脚本 - 修复多个 service 的配置和依赖关系 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
2c2e707971
commit
c5bf9df955
@ -339,7 +339,12 @@ echo -e "${YELLOW}🚀 启动所有服务...${NC}"
|
||||
start_service "userService" "services/userService/userService" 20000 1
|
||||
start_service "assetService" "services/assetService/assetService" 20003 1
|
||||
start_service "socialService" "services/socialService/socialService" 20002 1
|
||||
start_service "galleryService" "services/galleryService/galleryService" 20004 1
|
||||
# galleryService 需要连接 taskService (20006),单独处理
|
||||
echo -e "${GREEN}🚀 启动 galleryService...${NC}"
|
||||
"$SCRIPT_DIR/services/galleryService/galleryService" -port=20004 -task-service-url="tri://localhost:20006" "${DB_ARGS[@]}" > "/tmp/galleryService.log" 2>&1 &
|
||||
echo $! > "/tmp/dev_sh_galleryService.pid"
|
||||
sleep 2
|
||||
echo -e "${GREEN}✅ galleryService 已启动 (PID: $(cat /tmp/dev_sh_galleryService.pid), 端口: 20004)${NC}"
|
||||
start_service "activityService" "services/activityService/activityService" 20005 1
|
||||
start_service "taskService" "services/taskService/taskService" 20006 1
|
||||
start_service "starbookService" "services/starbookService/starbookService" 20007 1
|
||||
@ -352,7 +357,6 @@ start_watcher "gateway" "gateway" "gateway/gateway" 8
|
||||
start_watcher "userService" "services/userService" "services/userService/userService" 20000 1
|
||||
start_watcher "assetService" "services/assetService" "services/assetService/assetService" 20003 1
|
||||
start_watcher "socialService" "services/socialService" "services/socialService/socialService" 20002 1
|
||||
start_watcher "galleryService" "services/galleryService" "services/galleryService/galleryService" 20004 1
|
||||
start_watcher "activityService" "services/activityService" "services/activityService/activityService" 20005 1
|
||||
start_watcher "taskService" "services/taskService" "services/taskService/taskService" 20006 1
|
||||
start_watcher "starbookService" "services/starbookService" "services/starbookService/starbookService" 20007 1
|
||||
|
||||
@ -602,7 +602,9 @@ func (ctrl *TaskController) ClaimExhibitionRevenue(c *gin.Context) {
|
||||
}
|
||||
|
||||
response.Success(c, map[string]interface{}{
|
||||
"success": resp.Success,
|
||||
"success": resp.Success,
|
||||
"crystal_amount": resp.CrystalAmount,
|
||||
"total_balance": resp.TotalBalance,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -71,20 +71,22 @@ func ConvertMintOrder(pbOrder *pbAsset.MintOrder) MintOrderDTO {
|
||||
// 注意:预签名 URL 需要在 Controller 层生成,因为需要访问 OSS 配置
|
||||
func ConvertAsset(pbAsset *pbAsset.Asset) AssetDTO {
|
||||
dto := AssetDTO{
|
||||
AssetID: pbAsset.AssetId,
|
||||
OwnerUID: pbAsset.OwnerUid,
|
||||
OwnerNickname: pbAsset.OwnerNickname,
|
||||
StarID: pbAsset.StarId,
|
||||
Name: pbAsset.Name,
|
||||
CoverURL: pbAsset.CoverUrl,
|
||||
Visibility: pbAsset.Visibility,
|
||||
Status: pbAsset.Status,
|
||||
LikeCount: pbAsset.LikeCount,
|
||||
CreatedAt: pbAsset.CreatedAt,
|
||||
UpdatedAt: pbAsset.UpdatedAt,
|
||||
IsLiked: pbAsset.IsLiked,
|
||||
Info: pbAsset.Info,
|
||||
DisplayStatus: pbAsset.DisplayStatus,
|
||||
AssetID: pbAsset.AssetId,
|
||||
OwnerUID: pbAsset.OwnerUid,
|
||||
OwnerNickname: pbAsset.OwnerNickname,
|
||||
StarID: pbAsset.StarId,
|
||||
Name: pbAsset.Name,
|
||||
CoverURL: pbAsset.CoverUrl,
|
||||
Visibility: pbAsset.Visibility,
|
||||
Status: pbAsset.Status,
|
||||
LikeCount: pbAsset.LikeCount,
|
||||
CreatedAt: pbAsset.CreatedAt,
|
||||
UpdatedAt: pbAsset.UpdatedAt,
|
||||
IsLiked: pbAsset.IsLiked,
|
||||
Info: pbAsset.Info,
|
||||
DisplayStatus: pbAsset.DisplayStatus,
|
||||
Earnings: pbAsset.Earnings,
|
||||
ExhibitionExpireAt: pbAsset.ExhibitionExpireAt,
|
||||
}
|
||||
|
||||
// 可选字段
|
||||
|
||||
@ -80,7 +80,9 @@ type AssetDTO struct {
|
||||
Owner *OwnerInfoDTO `json:"owner,omitempty"` // 持有者信息(可选,保留用于兼容性)
|
||||
IsLiked bool `json:"is_liked"` // 当前用户是否已点赞
|
||||
Info string `json:"info"` // 藏品信息
|
||||
DisplayStatus int32 `json:"display_status"` // 展示状态:0=待展示, 1=已展示
|
||||
DisplayStatus int32 `json:"display_status"` // 展示状态:0=待展示, 1=已展示
|
||||
Earnings int64 `json:"earnings"` // 当前展出收益(实时计算,仅展出中时有值)
|
||||
ExhibitionExpireAt int64 `json:"exhibition_expire_at"` // 展出过期时间(毫秒时间戳,仅展出中时有值,0=未展出)
|
||||
}
|
||||
|
||||
// OwnerInfoDTO 持有者信息
|
||||
|
||||
@ -23,7 +23,7 @@ func (BoothSlot) TableName() string {
|
||||
// Exhibition 展品展示表
|
||||
type Exhibition struct {
|
||||
ID int64 `gorm:"primaryKey;column:id;autoIncrement"`
|
||||
AssetID int64 `gorm:"column:asset_id;not null;uniqueIndex:uk_asset"`
|
||||
AssetID int64 `gorm:"column:asset_id;not null;index:idx_asset"`
|
||||
SlotID int64 `gorm:"column:slot_id;not null;index:idx_slot"`
|
||||
HostProfileID int64 `gorm:"column:host_profile_id;not null;index:idx_host"`
|
||||
OccupierUID int64 `gorm:"column:occupier_uid;not null;index:idx_occupier"`
|
||||
|
||||
@ -2,13 +2,13 @@ package models
|
||||
|
||||
// SystemConfig 系统配置表模型
|
||||
type SystemConfig struct {
|
||||
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||||
ConfigKey string `gorm:"type:varchar(100);uniqueIndex;not null;column:config_key"`
|
||||
ConfigValue int `gorm:"not null;column:config_value"`
|
||||
Description string `gorm:"type:varchar(500);column:description"`
|
||||
IsActive bool `gorm:"default:true;column:is_active"`
|
||||
CreatedAt int64 `gorm:"column:created_at"`
|
||||
UpdatedAt int64 `gorm:"column:updated_at"`
|
||||
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||||
ConfigKey string `gorm:"type:varchar(100);uniqueIndex;not null;column:config_key"`
|
||||
ConfigValue float64 `gorm:"type:numeric(10,2);not null;column:config_value"` // 使用 float64 支持小数
|
||||
Description string `gorm:"type:varchar(500);column:description"`
|
||||
IsActive bool `gorm:"default:true;column:is_active"`
|
||||
CreatedAt int64 `gorm:"column:created_at"`
|
||||
UpdatedAt int64 `gorm:"column:updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@ -44,13 +44,15 @@ type Asset struct {
|
||||
UpdatedAt int64 `protobuf:"varint,16,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // 更新时间(毫秒时间戳)
|
||||
MintedAt int64 `protobuf:"varint,17,opt,name=minted_at,json=mintedAt,proto3" json:"minted_at,omitempty"` // 上链成功时间(毫秒时间戳,可选)
|
||||
// 扩展字段:持有者信息(用于详情展示)
|
||||
Owner *OwnerInfo `protobuf:"bytes,18,opt,name=owner,proto3" json:"owner,omitempty"` // 持有者信息(保留用于兼容性)
|
||||
OwnerNickname string `protobuf:"bytes,19,opt,name=owner_nickname,json=ownerNickname,proto3" json:"owner_nickname,omitempty"` // 持有者昵称(在该star下的昵称)
|
||||
IsLiked bool `protobuf:"varint,20,opt,name=is_liked,json=isLiked,proto3" json:"is_liked,omitempty"` // 当前用户是否已点赞
|
||||
Info string `protobuf:"bytes,21,opt,name=info,proto3" json:"info,omitempty"` // 藏品信息
|
||||
DisplayStatus int32 `protobuf:"varint,22,opt,name=display_status,json=displayStatus,proto3" json:"display_status,omitempty"` // 展示状态:0=待展示, 1=已展示
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
Owner *OwnerInfo `protobuf:"bytes,18,opt,name=owner,proto3" json:"owner,omitempty"` // 持有者信息(保留用于兼容性)
|
||||
OwnerNickname string `protobuf:"bytes,19,opt,name=owner_nickname,json=ownerNickname,proto3" json:"owner_nickname,omitempty"` // 持有者昵称(在该star下的昵称)
|
||||
IsLiked bool `protobuf:"varint,20,opt,name=is_liked,json=isLiked,proto3" json:"is_liked,omitempty"` // 当前用户是否已点赞
|
||||
Info string `protobuf:"bytes,21,opt,name=info,proto3" json:"info,omitempty"` // 藏品信息
|
||||
DisplayStatus int32 `protobuf:"varint,22,opt,name=display_status,json=displayStatus,proto3" json:"display_status,omitempty"` // 展示状态:0=待展示, 1=已展示
|
||||
Earnings int64 `protobuf:"varint,23,opt,name=earnings,proto3" json:"earnings,omitempty"` // 当前展出收益(实时计算,仅展出中时有值)
|
||||
ExhibitionExpireAt int64 `protobuf:"varint,24,opt,name=exhibition_expire_at,json=exhibitionExpireAt,proto3" json:"exhibition_expire_at,omitempty"` // 展出过期时间(毫秒时间戳,仅展出中时有值,0=未展出)
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Asset) Reset() {
|
||||
@ -237,6 +239,20 @@ func (x *Asset) GetDisplayStatus() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Asset) GetEarnings() int64 {
|
||||
if x != nil {
|
||||
return x.Earnings
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Asset) GetExhibitionExpireAt() int64 {
|
||||
if x != nil {
|
||||
return x.ExhibitionExpireAt
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 持有者信息
|
||||
type OwnerInfo struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@ -2618,7 +2634,7 @@ var File_asset_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_asset_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vasset.proto\x12\rtopfans.asset\x1a\x12proto/common.proto\x1a\x1cgoogle/api/annotations.proto\"\x93\x05\n" +
|
||||
"\vasset.proto\x12\rtopfans.asset\x1a\x12proto/common.proto\x1a\x1cgoogle/api/annotations.proto\"\xe1\x05\n" +
|
||||
"\x05Asset\x12\x19\n" +
|
||||
"\basset_id\x18\x01 \x01(\x03R\aassetId\x12\x1b\n" +
|
||||
"\towner_uid\x18\x02 \x01(\x03R\bownerUid\x12\x17\n" +
|
||||
@ -2647,7 +2663,9 @@ const file_asset_proto_rawDesc = "" +
|
||||
"\x0eowner_nickname\x18\x13 \x01(\tR\rownerNickname\x12\x19\n" +
|
||||
"\bis_liked\x18\x14 \x01(\bR\aisLiked\x12\x12\n" +
|
||||
"\x04info\x18\x15 \x01(\tR\x04info\x12%\n" +
|
||||
"\x0edisplay_status\x18\x16 \x01(\x05R\rdisplayStatus\"X\n" +
|
||||
"\x0edisplay_status\x18\x16 \x01(\x05R\rdisplayStatus\x12\x1a\n" +
|
||||
"\bearnings\x18\x17 \x01(\x03R\bearnings\x120\n" +
|
||||
"\x14exhibition_expire_at\x18\x18 \x01(\x03R\x12exhibitionExpireAt\"X\n" +
|
||||
"\tOwnerInfo\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x1a\n" +
|
||||
"\bnickname\x18\x02 \x01(\tR\bnickname\x12\x16\n" +
|
||||
|
||||
@ -939,6 +939,96 @@ func (x *RemoveFromSlotResponse) GetBase() *common.BaseResponse {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 根据资产ID移除展品请求
|
||||
type RemoveExhibitionByAssetRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AssetId int64 `protobuf:"varint,1,opt,name=asset_id,json=assetId,proto3" json:"asset_id,omitempty"` // 资产ID(必填)
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveExhibitionByAssetRequest) Reset() {
|
||||
*x = RemoveExhibitionByAssetRequest{}
|
||||
mi := &file_gallery_proto_msgTypes[16]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveExhibitionByAssetRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveExhibitionByAssetRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveExhibitionByAssetRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[16]
|
||||
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 RemoveExhibitionByAssetRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveExhibitionByAssetRequest) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{16}
|
||||
}
|
||||
|
||||
func (x *RemoveExhibitionByAssetRequest) GetAssetId() int64 {
|
||||
if x != nil {
|
||||
return x.AssetId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 根据资产ID移除展品响应
|
||||
type RemoveExhibitionByAssetResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveExhibitionByAssetResponse) Reset() {
|
||||
*x = RemoveExhibitionByAssetResponse{}
|
||||
mi := &file_gallery_proto_msgTypes[17]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveExhibitionByAssetResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveExhibitionByAssetResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveExhibitionByAssetResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[17]
|
||||
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 RemoveExhibitionByAssetResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveExhibitionByAssetResponse) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{17}
|
||||
}
|
||||
|
||||
func (x *RemoveExhibitionByAssetResponse) GetBase() *common.BaseResponse {
|
||||
if x != nil {
|
||||
return x.Base
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取我展出的作品列表请求
|
||||
type GetMyExhibitedAssetsRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@ -950,7 +1040,7 @@ type GetMyExhibitedAssetsRequest struct {
|
||||
|
||||
func (x *GetMyExhibitedAssetsRequest) Reset() {
|
||||
*x = GetMyExhibitedAssetsRequest{}
|
||||
mi := &file_gallery_proto_msgTypes[16]
|
||||
mi := &file_gallery_proto_msgTypes[18]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -962,7 +1052,7 @@ func (x *GetMyExhibitedAssetsRequest) String() string {
|
||||
func (*GetMyExhibitedAssetsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetMyExhibitedAssetsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[16]
|
||||
mi := &file_gallery_proto_msgTypes[18]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -975,7 +1065,7 @@ func (x *GetMyExhibitedAssetsRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetMyExhibitedAssetsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetMyExhibitedAssetsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{16}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{18}
|
||||
}
|
||||
|
||||
func (x *GetMyExhibitedAssetsRequest) GetPage() int32 {
|
||||
@ -1003,7 +1093,7 @@ type GetMyExhibitedAssetsResponse struct {
|
||||
|
||||
func (x *GetMyExhibitedAssetsResponse) Reset() {
|
||||
*x = GetMyExhibitedAssetsResponse{}
|
||||
mi := &file_gallery_proto_msgTypes[17]
|
||||
mi := &file_gallery_proto_msgTypes[19]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1015,7 +1105,7 @@ func (x *GetMyExhibitedAssetsResponse) String() string {
|
||||
func (*GetMyExhibitedAssetsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetMyExhibitedAssetsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[17]
|
||||
mi := &file_gallery_proto_msgTypes[19]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1028,7 +1118,7 @@ func (x *GetMyExhibitedAssetsResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetMyExhibitedAssetsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetMyExhibitedAssetsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{17}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{19}
|
||||
}
|
||||
|
||||
func (x *GetMyExhibitedAssetsResponse) GetBase() *common.BaseResponse {
|
||||
@ -1059,7 +1149,7 @@ type ExhibitedAssetsData struct {
|
||||
|
||||
func (x *ExhibitedAssetsData) Reset() {
|
||||
*x = ExhibitedAssetsData{}
|
||||
mi := &file_gallery_proto_msgTypes[18]
|
||||
mi := &file_gallery_proto_msgTypes[20]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1071,7 +1161,7 @@ func (x *ExhibitedAssetsData) String() string {
|
||||
func (*ExhibitedAssetsData) ProtoMessage() {}
|
||||
|
||||
func (x *ExhibitedAssetsData) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[18]
|
||||
mi := &file_gallery_proto_msgTypes[20]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1084,7 +1174,7 @@ func (x *ExhibitedAssetsData) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExhibitedAssetsData.ProtoReflect.Descriptor instead.
|
||||
func (*ExhibitedAssetsData) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{18}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{20}
|
||||
}
|
||||
|
||||
func (x *ExhibitedAssetsData) GetItems() []*ExhibitedAssetItem {
|
||||
@ -1138,7 +1228,7 @@ type ExhibitedAssetItem struct {
|
||||
|
||||
func (x *ExhibitedAssetItem) Reset() {
|
||||
*x = ExhibitedAssetItem{}
|
||||
mi := &file_gallery_proto_msgTypes[19]
|
||||
mi := &file_gallery_proto_msgTypes[21]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1150,7 +1240,7 @@ func (x *ExhibitedAssetItem) String() string {
|
||||
func (*ExhibitedAssetItem) ProtoMessage() {}
|
||||
|
||||
func (x *ExhibitedAssetItem) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[19]
|
||||
mi := &file_gallery_proto_msgTypes[21]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1163,7 +1253,7 @@ func (x *ExhibitedAssetItem) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExhibitedAssetItem.ProtoReflect.Descriptor instead.
|
||||
func (*ExhibitedAssetItem) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{19}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{21}
|
||||
}
|
||||
|
||||
func (x *ExhibitedAssetItem) GetAssetId() int64 {
|
||||
@ -1229,7 +1319,7 @@ type GetInspirationFlowRequest struct {
|
||||
|
||||
func (x *GetInspirationFlowRequest) Reset() {
|
||||
*x = GetInspirationFlowRequest{}
|
||||
mi := &file_gallery_proto_msgTypes[20]
|
||||
mi := &file_gallery_proto_msgTypes[22]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1241,7 +1331,7 @@ func (x *GetInspirationFlowRequest) String() string {
|
||||
func (*GetInspirationFlowRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetInspirationFlowRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[20]
|
||||
mi := &file_gallery_proto_msgTypes[22]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1254,7 +1344,7 @@ func (x *GetInspirationFlowRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetInspirationFlowRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetInspirationFlowRequest) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{20}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{22}
|
||||
}
|
||||
|
||||
func (x *GetInspirationFlowRequest) GetCursor() string {
|
||||
@ -1303,7 +1393,7 @@ type GetInspirationFlowResponse struct {
|
||||
|
||||
func (x *GetInspirationFlowResponse) Reset() {
|
||||
*x = GetInspirationFlowResponse{}
|
||||
mi := &file_gallery_proto_msgTypes[21]
|
||||
mi := &file_gallery_proto_msgTypes[23]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1315,7 +1405,7 @@ func (x *GetInspirationFlowResponse) String() string {
|
||||
func (*GetInspirationFlowResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetInspirationFlowResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[21]
|
||||
mi := &file_gallery_proto_msgTypes[23]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1328,7 +1418,7 @@ func (x *GetInspirationFlowResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetInspirationFlowResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetInspirationFlowResponse) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{21}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{23}
|
||||
}
|
||||
|
||||
func (x *GetInspirationFlowResponse) GetBase() *common.BaseResponse {
|
||||
@ -1358,7 +1448,7 @@ type InspirationFlowData struct {
|
||||
|
||||
func (x *InspirationFlowData) Reset() {
|
||||
*x = InspirationFlowData{}
|
||||
mi := &file_gallery_proto_msgTypes[22]
|
||||
mi := &file_gallery_proto_msgTypes[24]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1370,7 +1460,7 @@ func (x *InspirationFlowData) String() string {
|
||||
func (*InspirationFlowData) ProtoMessage() {}
|
||||
|
||||
func (x *InspirationFlowData) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[22]
|
||||
mi := &file_gallery_proto_msgTypes[24]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1383,7 +1473,7 @@ func (x *InspirationFlowData) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use InspirationFlowData.ProtoReflect.Descriptor instead.
|
||||
func (*InspirationFlowData) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{22}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{24}
|
||||
}
|
||||
|
||||
func (x *InspirationFlowData) GetItems() []*InspirationFlowItem {
|
||||
@ -1430,7 +1520,7 @@ type InspirationFlowItem struct {
|
||||
|
||||
func (x *InspirationFlowItem) Reset() {
|
||||
*x = InspirationFlowItem{}
|
||||
mi := &file_gallery_proto_msgTypes[23]
|
||||
mi := &file_gallery_proto_msgTypes[25]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1442,7 +1532,7 @@ func (x *InspirationFlowItem) String() string {
|
||||
func (*InspirationFlowItem) ProtoMessage() {}
|
||||
|
||||
func (x *InspirationFlowItem) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[23]
|
||||
mi := &file_gallery_proto_msgTypes[25]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1455,7 +1545,7 @@ func (x *InspirationFlowItem) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use InspirationFlowItem.ProtoReflect.Descriptor instead.
|
||||
func (*InspirationFlowItem) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{23}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{25}
|
||||
}
|
||||
|
||||
func (x *InspirationFlowItem) GetAssetId() int64 {
|
||||
@ -1519,7 +1609,7 @@ type GetUserExhibitedAssetsRequest struct {
|
||||
|
||||
func (x *GetUserExhibitedAssetsRequest) Reset() {
|
||||
*x = GetUserExhibitedAssetsRequest{}
|
||||
mi := &file_gallery_proto_msgTypes[24]
|
||||
mi := &file_gallery_proto_msgTypes[26]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1531,7 +1621,7 @@ func (x *GetUserExhibitedAssetsRequest) String() string {
|
||||
func (*GetUserExhibitedAssetsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetUserExhibitedAssetsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[24]
|
||||
mi := &file_gallery_proto_msgTypes[26]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1544,7 +1634,7 @@ func (x *GetUserExhibitedAssetsRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetUserExhibitedAssetsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetUserExhibitedAssetsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{24}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{26}
|
||||
}
|
||||
|
||||
func (x *GetUserExhibitedAssetsRequest) GetUserId() int64 {
|
||||
@ -1579,7 +1669,7 @@ type GetUserExhibitedAssetsResponse struct {
|
||||
|
||||
func (x *GetUserExhibitedAssetsResponse) Reset() {
|
||||
*x = GetUserExhibitedAssetsResponse{}
|
||||
mi := &file_gallery_proto_msgTypes[25]
|
||||
mi := &file_gallery_proto_msgTypes[27]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -1591,7 +1681,7 @@ func (x *GetUserExhibitedAssetsResponse) String() string {
|
||||
func (*GetUserExhibitedAssetsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetUserExhibitedAssetsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_gallery_proto_msgTypes[25]
|
||||
mi := &file_gallery_proto_msgTypes[27]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -1604,7 +1694,7 @@ func (x *GetUserExhibitedAssetsResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetUserExhibitedAssetsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetUserExhibitedAssetsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_gallery_proto_rawDescGZIP(), []int{25}
|
||||
return file_gallery_proto_rawDescGZIP(), []int{27}
|
||||
}
|
||||
|
||||
func (x *GetUserExhibitedAssetsResponse) GetBase() *common.BaseResponse {
|
||||
@ -1695,6 +1785,10 @@ const file_gallery_proto_rawDesc = "" +
|
||||
"\x15RemoveFromSlotRequest\x12\x17\n" +
|
||||
"\aslot_id\x18\x01 \x01(\x03R\x06slotId\"J\n" +
|
||||
"\x16RemoveFromSlotResponse\x120\n" +
|
||||
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\";\n" +
|
||||
"\x1eRemoveExhibitionByAssetRequest\x12\x19\n" +
|
||||
"\basset_id\x18\x01 \x01(\x03R\aassetId\"S\n" +
|
||||
"\x1fRemoveExhibitionByAssetResponse\x120\n" +
|
||||
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\"N\n" +
|
||||
"\x1bGetMyExhibitedAssetsRequest\x12\x12\n" +
|
||||
"\x04page\x18\x01 \x01(\x05R\x04page\x12\x1b\n" +
|
||||
@ -1748,7 +1842,7 @@ const file_gallery_proto_rawDesc = "" +
|
||||
"\tpage_size\x18\x03 \x01(\x05R\bpageSize\"\x8c\x01\n" +
|
||||
"\x1eGetUserExhibitedAssetsResponse\x120\n" +
|
||||
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x128\n" +
|
||||
"\x04data\x18\x02 \x01(\v2$.topfans.gallery.ExhibitedAssetsDataR\x04data2\xf4\b\n" +
|
||||
"\x04data\x18\x02 \x01(\v2$.topfans.gallery.ExhibitedAssetsDataR\x04data2\xf2\t\n" +
|
||||
"\x0eGalleryService\x12u\n" +
|
||||
"\fGetMyGallery\x12$.topfans.gallery.GetMyGalleryRequest\x1a%.topfans.gallery.GetMyGalleryResponse\"\x18\x82\xd3\xe4\x93\x02\x12\x12\x10/api/mygalleries\x12\x86\x01\n" +
|
||||
"\x0eGetUserGallery\x12&.topfans.gallery.GetUserGalleryRequest\x1a'.topfans.gallery.GetUserGalleryResponse\"#\x82\xd3\xe4\x93\x02\x1d\x12\x1b/api/galleries/{target_uid}\x12v\n" +
|
||||
@ -1756,7 +1850,8 @@ const file_gallery_proto_rawDesc = "" +
|
||||
"PlaceAsset\x12\".topfans.gallery.PlaceAssetRequest\x1a#.topfans.gallery.PlaceAssetResponse\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\"\x14/api/galleries/place\x12}\n" +
|
||||
"\n" +
|
||||
"UnlockSlot\x12\".topfans.gallery.UnlockSlotRequest\x1a#.topfans.gallery.UnlockSlotResponse\"&\x82\xd3\xe4\x93\x02 :\x01*\"\x1b/api/galleries/slots_unlock\x12\x8f\x01\n" +
|
||||
"\x0eRemoveFromSlot\x12&.topfans.gallery.RemoveFromSlotRequest\x1a'.topfans.gallery.RemoveFromSlotResponse\",\x82\xd3\xe4\x93\x02&*$/api/galleries/slots/{slot_id}/asset\x12\x98\x01\n" +
|
||||
"\x0eRemoveFromSlot\x12&.topfans.gallery.RemoveFromSlotRequest\x1a'.topfans.gallery.RemoveFromSlotResponse\",\x82\xd3\xe4\x93\x02&*$/api/galleries/slots/{slot_id}/asset\x12|\n" +
|
||||
"\x17RemoveExhibitionByAsset\x12/.topfans.gallery.RemoveExhibitionByAssetRequest\x1a0.topfans.gallery.RemoveExhibitionByAssetResponse\x12\x98\x01\n" +
|
||||
"\x14GetMyExhibitedAssets\x12,.topfans.gallery.GetMyExhibitedAssetsRequest\x1a-.topfans.gallery.GetMyExhibitedAssetsResponse\"#\x82\xd3\xe4\x93\x02\x1d\x12\x1b/api/v1/me/exhibited-assets\x12\x8f\x01\n" +
|
||||
"\x12GetInspirationFlow\x12*.topfans.gallery.GetInspirationFlowRequest\x1a+.topfans.gallery.GetInspirationFlowResponse\" \x82\xd3\xe4\x93\x02\x1a\x12\x18/api/v1/inspiration-flow\x12\xab\x01\n" +
|
||||
"\x16GetUserExhibitedAssets\x12..topfans.gallery.GetUserExhibitedAssetsRequest\x1a/.topfans.gallery.GetUserExhibitedAssetsResponse\"0\x82\xd3\xe4\x93\x02*\x12(/api/v1/users/{user_id}/exhibited-assetsB6Z4github.com/topfans/backend/pkg/proto/gallery;galleryb\x06proto3"
|
||||
@ -1773,78 +1868,83 @@ func file_gallery_proto_rawDescGZIP() []byte {
|
||||
return file_gallery_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_gallery_proto_msgTypes = make([]protoimpl.MessageInfo, 26)
|
||||
var file_gallery_proto_msgTypes = make([]protoimpl.MessageInfo, 28)
|
||||
var file_gallery_proto_goTypes = []any{
|
||||
(*GetMyGalleryRequest)(nil), // 0: topfans.gallery.GetMyGalleryRequest
|
||||
(*GetMyGalleryResponse)(nil), // 1: topfans.gallery.GetMyGalleryResponse
|
||||
(*GetUserGalleryRequest)(nil), // 2: topfans.gallery.GetUserGalleryRequest
|
||||
(*GetUserGalleryResponse)(nil), // 3: topfans.gallery.GetUserGalleryResponse
|
||||
(*PlaceAssetRequest)(nil), // 4: topfans.gallery.PlaceAssetRequest
|
||||
(*PlaceAssetResponse)(nil), // 5: topfans.gallery.PlaceAssetResponse
|
||||
(*UnlockSlotRequest)(nil), // 6: topfans.gallery.UnlockSlotRequest
|
||||
(*UnlockSlotResponse)(nil), // 7: topfans.gallery.UnlockSlotResponse
|
||||
(*GalleryData)(nil), // 8: topfans.gallery.GalleryData
|
||||
(*SlotInfo)(nil), // 9: topfans.gallery.SlotInfo
|
||||
(*AssetInfo)(nil), // 10: topfans.gallery.AssetInfo
|
||||
(*UnlockCondition)(nil), // 11: topfans.gallery.UnlockCondition
|
||||
(*PlaceAssetData)(nil), // 12: topfans.gallery.PlaceAssetData
|
||||
(*UnlockSlotData)(nil), // 13: topfans.gallery.UnlockSlotData
|
||||
(*RemoveFromSlotRequest)(nil), // 14: topfans.gallery.RemoveFromSlotRequest
|
||||
(*RemoveFromSlotResponse)(nil), // 15: topfans.gallery.RemoveFromSlotResponse
|
||||
(*GetMyExhibitedAssetsRequest)(nil), // 16: topfans.gallery.GetMyExhibitedAssetsRequest
|
||||
(*GetMyExhibitedAssetsResponse)(nil), // 17: topfans.gallery.GetMyExhibitedAssetsResponse
|
||||
(*ExhibitedAssetsData)(nil), // 18: topfans.gallery.ExhibitedAssetsData
|
||||
(*ExhibitedAssetItem)(nil), // 19: topfans.gallery.ExhibitedAssetItem
|
||||
(*GetInspirationFlowRequest)(nil), // 20: topfans.gallery.GetInspirationFlowRequest
|
||||
(*GetInspirationFlowResponse)(nil), // 21: topfans.gallery.GetInspirationFlowResponse
|
||||
(*InspirationFlowData)(nil), // 22: topfans.gallery.InspirationFlowData
|
||||
(*InspirationFlowItem)(nil), // 23: topfans.gallery.InspirationFlowItem
|
||||
(*GetUserExhibitedAssetsRequest)(nil), // 24: topfans.gallery.GetUserExhibitedAssetsRequest
|
||||
(*GetUserExhibitedAssetsResponse)(nil), // 25: topfans.gallery.GetUserExhibitedAssetsResponse
|
||||
(*common.BaseResponse)(nil), // 26: topfans.common.BaseResponse
|
||||
(*GetMyGalleryRequest)(nil), // 0: topfans.gallery.GetMyGalleryRequest
|
||||
(*GetMyGalleryResponse)(nil), // 1: topfans.gallery.GetMyGalleryResponse
|
||||
(*GetUserGalleryRequest)(nil), // 2: topfans.gallery.GetUserGalleryRequest
|
||||
(*GetUserGalleryResponse)(nil), // 3: topfans.gallery.GetUserGalleryResponse
|
||||
(*PlaceAssetRequest)(nil), // 4: topfans.gallery.PlaceAssetRequest
|
||||
(*PlaceAssetResponse)(nil), // 5: topfans.gallery.PlaceAssetResponse
|
||||
(*UnlockSlotRequest)(nil), // 6: topfans.gallery.UnlockSlotRequest
|
||||
(*UnlockSlotResponse)(nil), // 7: topfans.gallery.UnlockSlotResponse
|
||||
(*GalleryData)(nil), // 8: topfans.gallery.GalleryData
|
||||
(*SlotInfo)(nil), // 9: topfans.gallery.SlotInfo
|
||||
(*AssetInfo)(nil), // 10: topfans.gallery.AssetInfo
|
||||
(*UnlockCondition)(nil), // 11: topfans.gallery.UnlockCondition
|
||||
(*PlaceAssetData)(nil), // 12: topfans.gallery.PlaceAssetData
|
||||
(*UnlockSlotData)(nil), // 13: topfans.gallery.UnlockSlotData
|
||||
(*RemoveFromSlotRequest)(nil), // 14: topfans.gallery.RemoveFromSlotRequest
|
||||
(*RemoveFromSlotResponse)(nil), // 15: topfans.gallery.RemoveFromSlotResponse
|
||||
(*RemoveExhibitionByAssetRequest)(nil), // 16: topfans.gallery.RemoveExhibitionByAssetRequest
|
||||
(*RemoveExhibitionByAssetResponse)(nil), // 17: topfans.gallery.RemoveExhibitionByAssetResponse
|
||||
(*GetMyExhibitedAssetsRequest)(nil), // 18: topfans.gallery.GetMyExhibitedAssetsRequest
|
||||
(*GetMyExhibitedAssetsResponse)(nil), // 19: topfans.gallery.GetMyExhibitedAssetsResponse
|
||||
(*ExhibitedAssetsData)(nil), // 20: topfans.gallery.ExhibitedAssetsData
|
||||
(*ExhibitedAssetItem)(nil), // 21: topfans.gallery.ExhibitedAssetItem
|
||||
(*GetInspirationFlowRequest)(nil), // 22: topfans.gallery.GetInspirationFlowRequest
|
||||
(*GetInspirationFlowResponse)(nil), // 23: topfans.gallery.GetInspirationFlowResponse
|
||||
(*InspirationFlowData)(nil), // 24: topfans.gallery.InspirationFlowData
|
||||
(*InspirationFlowItem)(nil), // 25: topfans.gallery.InspirationFlowItem
|
||||
(*GetUserExhibitedAssetsRequest)(nil), // 26: topfans.gallery.GetUserExhibitedAssetsRequest
|
||||
(*GetUserExhibitedAssetsResponse)(nil), // 27: topfans.gallery.GetUserExhibitedAssetsResponse
|
||||
(*common.BaseResponse)(nil), // 28: topfans.common.BaseResponse
|
||||
}
|
||||
var file_gallery_proto_depIdxs = []int32{
|
||||
26, // 0: topfans.gallery.GetMyGalleryResponse.base:type_name -> topfans.common.BaseResponse
|
||||
28, // 0: topfans.gallery.GetMyGalleryResponse.base:type_name -> topfans.common.BaseResponse
|
||||
8, // 1: topfans.gallery.GetMyGalleryResponse.data:type_name -> topfans.gallery.GalleryData
|
||||
26, // 2: topfans.gallery.GetUserGalleryResponse.base:type_name -> topfans.common.BaseResponse
|
||||
28, // 2: topfans.gallery.GetUserGalleryResponse.base:type_name -> topfans.common.BaseResponse
|
||||
8, // 3: topfans.gallery.GetUserGalleryResponse.data:type_name -> topfans.gallery.GalleryData
|
||||
26, // 4: topfans.gallery.PlaceAssetResponse.base:type_name -> topfans.common.BaseResponse
|
||||
28, // 4: topfans.gallery.PlaceAssetResponse.base:type_name -> topfans.common.BaseResponse
|
||||
12, // 5: topfans.gallery.PlaceAssetResponse.data:type_name -> topfans.gallery.PlaceAssetData
|
||||
26, // 6: topfans.gallery.UnlockSlotResponse.base:type_name -> topfans.common.BaseResponse
|
||||
28, // 6: topfans.gallery.UnlockSlotResponse.base:type_name -> topfans.common.BaseResponse
|
||||
13, // 7: topfans.gallery.UnlockSlotResponse.data:type_name -> topfans.gallery.UnlockSlotData
|
||||
9, // 8: topfans.gallery.GalleryData.slots:type_name -> topfans.gallery.SlotInfo
|
||||
10, // 9: topfans.gallery.SlotInfo.asset:type_name -> topfans.gallery.AssetInfo
|
||||
11, // 10: topfans.gallery.SlotInfo.unlock_condition:type_name -> topfans.gallery.UnlockCondition
|
||||
26, // 11: topfans.gallery.RemoveFromSlotResponse.base:type_name -> topfans.common.BaseResponse
|
||||
26, // 12: topfans.gallery.GetMyExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse
|
||||
18, // 13: topfans.gallery.GetMyExhibitedAssetsResponse.data:type_name -> topfans.gallery.ExhibitedAssetsData
|
||||
19, // 14: topfans.gallery.ExhibitedAssetsData.items:type_name -> topfans.gallery.ExhibitedAssetItem
|
||||
26, // 15: topfans.gallery.GetInspirationFlowResponse.base:type_name -> topfans.common.BaseResponse
|
||||
22, // 16: topfans.gallery.GetInspirationFlowResponse.data:type_name -> topfans.gallery.InspirationFlowData
|
||||
23, // 17: topfans.gallery.InspirationFlowData.items:type_name -> topfans.gallery.InspirationFlowItem
|
||||
26, // 18: topfans.gallery.GetUserExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse
|
||||
18, // 19: topfans.gallery.GetUserExhibitedAssetsResponse.data:type_name -> topfans.gallery.ExhibitedAssetsData
|
||||
0, // 20: topfans.gallery.GalleryService.GetMyGallery:input_type -> topfans.gallery.GetMyGalleryRequest
|
||||
2, // 21: topfans.gallery.GalleryService.GetUserGallery:input_type -> topfans.gallery.GetUserGalleryRequest
|
||||
4, // 22: topfans.gallery.GalleryService.PlaceAsset:input_type -> topfans.gallery.PlaceAssetRequest
|
||||
6, // 23: topfans.gallery.GalleryService.UnlockSlot:input_type -> topfans.gallery.UnlockSlotRequest
|
||||
14, // 24: topfans.gallery.GalleryService.RemoveFromSlot:input_type -> topfans.gallery.RemoveFromSlotRequest
|
||||
16, // 25: topfans.gallery.GalleryService.GetMyExhibitedAssets:input_type -> topfans.gallery.GetMyExhibitedAssetsRequest
|
||||
20, // 26: topfans.gallery.GalleryService.GetInspirationFlow:input_type -> topfans.gallery.GetInspirationFlowRequest
|
||||
24, // 27: topfans.gallery.GalleryService.GetUserExhibitedAssets:input_type -> topfans.gallery.GetUserExhibitedAssetsRequest
|
||||
1, // 28: topfans.gallery.GalleryService.GetMyGallery:output_type -> topfans.gallery.GetMyGalleryResponse
|
||||
3, // 29: topfans.gallery.GalleryService.GetUserGallery:output_type -> topfans.gallery.GetUserGalleryResponse
|
||||
5, // 30: topfans.gallery.GalleryService.PlaceAsset:output_type -> topfans.gallery.PlaceAssetResponse
|
||||
7, // 31: topfans.gallery.GalleryService.UnlockSlot:output_type -> topfans.gallery.UnlockSlotResponse
|
||||
15, // 32: topfans.gallery.GalleryService.RemoveFromSlot:output_type -> topfans.gallery.RemoveFromSlotResponse
|
||||
17, // 33: topfans.gallery.GalleryService.GetMyExhibitedAssets:output_type -> topfans.gallery.GetMyExhibitedAssetsResponse
|
||||
21, // 34: topfans.gallery.GalleryService.GetInspirationFlow:output_type -> topfans.gallery.GetInspirationFlowResponse
|
||||
25, // 35: topfans.gallery.GalleryService.GetUserExhibitedAssets:output_type -> topfans.gallery.GetUserExhibitedAssetsResponse
|
||||
28, // [28:36] is the sub-list for method output_type
|
||||
20, // [20:28] is the sub-list for method input_type
|
||||
20, // [20:20] is the sub-list for extension type_name
|
||||
20, // [20:20] is the sub-list for extension extendee
|
||||
0, // [0:20] is the sub-list for field type_name
|
||||
28, // 11: topfans.gallery.RemoveFromSlotResponse.base:type_name -> topfans.common.BaseResponse
|
||||
28, // 12: topfans.gallery.RemoveExhibitionByAssetResponse.base:type_name -> topfans.common.BaseResponse
|
||||
28, // 13: topfans.gallery.GetMyExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse
|
||||
20, // 14: topfans.gallery.GetMyExhibitedAssetsResponse.data:type_name -> topfans.gallery.ExhibitedAssetsData
|
||||
21, // 15: topfans.gallery.ExhibitedAssetsData.items:type_name -> topfans.gallery.ExhibitedAssetItem
|
||||
28, // 16: topfans.gallery.GetInspirationFlowResponse.base:type_name -> topfans.common.BaseResponse
|
||||
24, // 17: topfans.gallery.GetInspirationFlowResponse.data:type_name -> topfans.gallery.InspirationFlowData
|
||||
25, // 18: topfans.gallery.InspirationFlowData.items:type_name -> topfans.gallery.InspirationFlowItem
|
||||
28, // 19: topfans.gallery.GetUserExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse
|
||||
20, // 20: topfans.gallery.GetUserExhibitedAssetsResponse.data:type_name -> topfans.gallery.ExhibitedAssetsData
|
||||
0, // 21: topfans.gallery.GalleryService.GetMyGallery:input_type -> topfans.gallery.GetMyGalleryRequest
|
||||
2, // 22: topfans.gallery.GalleryService.GetUserGallery:input_type -> topfans.gallery.GetUserGalleryRequest
|
||||
4, // 23: topfans.gallery.GalleryService.PlaceAsset:input_type -> topfans.gallery.PlaceAssetRequest
|
||||
6, // 24: topfans.gallery.GalleryService.UnlockSlot:input_type -> topfans.gallery.UnlockSlotRequest
|
||||
14, // 25: topfans.gallery.GalleryService.RemoveFromSlot:input_type -> topfans.gallery.RemoveFromSlotRequest
|
||||
16, // 26: topfans.gallery.GalleryService.RemoveExhibitionByAsset:input_type -> topfans.gallery.RemoveExhibitionByAssetRequest
|
||||
18, // 27: topfans.gallery.GalleryService.GetMyExhibitedAssets:input_type -> topfans.gallery.GetMyExhibitedAssetsRequest
|
||||
22, // 28: topfans.gallery.GalleryService.GetInspirationFlow:input_type -> topfans.gallery.GetInspirationFlowRequest
|
||||
26, // 29: topfans.gallery.GalleryService.GetUserExhibitedAssets:input_type -> topfans.gallery.GetUserExhibitedAssetsRequest
|
||||
1, // 30: topfans.gallery.GalleryService.GetMyGallery:output_type -> topfans.gallery.GetMyGalleryResponse
|
||||
3, // 31: topfans.gallery.GalleryService.GetUserGallery:output_type -> topfans.gallery.GetUserGalleryResponse
|
||||
5, // 32: topfans.gallery.GalleryService.PlaceAsset:output_type -> topfans.gallery.PlaceAssetResponse
|
||||
7, // 33: topfans.gallery.GalleryService.UnlockSlot:output_type -> topfans.gallery.UnlockSlotResponse
|
||||
15, // 34: topfans.gallery.GalleryService.RemoveFromSlot:output_type -> topfans.gallery.RemoveFromSlotResponse
|
||||
17, // 35: topfans.gallery.GalleryService.RemoveExhibitionByAsset:output_type -> topfans.gallery.RemoveExhibitionByAssetResponse
|
||||
19, // 36: topfans.gallery.GalleryService.GetMyExhibitedAssets:output_type -> topfans.gallery.GetMyExhibitedAssetsResponse
|
||||
23, // 37: topfans.gallery.GalleryService.GetInspirationFlow:output_type -> topfans.gallery.GetInspirationFlowResponse
|
||||
27, // 38: topfans.gallery.GalleryService.GetUserExhibitedAssets:output_type -> topfans.gallery.GetUserExhibitedAssetsResponse
|
||||
30, // [30:39] is the sub-list for method output_type
|
||||
21, // [21:30] is the sub-list for method input_type
|
||||
21, // [21:21] is the sub-list for extension type_name
|
||||
21, // [21:21] is the sub-list for extension extendee
|
||||
0, // [0:21] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_gallery_proto_init() }
|
||||
@ -1858,7 +1958,7 @@ func file_gallery_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_gallery_proto_rawDesc), len(file_gallery_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 26,
|
||||
NumMessages: 28,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@ -46,6 +46,8 @@ const (
|
||||
GalleryServiceUnlockSlotProcedure = "/topfans.gallery.GalleryService/UnlockSlot"
|
||||
// GalleryServiceRemoveFromSlotProcedure is the fully-qualified name of the GalleryService's RemoveFromSlot RPC.
|
||||
GalleryServiceRemoveFromSlotProcedure = "/topfans.gallery.GalleryService/RemoveFromSlot"
|
||||
// GalleryServiceRemoveExhibitionByAssetProcedure is the fully-qualified name of the GalleryService's RemoveExhibitionByAsset RPC.
|
||||
GalleryServiceRemoveExhibitionByAssetProcedure = "/topfans.gallery.GalleryService/RemoveExhibitionByAsset"
|
||||
// GalleryServiceGetMyExhibitedAssetsProcedure is the fully-qualified name of the GalleryService's GetMyExhibitedAssets RPC.
|
||||
GalleryServiceGetMyExhibitedAssetsProcedure = "/topfans.gallery.GalleryService/GetMyExhibitedAssets"
|
||||
// GalleryServiceGetInspirationFlowProcedure is the fully-qualified name of the GalleryService's GetInspirationFlow RPC.
|
||||
@ -65,6 +67,7 @@ type GalleryService interface {
|
||||
PlaceAsset(ctx context.Context, req *PlaceAssetRequest, opts ...client.CallOption) (*PlaceAssetResponse, error)
|
||||
UnlockSlot(ctx context.Context, req *UnlockSlotRequest, opts ...client.CallOption) (*UnlockSlotResponse, error)
|
||||
RemoveFromSlot(ctx context.Context, req *RemoveFromSlotRequest, opts ...client.CallOption) (*RemoveFromSlotResponse, error)
|
||||
RemoveExhibitionByAsset(ctx context.Context, req *RemoveExhibitionByAssetRequest, opts ...client.CallOption) (*RemoveExhibitionByAssetResponse, error)
|
||||
GetMyExhibitedAssets(ctx context.Context, req *GetMyExhibitedAssetsRequest, opts ...client.CallOption) (*GetMyExhibitedAssetsResponse, error)
|
||||
GetInspirationFlow(ctx context.Context, req *GetInspirationFlowRequest, opts ...client.CallOption) (*GetInspirationFlowResponse, error)
|
||||
GetUserExhibitedAssets(ctx context.Context, req *GetUserExhibitedAssetsRequest, opts ...client.CallOption) (*GetUserExhibitedAssetsResponse, error)
|
||||
@ -130,6 +133,14 @@ func (c *GalleryServiceImpl) RemoveFromSlot(ctx context.Context, req *RemoveFrom
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *GalleryServiceImpl) RemoveExhibitionByAsset(ctx context.Context, req *RemoveExhibitionByAssetRequest, opts ...client.CallOption) (*RemoveExhibitionByAssetResponse, error) {
|
||||
resp := new(RemoveExhibitionByAssetResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "RemoveExhibitionByAsset", opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *GalleryServiceImpl) GetMyExhibitedAssets(ctx context.Context, req *GetMyExhibitedAssetsRequest, opts ...client.CallOption) (*GetMyExhibitedAssetsResponse, error) {
|
||||
resp := new(GetMyExhibitedAssetsResponse)
|
||||
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyExhibitedAssets", opts...); err != nil {
|
||||
@ -156,7 +167,7 @@ func (c *GalleryServiceImpl) GetUserExhibitedAssets(ctx context.Context, req *Ge
|
||||
|
||||
var GalleryService_ClientInfo = client.ClientInfo{
|
||||
InterfaceName: "topfans.gallery.GalleryService",
|
||||
MethodNames: []string{"GetMyGallery", "GetUserGallery", "PlaceAsset", "UnlockSlot", "RemoveFromSlot", "GetMyExhibitedAssets", "GetInspirationFlow", "GetUserExhibitedAssets"},
|
||||
MethodNames: []string{"GetMyGallery", "GetUserGallery", "PlaceAsset", "UnlockSlot", "RemoveFromSlot", "RemoveExhibitionByAsset", "GetMyExhibitedAssets", "GetInspirationFlow", "GetUserExhibitedAssets"},
|
||||
ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) {
|
||||
dubboCli := dubboCliRaw.(*GalleryServiceImpl)
|
||||
dubboCli.conn = conn
|
||||
@ -170,6 +181,7 @@ type GalleryServiceHandler interface {
|
||||
PlaceAsset(context.Context, *PlaceAssetRequest) (*PlaceAssetResponse, error)
|
||||
UnlockSlot(context.Context, *UnlockSlotRequest) (*UnlockSlotResponse, error)
|
||||
RemoveFromSlot(context.Context, *RemoveFromSlotRequest) (*RemoveFromSlotResponse, error)
|
||||
RemoveExhibitionByAsset(context.Context, *RemoveExhibitionByAssetRequest) (*RemoveExhibitionByAssetResponse, error)
|
||||
GetMyExhibitedAssets(context.Context, *GetMyExhibitedAssetsRequest) (*GetMyExhibitedAssetsResponse, error)
|
||||
GetInspirationFlow(context.Context, *GetInspirationFlowRequest) (*GetInspirationFlowResponse, error)
|
||||
GetUserExhibitedAssets(context.Context, *GetUserExhibitedAssetsRequest) (*GetUserExhibitedAssetsResponse, error)
|
||||
@ -262,6 +274,21 @@ var GalleryService_ServiceInfo = server.ServiceInfo{
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "RemoveExhibitionByAsset",
|
||||
Type: constant.CallUnary,
|
||||
ReqInitFunc: func() interface{} {
|
||||
return new(RemoveExhibitionByAssetRequest)
|
||||
},
|
||||
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
|
||||
req := args[0].(*RemoveExhibitionByAssetRequest)
|
||||
res, err := handler.(GalleryServiceHandler).RemoveExhibitionByAsset(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return triple_protocol.NewResponse(res), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GetMyExhibitedAssets",
|
||||
Type: constant.CallUnary,
|
||||
|
||||
@ -1451,6 +1451,8 @@ type ClaimExhibitionRevenueResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
|
||||
Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"`
|
||||
CrystalAmount int64 `protobuf:"varint,3,opt,name=crystal_amount,json=crystalAmount,proto3" json:"crystal_amount,omitempty"` // 当前领取的收益金额
|
||||
TotalBalance int64 `protobuf:"varint,4,opt,name=total_balance,json=totalBalance,proto3" json:"total_balance,omitempty"` // 领取后的当前用户全部余额
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -1499,6 +1501,20 @@ func (x *ClaimExhibitionRevenueResponse) GetSuccess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ClaimExhibitionRevenueResponse) GetCrystalAmount() int64 {
|
||||
if x != nil {
|
||||
return x.CrystalAmount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ClaimExhibitionRevenueResponse) GetTotalBalance() int64 {
|
||||
if x != nil {
|
||||
return x.TotalBalance
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ClaimAllExhibitionRevenueRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
StarId int64 `protobuf:"varint,1,opt,name=star_id,json=starId,proto3" json:"star_id,omitempty"`
|
||||
@ -1969,10 +1985,12 @@ const file_task_proto_rawDesc = "" +
|
||||
"\x1dClaimExhibitionRevenueRequest\x12\x1d\n" +
|
||||
"\n" +
|
||||
"revenue_id\x18\x01 \x01(\x03R\trevenueId\x12\x17\n" +
|
||||
"\astar_id\x18\x02 \x01(\x03R\x06starId\"l\n" +
|
||||
"\astar_id\x18\x02 \x01(\x03R\x06starId\"\xb8\x01\n" +
|
||||
"\x1eClaimExhibitionRevenueResponse\x120\n" +
|
||||
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12\x18\n" +
|
||||
"\asuccess\x18\x02 \x01(\bR\asuccess\";\n" +
|
||||
"\asuccess\x18\x02 \x01(\bR\asuccess\x12%\n" +
|
||||
"\x0ecrystal_amount\x18\x03 \x01(\x03R\rcrystalAmount\x12#\n" +
|
||||
"\rtotal_balance\x18\x04 \x01(\x03R\ftotalBalance\";\n" +
|
||||
" ClaimAllExhibitionRevenueRequest\x12\x17\n" +
|
||||
"\astar_id\x18\x01 \x01(\x03R\x06starId\"z\n" +
|
||||
"!ClaimAllExhibitionRevenueResponse\x120\n" +
|
||||
@ -1997,7 +2015,7 @@ const file_task_proto_rawDesc = "" +
|
||||
"\texpire_at\x18\t \x01(\x03R\bexpireAt\"}\n" +
|
||||
"\x1dOnExhibitionCompletedResponse\x120\n" +
|
||||
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12*\n" +
|
||||
"\x11revenue_record_id\x18\x02 \x01(\x03R\x0frevenueRecordId2\xbd\f\n" +
|
||||
"\x11revenue_record_id\x18\x02 \x01(\x03R\x0frevenueRecordId2\xc6\f\n" +
|
||||
"\x11TaskMobileService\x12r\n" +
|
||||
"\rGetDailyTasks\x12\".topfans.task.GetDailyTasksRequest\x1a#.topfans.task.GetDailyTasksResponse\"\x18\x82\xd3\xe4\x93\x02\x12\x12\x10/api/tasks/daily\x12v\n" +
|
||||
"\vReportEvent\x12 .topfans.task.ReportEventRequest\x1a!.topfans.task.ReportEventResponse\"\"\x82\xd3\xe4\x93\x02\x1c:\x01*\"\x17/api/tasks/report-event\x12~\n" +
|
||||
@ -2006,10 +2024,10 @@ const file_task_proto_rawDesc = "" +
|
||||
"\rCompleteGuide\x12\".topfans.task.CompleteGuideRequest\x1a#.topfans.task.CompleteGuideResponse\"$\x82\xd3\xe4\x93\x02\x1e:\x01*\"\x19/api/tasks/guide/complete\x12\x90\x01\n" +
|
||||
"\x13GetOnboardingStatus\x12(.topfans.task.GetOnboardingStatusRequest\x1a).topfans.task.GetOnboardingStatusResponse\"$\x82\xd3\xe4\x93\x02\x1e\x12\x1c/api/tasks/onboarding/status\x12\x85\x01\n" +
|
||||
"\fAdvanceStage\x12!.topfans.task.AdvanceStageRequest\x1a\".topfans.task.AdvanceStageResponse\".\x82\xd3\xe4\x93\x02(:\x01*\"#/api/tasks/onboarding/advance-stage\x12\x9f\x01\n" +
|
||||
"\x15ClaimOnboardingReward\x12*.topfans.task.ClaimOnboardingRewardRequest\x1a+.topfans.task.ClaimOnboardingRewardResponse\"-\x82\xd3\xe4\x93\x02':\x01*\"\"/api/tasks/onboarding/claim-reward\x12\x94\x01\n" +
|
||||
"\x14GetExhibitionRevenue\x12).topfans.task.GetExhibitionRevenueRequest\x1a*.topfans.task.GetExhibitionRevenueResponse\"%\x82\xd3\xe4\x93\x02\x1f\x12\x1d/api/tasks/exhibition-revenue\x12\xa3\x01\n" +
|
||||
"\x16ClaimExhibitionRevenue\x12+.topfans.task.ClaimExhibitionRevenueRequest\x1a,.topfans.task.ClaimExhibitionRevenueResponse\".\x82\xd3\xe4\x93\x02(:\x01*\"#/api/tasks/exhibition-revenue/claim\x12\xb0\x01\n" +
|
||||
"\x19ClaimAllExhibitionRevenue\x12..topfans.task.ClaimAllExhibitionRevenueRequest\x1a/.topfans.task.ClaimAllExhibitionRevenueResponse\"2\x82\xd3\xe4\x93\x02,:\x01*\"'/api/tasks/exhibition-revenue/claim-all2\xe1\x01\n" +
|
||||
"\x15ClaimOnboardingReward\x12*.topfans.task.ClaimOnboardingRewardRequest\x1a+.topfans.task.ClaimOnboardingRewardResponse\"-\x82\xd3\xe4\x93\x02':\x01*\"\"/api/tasks/onboarding/claim-reward\x12\x97\x01\n" +
|
||||
"\x14GetExhibitionRevenue\x12).topfans.task.GetExhibitionRevenueRequest\x1a*.topfans.task.GetExhibitionRevenueResponse\"(\x82\xd3\xe4\x93\x02\"\x12 /api/v1/tasks/exhibition-revenue\x12\xa6\x01\n" +
|
||||
"\x16ClaimExhibitionRevenue\x12+.topfans.task.ClaimExhibitionRevenueRequest\x1a,.topfans.task.ClaimExhibitionRevenueResponse\"1\x82\xd3\xe4\x93\x02+:\x01*\"&/api/v1/tasks/exhibition-revenue/claim\x12\xb3\x01\n" +
|
||||
"\x19ClaimAllExhibitionRevenue\x12..topfans.task.ClaimAllExhibitionRevenueRequest\x1a/.topfans.task.ClaimAllExhibitionRevenueResponse\"5\x82\xd3\xe4\x93\x02/:\x01*\"*/api/v1/tasks/exhibition-revenue/claim-all2\xe1\x01\n" +
|
||||
"\x13TaskInternalService\x12X\n" +
|
||||
"\rInitUserTasks\x12\".topfans.task.InitUserTasksRequest\x1a#.topfans.task.InitUserTasksResponse\x12p\n" +
|
||||
"\x15OnExhibitionCompleted\x12*.topfans.task.OnExhibitionCompletedRequest\x1a+.topfans.task.OnExhibitionCompletedResponseB0Z.github.com/topfans/backend/pkg/proto/task;taskb\x06proto3"
|
||||
|
||||
@ -35,6 +35,8 @@ message Asset {
|
||||
bool is_liked = 20; // 当前用户是否已点赞
|
||||
string info = 21; // 藏品信息
|
||||
int32 display_status = 22; // 展示状态:0=待展示, 1=已展示
|
||||
int64 earnings = 23; // 当前展出收益(实时计算,仅展出中时有值)
|
||||
int64 exhibition_expire_at = 24; // 展出过期时间(毫秒时间戳,仅展出中时有值,0=未展出)
|
||||
}
|
||||
|
||||
// 持有者信息
|
||||
|
||||
@ -46,6 +46,9 @@ service GalleryService {
|
||||
};
|
||||
}
|
||||
|
||||
// 内部RPC:根据资产ID移除展品(用于领取收益后下架)
|
||||
rpc RemoveExhibitionByAsset(RemoveExhibitionByAssetRequest) returns (RemoveExhibitionByAssetResponse);
|
||||
|
||||
// ========== 我的作品相关 ==========
|
||||
|
||||
// 获取我展出的作品列表
|
||||
@ -162,6 +165,16 @@ message RemoveFromSlotResponse {
|
||||
topfans.common.BaseResponse base = 1;
|
||||
}
|
||||
|
||||
// 根据资产ID移除展品请求
|
||||
message RemoveExhibitionByAssetRequest {
|
||||
int64 asset_id = 1; // 资产ID(必填)
|
||||
}
|
||||
|
||||
// 根据资产ID移除展品响应
|
||||
message RemoveExhibitionByAssetResponse {
|
||||
topfans.common.BaseResponse base = 1;
|
||||
}
|
||||
|
||||
// ==================== 我的作品相关消息 ====================
|
||||
|
||||
// 获取我展出的作品列表请求
|
||||
|
||||
@ -160,6 +160,8 @@ message ClaimExhibitionRevenueRequest {
|
||||
message ClaimExhibitionRevenueResponse {
|
||||
topfans.common.BaseResponse base = 1;
|
||||
bool success = 2;
|
||||
int64 crystal_amount = 3; // 当前领取的收益金额
|
||||
int64 total_balance = 4; // 领取后的当前用户全部余额
|
||||
}
|
||||
|
||||
message ClaimAllExhibitionRevenueRequest {
|
||||
@ -228,13 +230,13 @@ service TaskMobileService {
|
||||
option (google.api.http) = { post: "/api/tasks/onboarding/claim-reward"; body: "*"; };
|
||||
}
|
||||
rpc GetExhibitionRevenue(GetExhibitionRevenueRequest) returns (GetExhibitionRevenueResponse) {
|
||||
option (google.api.http) = { get: "/api/tasks/exhibition-revenue"; };
|
||||
option (google.api.http) = { get: "/api/v1/tasks/exhibition-revenue"; };
|
||||
}
|
||||
rpc ClaimExhibitionRevenue(ClaimExhibitionRevenueRequest) returns (ClaimExhibitionRevenueResponse) {
|
||||
option (google.api.http) = { post: "/api/tasks/exhibition-revenue/claim"; body: "*"; };
|
||||
option (google.api.http) = { post: "/api/v1/tasks/exhibition-revenue/claim"; body: "*"; };
|
||||
}
|
||||
rpc ClaimAllExhibitionRevenue(ClaimAllExhibitionRevenueRequest) returns (ClaimAllExhibitionRevenueResponse) {
|
||||
option (google.api.http) = { post: "/api/tasks/exhibition-revenue/claim-all"; body: "*"; };
|
||||
option (google.api.http) = { post: "/api/v1/tasks/exhibition-revenue/claim-all"; body: "*"; };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
-- ============================================
|
||||
-- 展览表索引和外键修改
|
||||
-- 移除 asset_id 的唯一约束,改为普通索引
|
||||
-- 执行方式: psql -h <host> -U <user> -d <db> -f backend/scripts/migrate_exhibition_remove_unique_constraint.sql
|
||||
-- 创建日期: 2026-05-15
|
||||
-- ============================================
|
||||
|
||||
-- 1. 移除 asset_id 的唯一约束
|
||||
ALTER TABLE exhibitions DROP CONSTRAINT IF EXISTS uk_asset;
|
||||
|
||||
-- 2. 添加普通索引(如果不存在)
|
||||
CREATE INDEX IF NOT EXISTS idx_asset ON exhibitions(asset_id);
|
||||
|
||||
-- 3. 确认修改结果
|
||||
DO $$
|
||||
BEGIN
|
||||
-- 检查唯一约束是否已移除
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'uk_asset'
|
||||
) THEN
|
||||
RAISE NOTICE '唯一约束 uk_asset 已成功移除';
|
||||
ELSE
|
||||
RAISE WARNING '唯一约束 uk_asset 仍然存在';
|
||||
END IF;
|
||||
|
||||
-- 检查索引是否已创建
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM pg_indexes WHERE indexname = 'idx_asset'
|
||||
) THEN
|
||||
RAISE NOTICE '索引 idx_asset 已成功创建';
|
||||
ELSE
|
||||
RAISE WARNING '索引 idx_asset 创建失败';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ============================================
|
||||
-- 完成
|
||||
-- ============================================
|
||||
@ -50,6 +50,12 @@ type AssetRepository interface {
|
||||
|
||||
// IsExhibiting 检查资产是否正在展出中
|
||||
IsExhibiting(assetID int64) (bool, error)
|
||||
|
||||
// GetExhibitionStartTime 获取资产展出开始时间(如果正在展出)
|
||||
GetExhibitionStartTime(assetID int64) (int64, error)
|
||||
|
||||
// GetExhibitionExpireTime 获取资产展出过期时间(如果正在展出)
|
||||
GetExhibitionExpireTime(assetID int64) (int64, error)
|
||||
}
|
||||
|
||||
// assetRepository 资产Repository实现
|
||||
@ -336,3 +342,43 @@ func (r *assetRepository) IsExhibiting(assetID int64) (bool, error) {
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// GetExhibitionStartTime 获取资产展出开始时间(如果正在展出)
|
||||
func (r *assetRepository) GetExhibitionStartTime(assetID int64) (int64, error) {
|
||||
if assetID <= 0 {
|
||||
return 0, errors.New("asset_id must be greater than 0")
|
||||
}
|
||||
|
||||
var exhibition models.Exhibition
|
||||
err := r.db.Where("asset_id = ? AND expire_at > ?", assetID, time.Now().UnixMilli()).
|
||||
First(&exhibition).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return 0, nil // 未展出
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return exhibition.StartTime, nil
|
||||
}
|
||||
|
||||
// GetExhibitionExpireTime 获取资产展出过期时间(如果正在展出)
|
||||
func (r *assetRepository) GetExhibitionExpireTime(assetID int64) (int64, error) {
|
||||
if assetID <= 0 {
|
||||
return 0, errors.New("asset_id must be greater than 0")
|
||||
}
|
||||
|
||||
var exhibition models.Exhibition
|
||||
err := r.db.Where("asset_id = ? AND expire_at > ?", assetID, time.Now().UnixMilli()).
|
||||
First(&exhibition).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return 0, nil // 未展出
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return exhibition.ExpireAt, nil
|
||||
}
|
||||
|
||||
@ -134,6 +134,6 @@ func GetExhibitionDuration() int64 {
|
||||
zap.Error(err))
|
||||
return 14400
|
||||
}
|
||||
// 数据库存储的是小时,转换为秒
|
||||
return int64(config.ConfigValue) * 3600
|
||||
// 数据库存储的是小时,转换为秒(先乘后转换,避免 int64(0.10)=0 的截断问题)
|
||||
return int64(config.ConfigValue * 3600)
|
||||
}
|
||||
|
||||
@ -99,9 +99,28 @@ func main() {
|
||||
|
||||
// 创建 Repository 层实例
|
||||
db := database.GetDB()
|
||||
// 自动迁移展馆相关表(booth_slots / exhibitions)
|
||||
if err := db.AutoMigrate(&models.BoothSlot{}, &models.Exhibition{}); err != nil {
|
||||
logger.Logger.Fatal(fmt.Sprintf("Failed to migrate gallery tables: %v", err))
|
||||
|
||||
// 安全迁移:只在表不存在时才创建表,不自动重建
|
||||
// 这样可以避免 Gorm AutoMigrate 在检测到索引不匹配时重建表导致数据丢失
|
||||
if !db.Migrator().HasTable(&models.Exhibition{}) {
|
||||
logger.Logger.Info("Exhibitions table does not exist, creating...")
|
||||
if err := db.AutoMigrate(&models.Exhibition{}); err != nil {
|
||||
logger.Logger.Fatal(fmt.Sprintf("Failed to migrate Exhibition table: %v", err))
|
||||
}
|
||||
logger.Logger.Info("Exhibition table created successfully")
|
||||
} else {
|
||||
logger.Logger.Info("Exhibitions table already exists, skipping AutoMigrate to preserve data")
|
||||
}
|
||||
|
||||
// 同样处理 booth_slots 表
|
||||
if !db.Migrator().HasTable(&models.BoothSlot{}) {
|
||||
logger.Logger.Info("BoothSlots table does not exist, creating...")
|
||||
if err := db.AutoMigrate(&models.BoothSlot{}); err != nil {
|
||||
logger.Logger.Fatal(fmt.Sprintf("Failed to migrate BoothSlot table: %v", err))
|
||||
}
|
||||
logger.Logger.Info("BoothSlot table created successfully")
|
||||
} else {
|
||||
logger.Logger.Info("BoothSlots table already exists, skipping AutoMigrate to preserve data")
|
||||
}
|
||||
|
||||
galleryRepo := repository.NewGalleryRepository(db)
|
||||
|
||||
@ -421,6 +421,41 @@ func (p *GalleryProvider) GetUserExhibitedAssets(ctx context.Context, req *pb.Ge
|
||||
return p.exhibitionService.GetUserExhibitedAssets(ctx, userID, starID, req)
|
||||
}
|
||||
|
||||
// RemoveExhibitionByAsset 根据资产ID移除展品(内部RPC,用于领取收益后下架)
|
||||
func (p *GalleryProvider) RemoveExhibitionByAsset(ctx context.Context, req *pb.RemoveExhibitionByAssetRequest) (*pb.RemoveExhibitionByAssetResponse, error) {
|
||||
logger.Logger.Info("Received RemoveExhibitionByAsset request",
|
||||
zap.Int64("asset_id", req.AssetId),
|
||||
)
|
||||
|
||||
// 调用Service层
|
||||
err := p.exhibitionService.RemoveExhibitionByAsset(ctx, req.AssetId)
|
||||
if err != nil {
|
||||
logger.Logger.Error("RemoveExhibitionByAsset failed",
|
||||
zap.Int64("asset_id", req.AssetId),
|
||||
zap.Error(err),
|
||||
)
|
||||
return &pb.RemoveExhibitionByAssetResponse{
|
||||
Base: &pbCommon.BaseResponse{
|
||||
Code: appErrors.ToStatusCode(err),
|
||||
Message: err.Error(),
|
||||
Timestamp: 0,
|
||||
},
|
||||
}, err
|
||||
}
|
||||
|
||||
logger.Logger.Info("RemoveExhibitionByAsset successful",
|
||||
zap.Int64("asset_id", req.AssetId),
|
||||
)
|
||||
|
||||
return &pb.RemoveExhibitionByAssetResponse{
|
||||
Base: &pbCommon.BaseResponse{
|
||||
Code: pbCommon.StatusCode_STATUS_OK,
|
||||
Message: "success",
|
||||
Timestamp: 0,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ==================== 辅助函数 ====================
|
||||
|
||||
// extractUserInfoFromDubboAttachments 从Dubbo attachments提取用户信息
|
||||
|
||||
@ -23,6 +23,7 @@ type GalleryRepository interface {
|
||||
// 展品相关
|
||||
GetExhibitionByAsset(assetID int64) (*models.Exhibition, error)
|
||||
GetExhibitionBySlot(slotID int64) (*models.Exhibition, error)
|
||||
GetActiveExhibitionBySlot(slotID, now int64) (*models.Exhibition, error)
|
||||
GetExhibitionsByUser(userID, starID int64) ([]*models.Exhibition, error)
|
||||
CreateExhibition(exhibition *models.Exhibition) error
|
||||
DeleteExhibition(exhibitionID int64) error
|
||||
@ -37,6 +38,8 @@ type GalleryRepository interface {
|
||||
PlaceExhibitionTx(exhibition *models.Exhibition, displayStatus int32) error
|
||||
// 事务性操作:删除展品并更新展示状态(原子操作)
|
||||
RemoveExhibitionTx(exhibitionID int64, assetID int64) error
|
||||
// 更新展览过期时间(用于清理后防止重复处理)
|
||||
UpdateExhibitionExpireAt(exhibitionID int64, expireAt int64) error
|
||||
|
||||
// ========== 我的作品相关 ==========
|
||||
|
||||
@ -227,6 +230,19 @@ func (r *galleryRepository) GetExhibitionBySlot(slotID int64) (*models.Exhibitio
|
||||
return &exhibition, nil
|
||||
}
|
||||
|
||||
// GetActiveExhibitionBySlot 根据展位ID获取活跃展品展示记录(未删除且未过期)
|
||||
func (r *galleryRepository) GetActiveExhibitionBySlot(slotID, now int64) (*models.Exhibition, error) {
|
||||
var exhibition models.Exhibition
|
||||
err := r.db.Where("slot_id = ? AND deleted_at IS NULL AND expire_at > ?", slotID, now).First(&exhibition).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &exhibition, nil
|
||||
}
|
||||
|
||||
// GetExhibitionsByUser 获取用户的所有展品展示记录(不含已删除)
|
||||
func (r *galleryRepository) GetExhibitionsByUser(userID, starID int64) ([]*models.Exhibition, error) {
|
||||
var exhibitions []*models.Exhibition
|
||||
@ -235,24 +251,27 @@ func (r *galleryRepository) GetExhibitionsByUser(userID, starID int64) ([]*model
|
||||
return exhibitions, err
|
||||
}
|
||||
|
||||
// CreateExhibition 创建展品展示记录(支持软删除后重新展出)
|
||||
// asset_id 唯一索引冲突时:若旧记录已软删除则物理删除后重新插入;否则报错
|
||||
// CreateExhibition 创建展品展示记录
|
||||
// 允许多个 asset_id 记录,但同一 asset_id 只能有一个未删除且未过期的展出记录
|
||||
func (r *galleryRepository) CreateExhibition(exhibition *models.Exhibition) error {
|
||||
now := time.Now().UnixMilli()
|
||||
|
||||
// 检查是否有未删除且未过期的同一 asset_id 记录
|
||||
var count int64
|
||||
err := r.db.Model(&models.Exhibition{}).
|
||||
Where("asset_id = ? AND deleted_at IS NULL AND expire_at > ?", exhibition.AssetID, now).
|
||||
Count(&count).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("该藏品正在展出中,无法重复放置")
|
||||
}
|
||||
|
||||
exhibition.CreatedAt = now
|
||||
exhibition.UpdatedAt = now
|
||||
exhibition.DeletedAt = nil
|
||||
|
||||
// 在事务中:先物理删除已软删除的旧记录,再插入新记录
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Exec(`
|
||||
DELETE FROM exhibitions
|
||||
WHERE asset_id = ? AND deleted_at IS NOT NULL
|
||||
`, exhibition.AssetID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Create(exhibition).Error
|
||||
})
|
||||
return r.db.Create(exhibition).Error
|
||||
}
|
||||
|
||||
// DeleteExhibition 软删除展品展示记录(根据ID)
|
||||
@ -286,13 +305,14 @@ func (r *galleryRepository) GetExpiredExhibitions(beforeTime int64) ([]*models.E
|
||||
|
||||
// GetAssetsWithInvalidDisplayStatus 获取 display_status=1 但没有有效 exhibition 的资产ID列表
|
||||
// 用于清理手动软删除导致的 display_status 不同步问题
|
||||
// 注意:这里只要 exhibition 未删除(deleted_at IS NULL)就认为有效,包含已过期未领取的
|
||||
func (r *galleryRepository) GetAssetsWithInvalidDisplayStatus() ([]int64, error) {
|
||||
var assetIDs []int64
|
||||
|
||||
// 子查询:查找有有效 exhibition 记录的 asset_id
|
||||
// 子查询:查找有有效 exhibition 记录的 asset_id(不管是否过期,只要未删除)
|
||||
subQuery := r.db.Model(&models.Exhibition{}).
|
||||
Select("asset_id").
|
||||
Where("deleted_at IS NULL AND expire_at > ?", time.Now().UnixMilli())
|
||||
Where("deleted_at IS NULL")
|
||||
|
||||
// 查找 display_status=1 但没有有效 exhibition 记录的资产
|
||||
err := r.db.Model(&models.AssetRegistry{}).
|
||||
@ -313,23 +333,29 @@ func (r *galleryRepository) UpdateAssetRegistryDisplayStatus(assetID int64, disp
|
||||
// PlaceExhibitionTx 事务性创建展品并更新展示状态(原子操作)
|
||||
func (r *galleryRepository) PlaceExhibitionTx(exhibition *models.Exhibition, displayStatus int32) error {
|
||||
now := time.Now().UnixMilli()
|
||||
|
||||
// 检查是否有未删除且未过期的同一 asset_id 记录
|
||||
var count int64
|
||||
err := r.db.Model(&models.Exhibition{}).
|
||||
Where("asset_id = ? AND deleted_at IS NULL AND expire_at > ?", exhibition.AssetID, now).
|
||||
Count(&count).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("该藏品正在展出中,无法重复放置")
|
||||
}
|
||||
|
||||
exhibition.CreatedAt = now
|
||||
exhibition.UpdatedAt = now
|
||||
exhibition.DeletedAt = nil
|
||||
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
// 1. 物理删除已软删除的旧记录
|
||||
if err := tx.Exec(`
|
||||
DELETE FROM exhibitions
|
||||
WHERE asset_id = ? AND deleted_at IS NOT NULL
|
||||
`, exhibition.AssetID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 2. 插入新记录
|
||||
// 1. 插入新记录(允许多个 asset_id 记录)
|
||||
if err := tx.Create(exhibition).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
// 3. 更新展示状态(与展出操作在同一事务中)
|
||||
// 2. 更新展示状态(与展出操作在同一事务中)
|
||||
if err := tx.Model(&models.AssetRegistry{}).
|
||||
Where("asset_id = ?", exhibition.AssetID).
|
||||
Update("display_status", displayStatus).Error; err != nil {
|
||||
@ -363,24 +389,30 @@ func (r *galleryRepository) RemoveExhibitionTx(exhibitionID int64, assetID int64
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateExhibitionExpireAt 更新展览过期时间(用于清理后防止重复处理)
|
||||
func (r *galleryRepository) UpdateExhibitionExpireAt(exhibitionID int64, expireAt int64) error {
|
||||
return r.db.Model(&models.Exhibition{}).
|
||||
Where("id = ?", exhibitionID).
|
||||
Update("expire_at", expireAt).Error
|
||||
}
|
||||
|
||||
// ========== 我的作品相关实现 ==========
|
||||
|
||||
// GetMyExhibitedAssets 获取我展出的作品列表(只返回展出中且未过期的,含收益)
|
||||
// GetMyExhibitedAssets 获取我展出的作品列表(返回展出中且未下架的,含收益)
|
||||
// 包含未过期和已过期但未领取的展品,用户领取收益时才下架
|
||||
func (r *galleryRepository) GetMyExhibitedAssets(userID, starID int64, page, pageSize int) ([]*ExhibitedAssetInfo, int64, error) {
|
||||
var items []*ExhibitedAssetInfo
|
||||
var total int64
|
||||
|
||||
now := time.Now().UnixMilli()
|
||||
|
||||
// 计数查询
|
||||
// 计数查询:只要未下架(deleted_at IS NULL)都显示,包含已过期待领取的
|
||||
err := r.db.Model(&models.Exhibition{}).
|
||||
Where("occupier_uid = ? AND occupier_star_id = ? AND deleted_at IS NULL AND expire_at > ?", userID, starID, now).
|
||||
Where("occupier_uid = ? AND occupier_star_id = ? AND deleted_at IS NULL", userID, starID).
|
||||
Count(&total).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 数据查询
|
||||
// 数据查询:只过滤已下架的,不过滤过期(用户领取收益时才下架)
|
||||
offset := (page - 1) * pageSize
|
||||
err = r.db.Model(&models.Exhibition{}).
|
||||
Raw(`
|
||||
@ -390,10 +422,10 @@ func (r *galleryRepository) GetMyExhibitedAssets(userID, starID int64, page, pag
|
||||
JOIN assets a ON a.id = exhibitions.asset_id
|
||||
JOIN booth_slots bs ON bs.slot_id = exhibitions.slot_id
|
||||
WHERE exhibitions.occupier_uid = ? AND exhibitions.occupier_star_id = ?
|
||||
AND exhibitions.deleted_at IS NULL AND exhibitions.expire_at > ?
|
||||
ORDER BY bs.slot_index ASC
|
||||
AND exhibitions.deleted_at IS NULL
|
||||
ORDER BY exhibitions.expire_at DESC, bs.slot_index ASC
|
||||
LIMIT ? OFFSET ?
|
||||
`, userID, starID, now, pageSize, offset).Scan(&items).Error
|
||||
`, userID, starID, pageSize, offset).Scan(&items).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
@ -401,6 +433,7 @@ func (r *galleryRepository) GetMyExhibitedAssets(userID, starID int64, page, pag
|
||||
|
||||
// 实时计算展示收益:R1 = R0 × T × [100% + Buff(n)]
|
||||
// R0 = 5 水晶/小时
|
||||
now := time.Now().UnixMilli()
|
||||
for _, item := range items {
|
||||
item.Earnings = calculateRealtimeEarnings(item.LikeCount, item.ExhibitedAt, now)
|
||||
}
|
||||
@ -423,20 +456,17 @@ func (r *galleryRepository) GetUserExhibitedAssets(userID, starID int64, page, p
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 数据查询
|
||||
// 数据查询(实时计算收益)
|
||||
offset := (page - 1) * pageSize
|
||||
err = r.db.Model(&models.Exhibition{}).
|
||||
Raw(`
|
||||
SELECT exhibitions.asset_id, a.name, a.cover_url, a.like_count,
|
||||
exhibitions.start_time as exhibited_at, exhibitions.expire_at, bs.slot_index,
|
||||
COALESCE(CAST(SUM(err.crystal_amount) / 10 AS bigint), 0) as earnings
|
||||
exhibitions.start_time as exhibited_at, exhibitions.expire_at, bs.slot_index
|
||||
FROM exhibitions
|
||||
JOIN assets a ON a.id = exhibitions.asset_id
|
||||
JOIN booth_slots bs ON bs.slot_id = exhibitions.slot_id
|
||||
LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'
|
||||
WHERE exhibitions.occupier_uid = ? AND exhibitions.occupier_star_id = ?
|
||||
AND exhibitions.deleted_at IS NULL AND exhibitions.expire_at > ?
|
||||
GROUP BY exhibitions.asset_id, a.name, a.cover_url, a.like_count, exhibitions.start_time, exhibitions.expire_at, bs.slot_index
|
||||
ORDER BY bs.slot_index ASC
|
||||
LIMIT ? OFFSET ?
|
||||
`, userID, starID, now, pageSize, offset).Scan(&items).Error
|
||||
@ -445,6 +475,11 @@ func (r *galleryRepository) GetUserExhibitedAssets(userID, starID int64, page, p
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 实时计算每个资产的收益
|
||||
for _, item := range items {
|
||||
item.Earnings = calculateRealtimeEarnings(item.LikeCount, item.ExhibitedAt, now)
|
||||
}
|
||||
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
|
||||
@ -169,5 +169,5 @@ func GetMaxFriends() int {
|
||||
zap.Error(err))
|
||||
return 50
|
||||
}
|
||||
return config.ConfigValue
|
||||
return int(config.ConfigValue)
|
||||
}
|
||||
|
||||
@ -578,33 +578,29 @@ func (r *socialRepositoryImpl) GetMyLikedAssets(userID, starID int64, page, page
|
||||
var items []*LikedAssetInfo
|
||||
var total int64
|
||||
|
||||
// 子查询:查找当前时间未过期的展出记录
|
||||
now := time.Now().UnixMilli()
|
||||
|
||||
// 计数查询(使用 DISTINCT 因为一个资产可能在多个展位展出)
|
||||
// 只要资产未删除且未下架就显示,包含已过期的(用户可继续查看点赞记录)
|
||||
countQuery := r.db.Model(&models.AssetLike{}).
|
||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||
Where("e.deleted_at IS NULL AND e.expire_at > ?", now)
|
||||
Where("e.deleted_at IS NULL")
|
||||
|
||||
if err := countQuery.Distinct("asset_likes.asset_id").Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 数据查询
|
||||
// 数据查询:只过滤已下架的,不过滤过期
|
||||
offset := (page - 1) * pageSize
|
||||
err := r.db.Model(&models.AssetLike{}).
|
||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||
asset_likes.created_at as liked_at,
|
||||
COALESCE(SUM(err.crystal_amount), 0) as earnings`).
|
||||
asset_likes.created_at as liked_at`).
|
||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
||||
Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'").
|
||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||
Where("e.deleted_at IS NULL AND e.expire_at > ?", now).
|
||||
Where("e.deleted_at IS NULL").
|
||||
Group("asset_likes.asset_id, a.name, a.cover_url, a.like_count, asset_likes.created_at").
|
||||
Order("asset_likes.created_at DESC").
|
||||
Limit(pageSize).
|
||||
@ -615,9 +611,54 @@ func (r *socialRepositoryImpl) GetMyLikedAssets(userID, starID int64, page, page
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 实时计算每个资产的收益
|
||||
now := time.Now().UnixMilli()
|
||||
for _, item := range items {
|
||||
// 获取该资产的展出开始时间(如果还在展出中就计算收益)
|
||||
var exhibition models.Exhibition
|
||||
if err := r.db.Where("asset_id = ? AND deleted_at IS NULL", item.AssetID).
|
||||
First(&exhibition).Error; err == nil {
|
||||
item.Earnings = calculateRealtimeEarnings(item.LikeCount, exhibition.StartTime, now)
|
||||
}
|
||||
}
|
||||
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
// calculateRealtimeEarnings 实时计算展示收益
|
||||
// 公式:R1 = R0 × T × [100% + Buff(n)]
|
||||
// R0 = 5 水晶/小时,T = 上架时长(小时),Buff(n) 根据点赞数计算
|
||||
func calculateRealtimeEarnings(likeCount int32, startTime, now int64) int64 {
|
||||
R0 := int64(5) // 水晶/小时
|
||||
|
||||
// 计算上架时长(毫秒转小时)
|
||||
T := (now - startTime) / 3600000
|
||||
if T <= 0 {
|
||||
T = 1 // 最少1小时
|
||||
}
|
||||
|
||||
// 计算Buff
|
||||
var buff int
|
||||
switch {
|
||||
case likeCount >= 30:
|
||||
buff = 30
|
||||
case likeCount >= 10:
|
||||
buff = 20
|
||||
case likeCount >= 5:
|
||||
buff = 10
|
||||
default:
|
||||
buff = 0
|
||||
}
|
||||
|
||||
// 基础收益
|
||||
baseRevenue := R0 * T
|
||||
|
||||
// 应用Buff加成:R1 = R0 × T × (100% + Buff)
|
||||
buffedRevenue := baseRevenue * (100 + int64(buff)) / 100
|
||||
|
||||
return buffedRevenue
|
||||
}
|
||||
|
||||
// GetMyTodayLikedAssets 获取我今日点赞的作品列表(只返回展出中且未过期的)
|
||||
func (r *socialRepositoryImpl) GetMyTodayLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) {
|
||||
now := time.Now()
|
||||
@ -641,11 +682,9 @@ func (r *socialRepositoryImpl) GetMyTodayLikedAssets(userID, starID int64, page,
|
||||
offset := (page - 1) * pageSize
|
||||
err := r.db.Model(&models.AssetLike{}).
|
||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||
asset_likes.created_at as liked_at,
|
||||
COALESCE(SUM(err.crystal_amount), 0) as earnings`).
|
||||
asset_likes.created_at as liked_at`).
|
||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
||||
Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'").
|
||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||
Where("asset_likes.created_at >= ?", startOfDay).
|
||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||
@ -660,6 +699,15 @@ func (r *socialRepositoryImpl) GetMyTodayLikedAssets(userID, starID int64, page,
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 实时计算每个资产的收益
|
||||
for _, item := range items {
|
||||
var exhibition models.Exhibition
|
||||
if err := r.db.Where("asset_id = ? AND deleted_at IS NULL AND expire_at > ?", item.AssetID, now.UnixMilli()).
|
||||
First(&exhibition).Error; err == nil {
|
||||
item.Earnings = calculateRealtimeEarnings(item.LikeCount, exhibition.StartTime, now.UnixMilli())
|
||||
}
|
||||
}
|
||||
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
@ -693,11 +741,9 @@ func (r *socialRepositoryImpl) GetMyWeekLikedAssets(userID, starID int64, page,
|
||||
offset := (page - 1) * pageSize
|
||||
err := r.db.Model(&models.AssetLike{}).
|
||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||
asset_likes.created_at as liked_at,
|
||||
COALESCE(SUM(err.crystal_amount), 0) as earnings`).
|
||||
asset_likes.created_at as liked_at`).
|
||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
||||
Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'").
|
||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||
Where("asset_likes.created_at >= ?", startOfWeekMillis).
|
||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||
@ -712,6 +758,16 @@ func (r *socialRepositoryImpl) GetMyWeekLikedAssets(userID, starID int64, page,
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 实时计算每个资产的收益
|
||||
nowMillis := now.UnixMilli()
|
||||
for _, item := range items {
|
||||
var exhibition models.Exhibition
|
||||
if err := r.db.Where("asset_id = ? AND deleted_at IS NULL AND expire_at > ?", item.AssetID, nowMillis).
|
||||
First(&exhibition).Error; err == nil {
|
||||
item.Earnings = calculateRealtimeEarnings(item.LikeCount, exhibition.StartTime, nowMillis)
|
||||
}
|
||||
}
|
||||
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
@ -736,11 +792,9 @@ func (r *socialRepositoryImpl) GetUserLikedAssets(userID, starID int64, page, pa
|
||||
offset := (page - 1) * pageSize
|
||||
err := r.db.Model(&models.AssetLike{}).
|
||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||
asset_likes.created_at as liked_at,
|
||||
COALESCE(SUM(err.crystal_amount), 0) as earnings`).
|
||||
asset_likes.created_at as liked_at`).
|
||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
||||
Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'").
|
||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||
Where("e.deleted_at IS NULL AND e.expire_at > ?", now).
|
||||
@ -754,5 +808,14 @@ func (r *socialRepositoryImpl) GetUserLikedAssets(userID, starID int64, page, pa
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 实时计算每个资产的收益
|
||||
for _, item := range items {
|
||||
var exhibition models.Exhibition
|
||||
if err := r.db.Where("asset_id = ? AND deleted_at IS NULL AND expire_at > ?", item.AssetID, now).
|
||||
First(&exhibition).Error; err == nil {
|
||||
item.Earnings = calculateRealtimeEarnings(item.LikeCount, exhibition.StartTime, now)
|
||||
}
|
||||
}
|
||||
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
40
backend/services/taskService/client/gallery_rpc_client.go
Normal file
40
backend/services/taskService/client/gallery_rpc_client.go
Normal file
@ -0,0 +1,40 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/topfans/backend/pkg/logger"
|
||||
pbCommon "github.com/topfans/backend/pkg/proto/common"
|
||||
pbGallery "github.com/topfans/backend/pkg/proto/gallery"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type GalleryServiceClient interface {
|
||||
RemoveExhibitionByAsset(ctx context.Context, assetID int64) error
|
||||
}
|
||||
|
||||
type galleryServiceClient struct {
|
||||
client pbGallery.GalleryService
|
||||
}
|
||||
|
||||
func NewGalleryServiceClient(client pbGallery.GalleryService) GalleryServiceClient {
|
||||
return &galleryServiceClient{client: client}
|
||||
}
|
||||
|
||||
func (c *galleryServiceClient) RemoveExhibitionByAsset(ctx context.Context, assetID int64) error {
|
||||
logger.Logger.Debug("Calling GalleryService.RemoveExhibitionByAsset",
|
||||
zap.Int64("asset_id", assetID))
|
||||
resp, err := c.client.RemoveExhibitionByAsset(ctx, &pbGallery.RemoveExhibitionByAssetRequest{
|
||||
AssetId: assetID,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Logger.Error("GalleryService.RemoveExhibitionByAsset failed", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
|
||||
logger.Logger.Warn("RemoveExhibitionByAsset non-zero code", zap.Int32("code", int32(resp.Base.Code)), zap.String("message", resp.Base.Message))
|
||||
return fmt.Errorf("RemoveExhibitionByAsset failed with code: %d, message: %s", resp.Base.Code, resp.Base.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -14,7 +14,8 @@ type DatabaseConfig struct {
|
||||
}
|
||||
|
||||
type ServiceURLs struct {
|
||||
UserService string
|
||||
UserService string
|
||||
GalleryService string
|
||||
}
|
||||
|
||||
type WorkerConfig struct {
|
||||
@ -25,7 +26,7 @@ type WorkerConfig struct {
|
||||
|
||||
var (
|
||||
DBConfig = &DatabaseConfig{}
|
||||
ServiceURLsConfig = &ServiceURLs{UserService: "tri://localhost:20000"}
|
||||
ServiceURLsConfig = &ServiceURLs{UserService: "tri://localhost:20000", GalleryService: "tri://localhost:20004"}
|
||||
WorkerConfigData = &WorkerConfig{
|
||||
ResetHour: 5, ResetMinute: 0,
|
||||
RevenueBatchSize: 100, RevenueMaxRetries: 3,
|
||||
@ -52,6 +53,7 @@ func InitConfig() {
|
||||
flag.StringVar(&DBConfig.DBName, "db-name", getEnv("DB_NAME", "topfans"), "数据库名称")
|
||||
flag.StringVar(&DBConfig.SSLMode, "db-sslmode", "disable", "数据库 SSL 模式")
|
||||
flag.StringVar(&ServiceURLsConfig.UserService, "user-service-url", getEnv("USER_SERVICE_URL", "tri://localhost:20000"), "User Service RPC 地址")
|
||||
flag.StringVar(&ServiceURLsConfig.GalleryService, "gallery-service-url", getEnv("GALLERY_SERVICE_URL", "tri://localhost:20004"), "Gallery Service RPC 地址")
|
||||
flag.IntVar(&WorkerConfigData.ResetHour, "reset-hour", getEnvInt("RESET_HOUR", 5), "每日重置小时(Asia/Shanghai)")
|
||||
flag.IntVar(&WorkerConfigData.ResetMinute, "reset-minute", getEnvInt("RESET_MINUTE", 0), "每日重置分钟")
|
||||
flag.IntVar(&WorkerConfigData.RevenueBatchSize, "revenue-batch-size", getEnvInt("REVENUE_BATCH_SIZE", 100), "收益自动发放批次大小")
|
||||
@ -60,5 +62,6 @@ func InitConfig() {
|
||||
log.Println("taskService 配置初始化完成")
|
||||
log.Printf(" 数据库: %s:%d/%s", DBConfig.Host, DBConfig.Port, DBConfig.DBName)
|
||||
log.Printf(" User Service: %s", ServiceURLsConfig.UserService)
|
||||
log.Printf(" Gallery Service: %s", ServiceURLsConfig.GalleryService)
|
||||
log.Printf(" 重置时间: %02d:%02d Asia/Shanghai", WorkerConfigData.ResetHour, WorkerConfigData.ResetMinute)
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import (
|
||||
"github.com/topfans/backend/pkg/database"
|
||||
"github.com/topfans/backend/pkg/logger"
|
||||
pb "github.com/topfans/backend/pkg/proto/task"
|
||||
pbGallery "github.com/topfans/backend/pkg/proto/gallery"
|
||||
pbUser "github.com/topfans/backend/pkg/proto/user"
|
||||
"github.com/topfans/backend/services/taskService/client"
|
||||
"github.com/topfans/backend/services/taskService/config"
|
||||
@ -89,10 +90,24 @@ func main() {
|
||||
userRPCClient := client.NewUserServiceClient(userServiceClient)
|
||||
logger.Logger.Info("User RPC client initialized")
|
||||
|
||||
// 5.1 Init galleryService Dubbo client + RPC client
|
||||
galleryCli, err := dubboclient.NewClient(
|
||||
dubboclient.WithClientURL(config.ServiceURLsConfig.GalleryService),
|
||||
)
|
||||
if err != nil {
|
||||
logger.Logger.Fatal(fmt.Sprintf("Failed to create galleryService client: %v", err))
|
||||
}
|
||||
galleryServiceClient, err := pbGallery.NewGalleryService(galleryCli)
|
||||
if err != nil {
|
||||
logger.Logger.Fatal(fmt.Sprintf("Failed to get galleryService: %v", err))
|
||||
}
|
||||
galleryRPCClient := client.NewGalleryServiceClient(galleryServiceClient)
|
||||
logger.Logger.Info("Gallery RPC client initialized")
|
||||
|
||||
// 6. Init services
|
||||
dailySvc := service.NewDailyTaskService(dailyRepo, userRPCClient)
|
||||
onboardingSvc := service.NewOnboardingService(onboardingRepo, dailyRepo, userRPCClient)
|
||||
revenueSvc := service.NewRevenueService(revenueRepo, userRPCClient)
|
||||
revenueSvc := service.NewRevenueService(revenueRepo, userRPCClient, galleryRPCClient)
|
||||
logger.Logger.Info("Services initialized")
|
||||
|
||||
// 7. Init worker(goroutine 中启动)
|
||||
|
||||
@ -25,10 +25,10 @@ type FanProfileRepository interface {
|
||||
// Create 创建粉丝档案
|
||||
Create(profile *models.FanProfile) error
|
||||
|
||||
// GetByUserAndStar 根据user_id + star_id查询
|
||||
// GetByUserAndStar 根据user_id + star_id查询(等级为实时计算,基于累计时长+当前展出中时长)
|
||||
GetByUserAndStar(userID, starID int64) (*models.FanProfile, error)
|
||||
|
||||
// GetByUserID 查询用户的所有粉丝身份
|
||||
// GetByUserID 查询用户的所有粉丝身份(等级为实时计算)
|
||||
GetByUserID(userID int64) ([]*models.FanProfile, error)
|
||||
|
||||
// ExistsByNickname 检查昵称是否已存在
|
||||
@ -117,7 +117,7 @@ func (r *fanProfileRepository) Create(profile *models.FanProfile) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetByUserAndStar 根据user_id + star_id查询
|
||||
// GetByUserAndStar 根据user_id + star_id查询(等级为实时计算,基于累计时长+当前展出中时长)
|
||||
func (r *fanProfileRepository) GetByUserAndStar(userID, starID int64) (*models.FanProfile, error) {
|
||||
if userID <= 0 {
|
||||
return nil, errors.New("user_id must be greater than 0")
|
||||
@ -136,10 +136,49 @@ func (r *fanProfileRepository) GetByUserAndStar(userID, starID int64) (*models.F
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 实时计算等级:累计时长 + 当前展出中时长
|
||||
profile.Level = r.calculateRealtimeLevel(userID, starID)
|
||||
|
||||
return &profile, nil
|
||||
}
|
||||
|
||||
// GetByUserID 查询用户的所有粉丝身份
|
||||
// calculateRealtimeLevel 实时计算用户等级(基于累计时长 + 当前展出中的展品时长)
|
||||
func (r *fanProfileRepository) calculateRealtimeLevel(userID, starID int64) int32 {
|
||||
// 1. 获取累计时长
|
||||
var exhibitionHours models.UserExhibitionHours
|
||||
err := r.db.Where("user_id = ? AND star_id = ?", userID, starID).First(&exhibitionHours).Error
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
totalHours := exhibitionHours.TotalExhibitionHours
|
||||
|
||||
// 2. 获取当前展出中的展品累计时长(从开始到现在)
|
||||
now := time.Now().UnixMilli()
|
||||
var activeHours int64
|
||||
var exhibitions []models.Exhibition
|
||||
if err := r.db.Where("occupier_uid = ? AND occupier_star_id = ? AND deleted_at IS NULL AND expire_at > ?", userID, starID, now).
|
||||
Find(&exhibitions).Error; err == nil {
|
||||
for _, e := range exhibitions {
|
||||
activeHours += (now - e.StartTime) / 3600000
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 取较大值:累计值 vs 当前展出中的实际值(防止负数)
|
||||
realtimeHours := totalHours
|
||||
if activeHours > realtimeHours {
|
||||
realtimeHours = activeHours
|
||||
}
|
||||
|
||||
// 4. 计算等级
|
||||
maxLevel := GetLevelCap()
|
||||
newLevel := CalculateLevelFromExhibitionHours(realtimeHours)
|
||||
if newLevel > maxLevel {
|
||||
newLevel = maxLevel
|
||||
}
|
||||
return newLevel
|
||||
}
|
||||
|
||||
// GetByUserID 查询用户的所有粉丝身份(等级为实时计算)
|
||||
func (r *fanProfileRepository) GetByUserID(userID int64) ([]*models.FanProfile, error) {
|
||||
if userID <= 0 {
|
||||
return nil, errors.New("user_id must be greater than 0")
|
||||
@ -152,6 +191,11 @@ func (r *fanProfileRepository) GetByUserID(userID int64) ([]*models.FanProfile,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 实时计算每个身份的等级
|
||||
for _, profile := range profiles {
|
||||
profile.Level = r.calculateRealtimeLevel(userID, profile.StarID)
|
||||
}
|
||||
|
||||
return profiles, nil
|
||||
}
|
||||
|
||||
|
||||
@ -181,7 +181,7 @@ const handleNavClick = (index) => {
|
||||
.monster-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: drop-shadow(0 8rpx 24rpx rgba(255, 107, 157, 0.5)) drop-shadow(0 0 40rpx rgba(255, 140, 180, 0.3));
|
||||
/* filter: drop-shadow(0 8rpx 24rpx rgba(255, 107, 157, 0.5)) drop-shadow(0 0 40rpx rgba(255, 140, 180, 0.3)); */
|
||||
transition: filter 0.3s ease, transform 0.3s ease;
|
||||
animation: breathe 2s ease-in-out infinite;
|
||||
}
|
||||
@ -235,7 +235,7 @@ const handleNavClick = (index) => {
|
||||
height: 100rpx;
|
||||
margin-bottom: 8rpx;
|
||||
transition: transform 0.3s ease, filter 0.3s ease;
|
||||
filter: drop-shadow(0 6rpx 16rpx rgba(0, 0, 0, 0.4)) drop-shadow(0 2rpx 8rpx rgba(0, 0, 0, 0.2));
|
||||
/* filter: drop-shadow(0 6rpx 16rpx rgba(0, 0, 0, 0.4)) dr8op-shadow(0 2rpx 8rpx rgba(0, 0, 0, 0.2)); */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
@ -169,6 +169,7 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { getMyExhibitedAssetsApi, getMyLikedAssetsApi, getMyTodayLikedAssetsApi, getMyWeekLikedAssetsApi, getMyGalleriesApi, placeAssetToGalleryApi } from '@/utils/api.js';
|
||||
import { getExhibitionRevenue, claimExhibitionRevenue } from '@/utils/task-api.js';
|
||||
import AssetSelector from '../components/AssetSelector.vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { doubleTapLike } from '@/utils/likeHelper.js';
|
||||
@ -276,9 +277,46 @@ const goToAssetDetail = (id) => {
|
||||
const cardTapTimers = {};
|
||||
|
||||
// 领取收益处理
|
||||
const handleClaimReward = (item, _index) => {
|
||||
const handleClaimReward = async (item, _index) => {
|
||||
console.log('领取收益:', item);
|
||||
uni.showToast({ title: '收益已领取', icon: 'success' });
|
||||
|
||||
uni.showLoading({ title: '领取中...' });
|
||||
|
||||
try {
|
||||
// 从缓存获取 star_id
|
||||
const starId = uni.getStorageSync('star_id') || 1;
|
||||
|
||||
// 查询该藏品的可领取收益记录
|
||||
const res = await getExhibitionRevenue(starId, 'claimable', 1, 100);
|
||||
const records = res.data?.items || [];
|
||||
|
||||
// 找到对应资产ID的收益记录
|
||||
const revenueRecord = records.find(r => r.asset_id === item.id);
|
||||
|
||||
if (!revenueRecord) {
|
||||
uni.showToast({ title: '暂无可领取收益', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用领取接口
|
||||
const claimRes = await claimExhibitionRevenue(revenueRecord.id, starId);
|
||||
|
||||
uni.showToast({ title: '收益已领取', icon: 'success' });
|
||||
|
||||
// 更新全局余额
|
||||
if (claimRes?.data?.total_balance !== undefined) {
|
||||
uni.$emit('balanceUpdated', { crystal_balance: claimRes.data.total_balance });
|
||||
}
|
||||
|
||||
// 刷新列表
|
||||
await loadExhibitedAssets();
|
||||
|
||||
} catch (err) {
|
||||
console.error('领取收益失败:', err);
|
||||
uni.showToast({ title: err.message || '领取失败', icon: 'none' });
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
};
|
||||
|
||||
const handleExhibitionCardTap = (item, index) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user