225 lines
6.2 KiB
Protocol Buffer
225 lines
6.2 KiB
Protocol Buffer
syntax = "proto3";
|
||
|
||
package topfans.gallery;
|
||
|
||
import "proto/common.proto";
|
||
import "google/api/annotations.proto";
|
||
|
||
option go_package = "github.com/topfans/backend/pkg/proto/gallery;gallery";
|
||
|
||
// 展馆服务
|
||
service GalleryService {
|
||
// 获取我的展馆
|
||
rpc GetMyGallery(GetMyGalleryRequest) returns (GetMyGalleryResponse) {
|
||
option (google.api.http) = {
|
||
get: "/api/mygalleries"
|
||
};
|
||
}
|
||
|
||
// 获取他人展馆
|
||
rpc GetUserGallery(GetUserGalleryRequest) returns (GetUserGalleryResponse) {
|
||
option (google.api.http) = {
|
||
get: "/api/galleries/{target_uid}"
|
||
};
|
||
}
|
||
|
||
// 在展位展示藏品
|
||
rpc PlaceAsset(PlaceAssetRequest) returns (PlaceAssetResponse) {
|
||
option (google.api.http) = {
|
||
post: "/api/galleries/place"
|
||
body: "*"
|
||
};
|
||
}
|
||
|
||
// 解锁/购买新展位
|
||
rpc UnlockSlot(UnlockSlotRequest) returns (UnlockSlotResponse) {
|
||
option (google.api.http) = {
|
||
post: "/api/galleries/slots_unlock"
|
||
body: "*"
|
||
};
|
||
}
|
||
|
||
// 从展位移除资产(统一接口,支持展位所有者踢走和占位者下架)
|
||
rpc RemoveFromSlot(RemoveFromSlotRequest) returns (RemoveFromSlotResponse) {
|
||
option (google.api.http) = {
|
||
delete: "/api/galleries/slots/{slot_id}/asset"
|
||
};
|
||
}
|
||
|
||
// ========== 我的作品相关 ==========
|
||
|
||
// 获取我展出的作品列表
|
||
rpc GetMyExhibitedAssets(GetMyExhibitedAssetsRequest) returns (GetMyExhibitedAssetsResponse) {
|
||
option (google.api.http) = {
|
||
get: "/api/v1/me/exhibited-assets"
|
||
};
|
||
}
|
||
|
||
// 获取灵感瀑布藏品列表
|
||
rpc GetInspirationFlow(GetInspirationFlowRequest) returns (GetInspirationFlowResponse) {
|
||
option (google.api.http) = {
|
||
get: "/api/v1/inspiration-flow"
|
||
};
|
||
}
|
||
}
|
||
|
||
// 请求和响应消息定义
|
||
message GetMyGalleryRequest {}
|
||
|
||
message GetMyGalleryResponse {
|
||
topfans.common.BaseResponse base = 1;
|
||
GalleryData data = 2;
|
||
}
|
||
|
||
message GetUserGalleryRequest {
|
||
int64 target_uid = 1;
|
||
}
|
||
|
||
message GetUserGalleryResponse {
|
||
topfans.common.BaseResponse base = 1;
|
||
GalleryData data = 2;
|
||
}
|
||
|
||
message PlaceAssetRequest {
|
||
int64 asset_id = 1;
|
||
int64 gallery_owner_id = 2;
|
||
int64 slot_id = 3;
|
||
}
|
||
|
||
message PlaceAssetResponse {
|
||
topfans.common.BaseResponse base = 1;
|
||
PlaceAssetData data = 2;
|
||
}
|
||
|
||
message UnlockSlotRequest {}
|
||
|
||
message UnlockSlotResponse {
|
||
topfans.common.BaseResponse base = 1;
|
||
UnlockSlotData data = 2;
|
||
}
|
||
|
||
// 数据模型
|
||
message GalleryData {
|
||
int64 gallery_owner_id = 1;
|
||
int32 slot_total = 2;
|
||
repeated SlotInfo slots = 3;
|
||
string nickname = 4; // 展馆所有者昵称(从 fan_profiles 表获取)
|
||
}
|
||
|
||
message SlotInfo {
|
||
int64 slot_id = 1;
|
||
int32 slot_index = 2;
|
||
string status = 3; // EMPTY, OCCUPIED, LOCKED
|
||
bool is_enabled = 4;
|
||
AssetInfo asset = 5;
|
||
int64 occupier_uid = 6;
|
||
int64 occupied_at = 7;
|
||
int64 expire_at = 8;
|
||
UnlockCondition unlock_condition = 9;
|
||
string visibility = 10; // public / private
|
||
bool can_operate = 11; // 当前用户是否可以操作此展位
|
||
string operation = 12; // 操作类型: "place" | "remove" | "none"
|
||
}
|
||
|
||
message AssetInfo {
|
||
int64 asset_id = 1;
|
||
string name = 2;
|
||
string cover_url = 3;
|
||
int32 like_count = 4;
|
||
int64 remain_time = 5; // 剩余时间(秒)
|
||
}
|
||
|
||
message UnlockCondition {
|
||
string type = 1; // level, crystal
|
||
int32 value = 2;
|
||
}
|
||
|
||
message PlaceAssetData {
|
||
string status = 1; // OCCUPIED
|
||
string occupied_until = 2; // ISO 8601格式
|
||
int64 occupier_uid = 3; // 占位者用户ID
|
||
}
|
||
|
||
message UnlockSlotData {
|
||
int32 slot_total = 1; // 展位总数
|
||
int64 crystal_balance = 2; // 水晶余额(如果使用水晶购买,显示扣除后的余额)
|
||
}
|
||
|
||
// 从展位移除资产请求
|
||
message RemoveFromSlotRequest {
|
||
int64 slot_id = 1; // 展位ID(必填)
|
||
}
|
||
|
||
// 从展位移除资产响应
|
||
message RemoveFromSlotResponse {
|
||
topfans.common.BaseResponse base = 1;
|
||
}
|
||
|
||
// ==================== 我的作品相关消息 ====================
|
||
|
||
// 获取我展出的作品列表请求
|
||
message GetMyExhibitedAssetsRequest {
|
||
int32 page = 1; // 页码(默认1)
|
||
int32 page_size = 2; // 每页数量(默认20,最大100)
|
||
}
|
||
|
||
// 获取我展出的作品列表响应
|
||
message GetMyExhibitedAssetsResponse {
|
||
topfans.common.BaseResponse base = 1;
|
||
ExhibitedAssetsData data = 2;
|
||
}
|
||
|
||
// 展出作品数据
|
||
message ExhibitedAssetsData {
|
||
repeated ExhibitedAssetItem items = 1; // 作品列表
|
||
int32 page = 2; // 当前页码
|
||
int32 page_size = 3; // 每页数量
|
||
int64 total = 4; // 总数量
|
||
bool has_more = 5; // 是否有更多
|
||
}
|
||
|
||
// 展出作品项
|
||
message ExhibitedAssetItem {
|
||
int64 asset_id = 1; // 资产ID
|
||
string name = 2; // 藏品名称
|
||
string cover_url = 3; // 封面图URL
|
||
int32 like_count = 4; // 实时点赞数
|
||
int64 exhibited_at = 5; // 展出开始时间(毫秒时间戳)
|
||
int64 expire_at = 6; // 展出过期时间(毫秒时间戳)
|
||
int64 earnings = 7; // 当前可领取收益
|
||
}
|
||
|
||
// ==================== 灵感瀑布相关消息 ====================
|
||
|
||
// 获取灵感瀑布藏品列表请求
|
||
message GetInspirationFlowRequest {
|
||
string cursor = 1; // 游标(首次请求为空)
|
||
string direction = 2; // 滚动方向:right(加载新数据)/ left(加载历史)
|
||
int32 limit = 3; // 每页数量(默认10,最大20)
|
||
string type = 4; // 过滤类型:badge/poster/original/all(默认all)
|
||
string session_id = 5; // 会话ID(首次请求时为空,后端返回新的session_id)
|
||
}
|
||
|
||
// 获取灵感瀑布藏品列表响应
|
||
message GetInspirationFlowResponse {
|
||
topfans.common.BaseResponse base = 1;
|
||
InspirationFlowData data = 2;
|
||
}
|
||
|
||
// 灵感瀑布数据
|
||
message InspirationFlowData {
|
||
repeated InspirationFlowItem items = 1; // 藏品列表
|
||
string cursor = 2; // 下次请求的游标
|
||
bool has_more = 3; // 是否有更多
|
||
string session_id = 4; // 会话ID(首次请求时返回)
|
||
}
|
||
|
||
// 灵感瀑布藏品项
|
||
message InspirationFlowItem {
|
||
int64 asset_id = 1; // 资产ID
|
||
string name = 2; // 藏品名称
|
||
string cover_url = 3; // 封面图URL
|
||
int32 like_count = 4; // 点赞数
|
||
string owner_nickname = 5; // 展出者昵称
|
||
}
|