533 lines
21 KiB
Go
533 lines
21 KiB
Go
package activityapi
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
activityv1 "hyapp.local/api/proto/activity/v1"
|
|
walletv1 "hyapp.local/api/proto/wallet/v1"
|
|
"hyapp/pkg/appcode"
|
|
"hyapp/services/gateway-service/internal/auth"
|
|
"hyapp/services/gateway-service/internal/transport/http/httpkit"
|
|
)
|
|
|
|
type achievementData struct {
|
|
Definition achievementDefinitionData `json:"definition"`
|
|
CycleKey string `json:"cycle_key"`
|
|
ProgressValue int64 `json:"progress_value"`
|
|
TargetValue int64 `json:"target_value"`
|
|
UserStatus string `json:"user_status"`
|
|
UnlockedAtMS int64 `json:"unlocked_at_ms"`
|
|
RewardStatus string `json:"reward_status"`
|
|
}
|
|
|
|
type achievementDefinitionData struct {
|
|
AchievementID string `json:"achievement_id"`
|
|
CollectionID string `json:"collection_id"`
|
|
CollectionType string `json:"collection_type"`
|
|
AchievementType string `json:"achievement_type"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
Status string `json:"status"`
|
|
Version int64 `json:"version"`
|
|
PrimaryBadgeResourceID int64 `json:"primary_badge_resource_id"`
|
|
PrimaryBadgeResource *achievementResourceData `json:"primary_badge_resource,omitempty"`
|
|
RewardResourceGroupID int64 `json:"reward_resource_group_id"`
|
|
RewardResourceGroup *achievementResourceGroupData `json:"reward_resource_group,omitempty"`
|
|
AutoPinPolicy string `json:"auto_pin_policy"`
|
|
HonorVisibility bool `json:"honor_visibility"`
|
|
EffectiveFromMS int64 `json:"effective_from_ms"`
|
|
EffectiveToMS int64 `json:"effective_to_ms"`
|
|
SortOrder int32 `json:"sort_order"`
|
|
DisplayConfigJSON string `json:"display_config_json"`
|
|
CreatedByAdminID int64 `json:"created_by_admin_id"`
|
|
UpdatedByAdminID int64 `json:"updated_by_admin_id"`
|
|
CreatedAtMS int64 `json:"created_at_ms"`
|
|
UpdatedAtMS int64 `json:"updated_at_ms"`
|
|
Conditions []achievementConditionData `json:"conditions"`
|
|
}
|
|
|
|
type achievementConditionData struct {
|
|
ConditionID string `json:"condition_id"`
|
|
AchievementID string `json:"achievement_id"`
|
|
Version int64 `json:"version"`
|
|
MetricType string `json:"metric_type"`
|
|
TargetValue int64 `json:"target_value"`
|
|
TargetUnit string `json:"target_unit"`
|
|
DimensionFilterJSON string `json:"dimension_filter_json"`
|
|
}
|
|
|
|
type achievementResourceData struct {
|
|
ResourceID int64 `json:"resource_id"`
|
|
ResourceCode string `json:"resource_code"`
|
|
ResourceType string `json:"resource_type"`
|
|
Name string `json:"name"`
|
|
Status string `json:"status"`
|
|
Grantable bool `json:"grantable"`
|
|
GrantStrategy string `json:"grant_strategy"`
|
|
WalletAssetType string `json:"wallet_asset_type,omitempty"`
|
|
WalletAssetAmount int64 `json:"wallet_asset_amount,omitempty"`
|
|
UsageScopes []string `json:"usage_scopes"`
|
|
AssetURL string `json:"asset_url"`
|
|
PreviewURL string `json:"preview_url"`
|
|
AnimationURL string `json:"animation_url"`
|
|
MetadataJSON string `json:"metadata_json"`
|
|
SortOrder int32 `json:"sort_order"`
|
|
CreatedAtMS int64 `json:"created_at_ms"`
|
|
UpdatedAtMS int64 `json:"updated_at_ms"`
|
|
}
|
|
|
|
type achievementResourceGroupItemData struct {
|
|
GroupItemID int64 `json:"group_item_id"`
|
|
ItemType string `json:"item_type"`
|
|
ResourceID int64 `json:"resource_id"`
|
|
Resource *achievementResourceData `json:"resource,omitempty"`
|
|
WalletAssetType string `json:"wallet_asset_type,omitempty"`
|
|
WalletAssetAmount int64 `json:"wallet_asset_amount,omitempty"`
|
|
Quantity int64 `json:"quantity"`
|
|
DurationMS int64 `json:"duration_ms"`
|
|
SortOrder int32 `json:"sort_order"`
|
|
}
|
|
|
|
type achievementResourceGroupData struct {
|
|
GroupID int64 `json:"group_id"`
|
|
GroupCode string `json:"group_code"`
|
|
Name string `json:"name"`
|
|
Status string `json:"status"`
|
|
Description string `json:"description"`
|
|
SortOrder int32 `json:"sort_order"`
|
|
Items []achievementResourceGroupItemData `json:"items"`
|
|
CreatedAtMS int64 `json:"created_at_ms"`
|
|
UpdatedAtMS int64 `json:"updated_at_ms"`
|
|
}
|
|
|
|
type badgeProfileData struct {
|
|
StripBadges []badgeDisplayItemData `json:"strip_badges"`
|
|
ProfileTileBadges []badgeDisplayItemData `json:"profile_tile_badges"`
|
|
HonorBadges []badgeDisplayItemData `json:"honor_badges"`
|
|
ServerTimeMS int64 `json:"server_time_ms"`
|
|
}
|
|
|
|
type badgeDisplayItemData struct {
|
|
Slot string `json:"slot"`
|
|
Position int32 `json:"position"`
|
|
BadgeForm string `json:"badge_form"`
|
|
ResourceID int64 `json:"resource_id"`
|
|
Resource *achievementResourceData `json:"resource,omitempty"`
|
|
EntitlementID string `json:"entitlement_id"`
|
|
SourceType string `json:"source_type"`
|
|
SourceID string `json:"source_id"`
|
|
PinMode string `json:"pin_mode"`
|
|
UpdatedAtMS int64 `json:"updated_at_ms"`
|
|
}
|
|
|
|
type badgeDisplayRequestBody struct {
|
|
Slot string `json:"slot"`
|
|
CommandID string `json:"command_id"`
|
|
Items []badgeDisplayItemData `json:"items"`
|
|
}
|
|
|
|
func (h *Handler) listAchievements(writer http.ResponseWriter, request *http.Request) {
|
|
if h.achievementClient == nil {
|
|
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
|
return
|
|
}
|
|
page, ok := httpkit.PositiveInt32Query(request, "page", 1)
|
|
if !ok {
|
|
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
|
|
return
|
|
}
|
|
pageSize, ok := httpkit.PositiveInt32Query(request, "page_size", 20)
|
|
if !ok {
|
|
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
|
|
return
|
|
}
|
|
userID := auth.UserIDFromContext(request.Context())
|
|
rawUserID := strings.TrimSpace(request.URL.Query().Get("user_id"))
|
|
if rawUserID != "" {
|
|
targetUserID, err := strconv.ParseInt(rawUserID, 10, 64)
|
|
if err != nil || targetUserID <= 0 {
|
|
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
|
|
return
|
|
}
|
|
// 成就 H5 支持分享/外部入口按目标用户查看;显式 user_id 是查询目标,不代表操作者身份。
|
|
userID = targetUserID
|
|
}
|
|
if userID <= 0 {
|
|
httpkit.WriteError(writer, request, http.StatusUnauthorized, httpkit.CodeUnauthorized, "unauthorized")
|
|
return
|
|
}
|
|
resp, err := h.achievementClient.ListAchievements(request.Context(), &activityv1.ListAchievementsRequest{
|
|
Meta: httpkit.ActivityMeta(request),
|
|
UserId: userID,
|
|
CollectionType: strings.TrimSpace(request.URL.Query().Get("collection_type")),
|
|
CollectionId: strings.TrimSpace(request.URL.Query().Get("collection_id")),
|
|
Page: page,
|
|
PageSize: pageSize,
|
|
})
|
|
if err != nil {
|
|
httpkit.WriteRPCError(writer, request, err)
|
|
return
|
|
}
|
|
resources, ok := h.resolveAchievementResources(writer, request, achievementResourceIDs(resp.GetAchievements()))
|
|
if !ok {
|
|
return
|
|
}
|
|
resourceGroups, ok := h.resolveAchievementResourceGroups(writer, request, achievementResourceGroupIDs(resp.GetAchievements()))
|
|
if !ok {
|
|
return
|
|
}
|
|
items := make([]achievementData, 0, len(resp.GetAchievements()))
|
|
for _, item := range resp.GetAchievements() {
|
|
items = append(items, achievementFromProto(item, resources, resourceGroups))
|
|
}
|
|
httpkit.WriteOK(writer, request, map[string]any{
|
|
"achievements": items,
|
|
"total": resp.GetTotal(),
|
|
"page": page,
|
|
"page_size": pageSize,
|
|
"server_time_ms": resp.GetServerTimeMs(),
|
|
})
|
|
}
|
|
|
|
func (h *Handler) listMyBadges(writer http.ResponseWriter, request *http.Request) {
|
|
if h.achievementClient == nil {
|
|
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
|
return
|
|
}
|
|
resp, err := h.achievementClient.ListMyBadges(request.Context(), &activityv1.ListMyBadgesRequest{
|
|
Meta: httpkit.ActivityMeta(request),
|
|
UserId: auth.UserIDFromContext(request.Context()),
|
|
})
|
|
if err != nil {
|
|
httpkit.WriteRPCError(writer, request, err)
|
|
return
|
|
}
|
|
resources, ok := h.resolveAchievementResources(writer, request, badgeProfileResourceIDs(resp))
|
|
if !ok {
|
|
return
|
|
}
|
|
httpkit.WriteOK(writer, request, badgeProfileFromProto(resp, resources))
|
|
}
|
|
|
|
func (h *Handler) setBadgeDisplay(writer http.ResponseWriter, request *http.Request) {
|
|
if h.achievementClient == nil {
|
|
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
|
return
|
|
}
|
|
var body badgeDisplayRequestBody
|
|
if !httpkit.Decode(writer, request, &body) {
|
|
return
|
|
}
|
|
slot := strings.TrimSpace(body.Slot)
|
|
commandID := strings.TrimSpace(body.CommandID)
|
|
if slot == "" || commandID == "" {
|
|
httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument")
|
|
return
|
|
}
|
|
items := make([]*activityv1.BadgeDisplayItem, 0, len(body.Items))
|
|
for _, item := range body.Items {
|
|
items = append(items, badgeDisplayItemToProto(slot, item))
|
|
}
|
|
resp, err := h.achievementClient.SetBadgeDisplay(request.Context(), &activityv1.SetBadgeDisplayRequest{
|
|
Meta: httpkit.ActivityMeta(request),
|
|
UserId: auth.UserIDFromContext(request.Context()),
|
|
Slot: slot,
|
|
Items: items,
|
|
CommandId: commandID,
|
|
})
|
|
if err != nil {
|
|
httpkit.WriteRPCError(writer, request, err)
|
|
return
|
|
}
|
|
resources, ok := h.resolveAchievementResources(writer, request, badgeProfileResourceIDs(resp.GetProfile()))
|
|
if !ok {
|
|
return
|
|
}
|
|
httpkit.WriteOK(writer, request, badgeProfileFromProto(resp.GetProfile(), resources))
|
|
}
|
|
|
|
func achievementFromProto(item *activityv1.UserAchievement, resources map[int64]achievementResourceData, resourceGroups map[int64]achievementResourceGroupData) achievementData {
|
|
return achievementData{
|
|
Definition: achievementDefinitionFromProto(item.GetDefinition(), resources, resourceGroups),
|
|
CycleKey: item.GetCycleKey(),
|
|
ProgressValue: item.GetProgressValue(),
|
|
TargetValue: item.GetTargetValue(),
|
|
UserStatus: item.GetUserStatus(),
|
|
UnlockedAtMS: item.GetUnlockedAtMs(),
|
|
RewardStatus: item.GetRewardStatus(),
|
|
}
|
|
}
|
|
|
|
func achievementDefinitionFromProto(item *activityv1.AchievementDefinition, resources map[int64]achievementResourceData, resourceGroups map[int64]achievementResourceGroupData) achievementDefinitionData {
|
|
conditions := make([]achievementConditionData, 0, len(item.GetConditions()))
|
|
for _, condition := range item.GetConditions() {
|
|
conditions = append(conditions, achievementConditionFromProto(condition))
|
|
}
|
|
data := achievementDefinitionData{
|
|
AchievementID: item.GetAchievementId(),
|
|
CollectionID: item.GetCollectionId(),
|
|
CollectionType: item.GetCollectionType(),
|
|
AchievementType: item.GetAchievementType(),
|
|
Title: item.GetTitle(),
|
|
Description: item.GetDescription(),
|
|
Status: item.GetStatus(),
|
|
Version: item.GetVersion(),
|
|
PrimaryBadgeResourceID: item.GetPrimaryBadgeResourceId(),
|
|
RewardResourceGroupID: item.GetRewardResourceGroupId(),
|
|
AutoPinPolicy: item.GetAutoPinPolicy(),
|
|
HonorVisibility: item.GetHonorVisibility(),
|
|
EffectiveFromMS: item.GetEffectiveFromMs(),
|
|
EffectiveToMS: item.GetEffectiveToMs(),
|
|
SortOrder: item.GetSortOrder(),
|
|
DisplayConfigJSON: item.GetDisplayConfigJson(),
|
|
CreatedByAdminID: item.GetCreatedByAdminId(),
|
|
UpdatedByAdminID: item.GetUpdatedByAdminId(),
|
|
CreatedAtMS: item.GetCreatedAtMs(),
|
|
UpdatedAtMS: item.GetUpdatedAtMs(),
|
|
Conditions: conditions,
|
|
}
|
|
if resource, ok := resources[item.GetPrimaryBadgeResourceId()]; ok {
|
|
data.PrimaryBadgeResource = &resource
|
|
}
|
|
if group, ok := resourceGroups[item.GetRewardResourceGroupId()]; ok {
|
|
data.RewardResourceGroup = &group
|
|
}
|
|
return data
|
|
}
|
|
|
|
func achievementConditionFromProto(item *activityv1.AchievementCondition) achievementConditionData {
|
|
return achievementConditionData{
|
|
ConditionID: item.GetConditionId(),
|
|
AchievementID: item.GetAchievementId(),
|
|
Version: item.GetVersion(),
|
|
MetricType: item.GetMetricType(),
|
|
TargetValue: item.GetTargetValue(),
|
|
TargetUnit: item.GetTargetUnit(),
|
|
DimensionFilterJSON: item.GetDimensionFilterJson(),
|
|
}
|
|
}
|
|
|
|
func badgeProfileFromProto(resp *activityv1.ListMyBadgesResponse, resources map[int64]achievementResourceData) badgeProfileData {
|
|
return badgeProfileData{
|
|
StripBadges: badgeItemsFromProto(resp.GetStripBadges(), resources),
|
|
ProfileTileBadges: badgeItemsFromProto(resp.GetProfileTileBadges(), resources),
|
|
HonorBadges: badgeItemsFromProto(resp.GetHonorBadges(), resources),
|
|
ServerTimeMS: resp.GetServerTimeMs(),
|
|
}
|
|
}
|
|
|
|
func badgeItemsFromProto(items []*activityv1.BadgeDisplayItem, resources map[int64]achievementResourceData) []badgeDisplayItemData {
|
|
result := make([]badgeDisplayItemData, 0, len(items))
|
|
for _, item := range items {
|
|
result = append(result, badgeDisplayItemFromProto(item, resources))
|
|
}
|
|
return result
|
|
}
|
|
|
|
func badgeDisplayItemFromProto(item *activityv1.BadgeDisplayItem, resources map[int64]achievementResourceData) badgeDisplayItemData {
|
|
data := badgeDisplayItemData{
|
|
Slot: item.GetSlot(),
|
|
Position: item.GetPosition(),
|
|
BadgeForm: item.GetBadgeForm(),
|
|
ResourceID: item.GetResourceId(),
|
|
EntitlementID: item.GetEntitlementId(),
|
|
SourceType: item.GetSourceType(),
|
|
SourceID: item.GetSourceId(),
|
|
PinMode: item.GetPinMode(),
|
|
UpdatedAtMS: item.GetUpdatedAtMs(),
|
|
}
|
|
if resource, ok := resources[item.GetResourceId()]; ok {
|
|
data.Resource = &resource
|
|
}
|
|
return data
|
|
}
|
|
|
|
func badgeDisplayItemToProto(slot string, item badgeDisplayItemData) *activityv1.BadgeDisplayItem {
|
|
return &activityv1.BadgeDisplayItem{
|
|
Slot: slot,
|
|
Position: item.Position,
|
|
BadgeForm: item.BadgeForm,
|
|
ResourceId: item.ResourceID,
|
|
EntitlementId: strings.TrimSpace(item.EntitlementID),
|
|
SourceType: strings.TrimSpace(item.SourceType),
|
|
SourceId: strings.TrimSpace(item.SourceID),
|
|
PinMode: item.PinMode,
|
|
UpdatedAtMs: item.UpdatedAtMS,
|
|
}
|
|
}
|
|
|
|
func (h *Handler) resolveAchievementResources(writer http.ResponseWriter, request *http.Request, ids []int64) (map[int64]achievementResourceData, bool) {
|
|
ids = uniquePositiveIDs(ids)
|
|
resources := make(map[int64]achievementResourceData, len(ids))
|
|
if len(ids) == 0 {
|
|
return resources, true
|
|
}
|
|
if h.walletClient == nil {
|
|
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
|
return nil, false
|
|
}
|
|
for _, id := range ids {
|
|
resp, err := h.walletClient.GetResource(request.Context(), &walletv1.GetResourceRequest{
|
|
RequestId: httpkit.RequestIDFromContext(request.Context()),
|
|
AppCode: appcode.FromContext(request.Context()),
|
|
ResourceId: id,
|
|
})
|
|
if err != nil {
|
|
httpkit.WriteRPCError(writer, request, err)
|
|
return nil, false
|
|
}
|
|
resource := achievementResourceFromProto(resp.GetResource())
|
|
if resource.ResourceID > 0 {
|
|
resources[resource.ResourceID] = resource
|
|
}
|
|
}
|
|
return resources, true
|
|
}
|
|
|
|
func (h *Handler) resolveAchievementResourceGroups(writer http.ResponseWriter, request *http.Request, ids []int64) (map[int64]achievementResourceGroupData, bool) {
|
|
ids = uniquePositiveIDs(ids)
|
|
groups := make(map[int64]achievementResourceGroupData, len(ids))
|
|
if len(ids) == 0 {
|
|
return groups, true
|
|
}
|
|
if h.walletClient == nil {
|
|
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
|
return nil, false
|
|
}
|
|
for _, id := range ids {
|
|
resp, err := h.walletClient.GetResourceGroup(request.Context(), &walletv1.GetResourceGroupRequest{
|
|
RequestId: httpkit.RequestIDFromContext(request.Context()),
|
|
AppCode: appcode.FromContext(request.Context()),
|
|
GroupId: id,
|
|
})
|
|
if err != nil {
|
|
httpkit.WriteRPCError(writer, request, err)
|
|
return nil, false
|
|
}
|
|
group := achievementResourceGroupFromProto(resp.GetGroup())
|
|
if group.GroupID > 0 {
|
|
groups[group.GroupID] = group
|
|
}
|
|
}
|
|
return groups, true
|
|
}
|
|
|
|
func achievementResourceIDs(items []*activityv1.UserAchievement) []int64 {
|
|
ids := make([]int64, 0, len(items))
|
|
for _, item := range items {
|
|
if item.GetDefinition().GetPrimaryBadgeResourceId() > 0 {
|
|
ids = append(ids, item.GetDefinition().GetPrimaryBadgeResourceId())
|
|
}
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func achievementResourceGroupIDs(items []*activityv1.UserAchievement) []int64 {
|
|
ids := make([]int64, 0, len(items))
|
|
for _, item := range items {
|
|
if item.GetDefinition().GetRewardResourceGroupId() > 0 {
|
|
ids = append(ids, item.GetDefinition().GetRewardResourceGroupId())
|
|
}
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func badgeProfileResourceIDs(resp *activityv1.ListMyBadgesResponse) []int64 {
|
|
if resp == nil {
|
|
return nil
|
|
}
|
|
ids := make([]int64, 0, len(resp.GetStripBadges())+len(resp.GetProfileTileBadges())+len(resp.GetHonorBadges()))
|
|
for _, item := range resp.GetStripBadges() {
|
|
ids = append(ids, item.GetResourceId())
|
|
}
|
|
for _, item := range resp.GetProfileTileBadges() {
|
|
ids = append(ids, item.GetResourceId())
|
|
}
|
|
for _, item := range resp.GetHonorBadges() {
|
|
ids = append(ids, item.GetResourceId())
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func uniquePositiveIDs(ids []int64) []int64 {
|
|
seen := make(map[int64]struct{}, len(ids))
|
|
result := make([]int64, 0, len(ids))
|
|
for _, id := range ids {
|
|
if id <= 0 {
|
|
continue
|
|
}
|
|
if _, ok := seen[id]; ok {
|
|
continue
|
|
}
|
|
seen[id] = struct{}{}
|
|
result = append(result, id)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func achievementResourceFromProto(item *walletv1.Resource) achievementResourceData {
|
|
if item == nil {
|
|
return achievementResourceData{}
|
|
}
|
|
return achievementResourceData{
|
|
ResourceID: item.GetResourceId(),
|
|
ResourceCode: item.GetResourceCode(),
|
|
ResourceType: item.GetResourceType(),
|
|
Name: item.GetName(),
|
|
Status: item.GetStatus(),
|
|
Grantable: item.GetGrantable(),
|
|
GrantStrategy: item.GetGrantStrategy(),
|
|
WalletAssetType: item.GetWalletAssetType(),
|
|
WalletAssetAmount: item.GetWalletAssetAmount(),
|
|
UsageScopes: item.GetUsageScopes(),
|
|
AssetURL: item.GetAssetUrl(),
|
|
PreviewURL: item.GetPreviewUrl(),
|
|
AnimationURL: item.GetAnimationUrl(),
|
|
MetadataJSON: item.GetMetadataJson(),
|
|
SortOrder: item.GetSortOrder(),
|
|
CreatedAtMS: item.GetCreatedAtMs(),
|
|
UpdatedAtMS: item.GetUpdatedAtMs(),
|
|
}
|
|
}
|
|
|
|
func achievementResourceGroupFromProto(group *walletv1.ResourceGroup) achievementResourceGroupData {
|
|
if group == nil {
|
|
return achievementResourceGroupData{}
|
|
}
|
|
items := make([]achievementResourceGroupItemData, 0, len(group.GetItems()))
|
|
for _, item := range group.GetItems() {
|
|
items = append(items, achievementResourceGroupItemData{
|
|
GroupItemID: item.GetGroupItemId(),
|
|
ItemType: item.GetItemType(),
|
|
ResourceID: item.GetResourceId(),
|
|
Resource: achievementResourcePointerFromProto(item.GetResource()),
|
|
WalletAssetType: item.GetWalletAssetType(),
|
|
WalletAssetAmount: item.GetWalletAssetAmount(),
|
|
Quantity: item.GetQuantity(),
|
|
DurationMS: item.GetDurationMs(),
|
|
SortOrder: item.GetSortOrder(),
|
|
})
|
|
}
|
|
return achievementResourceGroupData{
|
|
GroupID: group.GetGroupId(),
|
|
GroupCode: group.GetGroupCode(),
|
|
Name: group.GetName(),
|
|
Status: group.GetStatus(),
|
|
Description: group.GetDescription(),
|
|
SortOrder: group.GetSortOrder(),
|
|
Items: items,
|
|
CreatedAtMS: group.GetCreatedAtMs(),
|
|
UpdatedAtMS: group.GetUpdatedAtMs(),
|
|
}
|
|
}
|
|
|
|
func achievementResourcePointerFromProto(item *walletv1.Resource) *achievementResourceData {
|
|
resource := achievementResourceFromProto(item)
|
|
if resource.ResourceID == 0 {
|
|
return nil
|
|
}
|
|
return &resource
|
|
}
|