推进活动系统最小成品闭环与游客体验
This commit is contained in:
@@ -44,6 +44,7 @@ type CreateAdminPlaceInput struct {
|
||||
type AdminMapAssetSummary struct {
|
||||
ID string `json:"id"`
|
||||
PlaceID string `json:"placeId"`
|
||||
PlaceName *string `json:"placeName,omitempty"`
|
||||
LegacyMapID *string `json:"legacyMapId,omitempty"`
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
@@ -61,9 +62,10 @@ type AdminTileReleaseBrief struct {
|
||||
}
|
||||
|
||||
type AdminMapAssetDetail struct {
|
||||
MapAsset AdminMapAssetSummary `json:"mapAsset"`
|
||||
TileReleases []AdminTileReleaseView `json:"tileReleases"`
|
||||
CourseSets []AdminCourseSetBrief `json:"courseSets"`
|
||||
MapAsset AdminMapAssetSummary `json:"mapAsset"`
|
||||
TileReleases []AdminTileReleaseView `json:"tileReleases"`
|
||||
CourseSets []AdminCourseSetBrief `json:"courseSets"`
|
||||
LinkedEvents []AdminMapLinkedEventBrief `json:"linkedEvents"`
|
||||
}
|
||||
|
||||
type CreateAdminMapAssetInput struct {
|
||||
@@ -76,6 +78,31 @@ type CreateAdminMapAssetInput struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type UpdateAdminMapAssetInput struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
MapType string `json:"mapType"`
|
||||
CoverURL *string `json:"coverUrl,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type AdminMapLinkedEventBrief struct {
|
||||
EventID string `json:"eventId"`
|
||||
Title string `json:"title"`
|
||||
Summary *string `json:"summary,omitempty"`
|
||||
Status string `json:"status"`
|
||||
IsDefaultExperience bool `json:"isDefaultExperience"`
|
||||
ShowInEventList bool `json:"showInEventList"`
|
||||
CurrentReleaseID *string `json:"currentReleaseId,omitempty"`
|
||||
ConfigLabel *string `json:"configLabel,omitempty"`
|
||||
RouteCode *string `json:"routeCode,omitempty"`
|
||||
CurrentPresentationID *string `json:"currentPresentationId,omitempty"`
|
||||
CurrentPresentation *string `json:"currentPresentation,omitempty"`
|
||||
CurrentContentBundleID *string `json:"currentContentBundleId,omitempty"`
|
||||
CurrentContentBundle *string `json:"currentContentBundle,omitempty"`
|
||||
}
|
||||
|
||||
type AdminTileReleaseView struct {
|
||||
ID string `json:"id"`
|
||||
LegacyVersionID *string `json:"legacyVersionId,omitempty"`
|
||||
@@ -202,6 +229,66 @@ type CreateAdminRuntimeBindingInput struct {
|
||||
Notes *string `json:"notes,omitempty"`
|
||||
}
|
||||
|
||||
type ImportAdminTileReleaseInput struct {
|
||||
PlaceCode string `json:"placeCode"`
|
||||
PlaceName string `json:"placeName"`
|
||||
PlaceRegion *string `json:"placeRegion,omitempty"`
|
||||
PlaceCoverURL *string `json:"placeCoverUrl,omitempty"`
|
||||
PlaceDescription *string `json:"placeDescription,omitempty"`
|
||||
PlaceCenterPoint map[string]any `json:"placeCenterPoint,omitempty"`
|
||||
MapAssetCode string `json:"mapAssetCode"`
|
||||
MapAssetName string `json:"mapAssetName"`
|
||||
MapType string `json:"mapType"`
|
||||
MapCoverURL *string `json:"mapCoverUrl,omitempty"`
|
||||
MapDescription *string `json:"mapDescription,omitempty"`
|
||||
VersionCode string `json:"versionCode"`
|
||||
Status string `json:"status"`
|
||||
TileBaseURL string `json:"tileBaseUrl"`
|
||||
MetaURL string `json:"metaUrl"`
|
||||
PublishedAssetRoot *string `json:"publishedAssetRoot,omitempty"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
SetAsCurrent bool `json:"setAsCurrent"`
|
||||
}
|
||||
|
||||
type ImportAdminTileReleaseResult struct {
|
||||
Place AdminPlaceSummary `json:"place"`
|
||||
MapAsset AdminMapAssetSummary `json:"mapAsset"`
|
||||
TileRelease AdminTileReleaseView `json:"tileRelease"`
|
||||
}
|
||||
|
||||
type ImportAdminCourseRouteInput struct {
|
||||
Name string `json:"name"`
|
||||
RouteCode string `json:"routeCode"`
|
||||
FileURL string `json:"fileUrl"`
|
||||
SourceType string `json:"sourceType"`
|
||||
ControlCount *int `json:"controlCount,omitempty"`
|
||||
Difficulty *string `json:"difficulty,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type ImportAdminCourseSetBatchInput struct {
|
||||
PlaceCode string `json:"placeCode"`
|
||||
PlaceName string `json:"placeName"`
|
||||
MapAssetCode string `json:"mapAssetCode"`
|
||||
MapAssetName string `json:"mapAssetName"`
|
||||
MapType string `json:"mapType"`
|
||||
CourseSetCode string `json:"courseSetCode"`
|
||||
CourseSetName string `json:"courseSetName"`
|
||||
Mode string `json:"mode"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Status string `json:"status"`
|
||||
DefaultRouteCode *string `json:"defaultRouteCode,omitempty"`
|
||||
Routes []ImportAdminCourseRouteInput `json:"routes"`
|
||||
}
|
||||
|
||||
type ImportAdminCourseSetBatchResult struct {
|
||||
Place AdminPlaceSummary `json:"place"`
|
||||
MapAsset AdminMapAssetSummary `json:"mapAsset"`
|
||||
CourseSet AdminCourseSetBrief `json:"courseSet"`
|
||||
Variants []AdminCourseVariantView `json:"variants"`
|
||||
}
|
||||
|
||||
func NewAdminProductionService(store *postgres.Store) *AdminProductionService {
|
||||
return &AdminProductionService{store: store}
|
||||
}
|
||||
@@ -218,6 +305,22 @@ func (s *AdminProductionService) ListPlaces(ctx context.Context, limit int) ([]A
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) ListMapAssets(ctx context.Context, limit int) ([]AdminMapAssetSummary, error) {
|
||||
items, err := s.store.ListMapAssets(ctx, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]AdminMapAssetSummary, 0, len(items))
|
||||
for _, item := range items {
|
||||
summary, err := s.buildAdminMapAssetSummary(ctx, item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, summary)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) CreatePlace(ctx context.Context, input CreateAdminPlaceInput) (*AdminPlaceSummary, error) {
|
||||
input.Code = strings.TrimSpace(input.Code)
|
||||
input.Name = strings.TrimSpace(input.Name)
|
||||
@@ -362,10 +465,15 @@ func (s *AdminProductionService) GetMapAssetDetail(ctx context.Context, mapAsset
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
linkedEvents, err := s.store.ListMapAssetLinkedEvents(ctx, item.ID, 100)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := &AdminMapAssetDetail{
|
||||
MapAsset: summary,
|
||||
TileReleases: make([]AdminTileReleaseView, 0, len(tileReleases)),
|
||||
CourseSets: make([]AdminCourseSetBrief, 0, len(courseSets)),
|
||||
LinkedEvents: make([]AdminMapLinkedEventBrief, 0, len(linkedEvents)),
|
||||
}
|
||||
for _, release := range tileReleases {
|
||||
result.TileReleases = append(result.TileReleases, buildAdminTileReleaseView(release))
|
||||
@@ -377,9 +485,64 @@ func (s *AdminProductionService) GetMapAssetDetail(ctx context.Context, mapAsset
|
||||
}
|
||||
result.CourseSets = append(result.CourseSets, brief)
|
||||
}
|
||||
for _, linked := range linkedEvents {
|
||||
result.LinkedEvents = append(result.LinkedEvents, buildAdminMapLinkedEventBrief(linked))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) UpdateMapAsset(ctx context.Context, mapAssetPublicID string, input UpdateAdminMapAssetInput) (*AdminMapAssetSummary, error) {
|
||||
item, err := s.store.GetMapAssetByPublicID(ctx, strings.TrimSpace(mapAssetPublicID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if item == nil {
|
||||
return nil, apperr.New(http.StatusNotFound, "map_asset_not_found", "map asset not found")
|
||||
}
|
||||
input.Code = strings.TrimSpace(input.Code)
|
||||
input.Name = strings.TrimSpace(input.Name)
|
||||
input.MapType = strings.TrimSpace(input.MapType)
|
||||
if input.Code == "" || input.Name == "" {
|
||||
return nil, apperr.New(http.StatusBadRequest, "invalid_params", "code and name are required")
|
||||
}
|
||||
if input.MapType == "" {
|
||||
input.MapType = "standard"
|
||||
}
|
||||
|
||||
tx, err := s.store.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
updated, err := s.store.UpdateMapAsset(ctx, tx, postgres.UpdateMapAssetParams{
|
||||
MapAssetID: item.ID,
|
||||
Code: input.Code,
|
||||
Name: input.Name,
|
||||
MapType: input.MapType,
|
||||
CoverURL: trimStringPtr(input.CoverURL),
|
||||
Description: trimStringPtr(input.Description),
|
||||
Status: normalizeCatalogStatus(input.Status),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refreshed, err := s.store.GetMapAssetByPublicID(ctx, updated.PublicID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if refreshed == nil {
|
||||
return nil, apperr.New(http.StatusNotFound, "map_asset_not_found", "map asset not found")
|
||||
}
|
||||
result, err := s.buildAdminMapAssetSummary(ctx, *refreshed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) CreateTileRelease(ctx context.Context, mapAssetPublicID string, input CreateAdminTileReleaseInput) (*AdminTileReleaseView, error) {
|
||||
mapAsset, err := s.store.GetMapAssetByPublicID(ctx, strings.TrimSpace(mapAssetPublicID))
|
||||
if err != nil {
|
||||
@@ -748,6 +911,293 @@ func (s *AdminProductionService) CreateRuntimeBinding(ctx context.Context, input
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) ImportTileRelease(ctx context.Context, input ImportAdminTileReleaseInput) (*ImportAdminTileReleaseResult, error) {
|
||||
input.PlaceCode = strings.TrimSpace(input.PlaceCode)
|
||||
input.PlaceName = strings.TrimSpace(input.PlaceName)
|
||||
input.MapAssetCode = strings.TrimSpace(input.MapAssetCode)
|
||||
input.MapAssetName = strings.TrimSpace(input.MapAssetName)
|
||||
input.VersionCode = strings.TrimSpace(input.VersionCode)
|
||||
input.TileBaseURL = strings.TrimSpace(input.TileBaseURL)
|
||||
input.MetaURL = strings.TrimSpace(input.MetaURL)
|
||||
if input.PlaceCode == "" || input.PlaceName == "" || input.MapAssetCode == "" || input.MapAssetName == "" || input.VersionCode == "" || input.TileBaseURL == "" || input.MetaURL == "" {
|
||||
return nil, apperr.New(http.StatusBadRequest, "invalid_params", "placeCode, placeName, mapAssetCode, mapAssetName, versionCode, tileBaseUrl and metaUrl are required")
|
||||
}
|
||||
|
||||
place, err := s.store.GetPlaceByCode(ctx, input.PlaceCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if place == nil {
|
||||
created, err := s.CreatePlace(ctx, CreateAdminPlaceInput{
|
||||
Code: input.PlaceCode,
|
||||
Name: input.PlaceName,
|
||||
Region: trimStringPtr(input.PlaceRegion),
|
||||
CoverURL: trimStringPtr(input.PlaceCoverURL),
|
||||
Description: trimStringPtr(input.PlaceDescription),
|
||||
CenterPoint: input.PlaceCenterPoint,
|
||||
Status: normalizeCatalogStatus(input.Status),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
place, err = s.store.GetPlaceByPublicID(ctx, created.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if place == nil {
|
||||
return nil, apperr.New(http.StatusNotFound, "place_not_found", "place not found")
|
||||
}
|
||||
|
||||
mapAsset, err := s.store.GetMapAssetByCode(ctx, input.MapAssetCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mapAsset == nil {
|
||||
created, err := s.CreateMapAsset(ctx, place.PublicID, CreateAdminMapAssetInput{
|
||||
Code: input.MapAssetCode,
|
||||
Name: input.MapAssetName,
|
||||
MapType: strings.TrimSpace(input.MapType),
|
||||
CoverURL: trimStringPtr(input.MapCoverURL),
|
||||
Description: trimStringPtr(input.MapDescription),
|
||||
Status: normalizeCatalogStatus(input.Status),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapAsset, err = s.store.GetMapAssetByPublicID(ctx, created.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if mapAsset == nil || mapAsset.PlaceID != place.ID {
|
||||
return nil, apperr.New(http.StatusBadRequest, "map_asset_mismatch", "map asset does not belong to place")
|
||||
}
|
||||
|
||||
release, err := s.store.GetTileReleaseByMapAssetIDAndVersionCode(ctx, mapAsset.ID, input.VersionCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if release == nil {
|
||||
created, err := s.CreateTileRelease(ctx, mapAsset.PublicID, CreateAdminTileReleaseInput{
|
||||
VersionCode: input.VersionCode,
|
||||
Status: normalizeReleaseStatus(input.Status),
|
||||
TileBaseURL: input.TileBaseURL,
|
||||
MetaURL: input.MetaURL,
|
||||
PublishedAssetRoot: trimStringPtr(input.PublishedAssetRoot),
|
||||
Metadata: input.Metadata,
|
||||
SetAsCurrent: input.SetAsCurrent,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
release, err = s.store.GetTileReleaseByPublicID(ctx, created.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if input.SetAsCurrent {
|
||||
tx, err := s.store.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
if err := s.store.SetMapAssetCurrentTileRelease(ctx, tx, mapAsset.ID, release.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapAsset, err = s.store.GetMapAssetByPublicID(ctx, mapAsset.PublicID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if release == nil {
|
||||
return nil, apperr.New(http.StatusNotFound, "tile_release_not_found", "tile release not found")
|
||||
}
|
||||
|
||||
placeSummary := buildAdminPlaceSummary(*place)
|
||||
mapSummary, err := s.buildAdminMapAssetSummary(ctx, *mapAsset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ImportAdminTileReleaseResult{
|
||||
Place: placeSummary,
|
||||
MapAsset: mapSummary,
|
||||
TileRelease: buildAdminTileReleaseView(*release),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) ImportCourseSetKMLBatch(ctx context.Context, input ImportAdminCourseSetBatchInput) (*ImportAdminCourseSetBatchResult, error) {
|
||||
input.PlaceCode = strings.TrimSpace(input.PlaceCode)
|
||||
input.PlaceName = strings.TrimSpace(input.PlaceName)
|
||||
input.MapAssetCode = strings.TrimSpace(input.MapAssetCode)
|
||||
input.MapAssetName = strings.TrimSpace(input.MapAssetName)
|
||||
input.CourseSetCode = strings.TrimSpace(input.CourseSetCode)
|
||||
input.CourseSetName = strings.TrimSpace(input.CourseSetName)
|
||||
input.Mode = strings.TrimSpace(input.Mode)
|
||||
if input.PlaceCode == "" || input.PlaceName == "" || input.MapAssetCode == "" || input.MapAssetName == "" || input.CourseSetCode == "" || input.CourseSetName == "" || input.Mode == "" || len(input.Routes) == 0 {
|
||||
return nil, apperr.New(http.StatusBadRequest, "invalid_params", "placeCode, placeName, mapAssetCode, mapAssetName, courseSetCode, courseSetName, mode and routes are required")
|
||||
}
|
||||
|
||||
place, err := s.store.GetPlaceByCode(ctx, input.PlaceCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if place == nil {
|
||||
created, err := s.CreatePlace(ctx, CreateAdminPlaceInput{
|
||||
Code: input.PlaceCode,
|
||||
Name: input.PlaceName,
|
||||
Status: normalizeCatalogStatus(input.Status),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
place, err = s.store.GetPlaceByPublicID(ctx, created.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
mapAsset, err := s.store.GetMapAssetByCode(ctx, input.MapAssetCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mapAsset == nil {
|
||||
created, err := s.CreateMapAsset(ctx, place.PublicID, CreateAdminMapAssetInput{
|
||||
Code: input.MapAssetCode,
|
||||
Name: input.MapAssetName,
|
||||
MapType: strings.TrimSpace(input.MapType),
|
||||
Status: normalizeCatalogStatus(input.Status),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapAsset, err = s.store.GetMapAssetByPublicID(ctx, created.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if mapAsset == nil || mapAsset.PlaceID != place.ID {
|
||||
return nil, apperr.New(http.StatusBadRequest, "map_asset_mismatch", "map asset does not belong to place")
|
||||
}
|
||||
|
||||
courseSet, err := s.store.GetCourseSetByCode(ctx, input.CourseSetCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if courseSet == nil {
|
||||
created, err := s.CreateCourseSet(ctx, mapAsset.PublicID, CreateAdminCourseSetInput{
|
||||
Code: input.CourseSetCode,
|
||||
Mode: input.Mode,
|
||||
Name: input.CourseSetName,
|
||||
Description: trimStringPtr(input.Description),
|
||||
Status: normalizeCatalogStatus(input.Status),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
courseSet, err = s.store.GetCourseSetByPublicID(ctx, created.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if courseSet == nil || courseSet.PlaceID != place.ID || courseSet.MapAssetID != mapAsset.ID {
|
||||
return nil, apperr.New(http.StatusBadRequest, "course_set_mismatch", "course set does not match place/map asset")
|
||||
}
|
||||
|
||||
defaultRouteCode := ""
|
||||
if input.DefaultRouteCode != nil {
|
||||
defaultRouteCode = strings.TrimSpace(*input.DefaultRouteCode)
|
||||
}
|
||||
|
||||
for _, route := range input.Routes {
|
||||
route.Name = strings.TrimSpace(route.Name)
|
||||
route.RouteCode = strings.TrimSpace(route.RouteCode)
|
||||
route.FileURL = strings.TrimSpace(route.FileURL)
|
||||
sourceType := strings.TrimSpace(route.SourceType)
|
||||
if sourceType == "" {
|
||||
sourceType = "kml"
|
||||
}
|
||||
if route.Name == "" || route.RouteCode == "" || route.FileURL == "" {
|
||||
return nil, apperr.New(http.StatusBadRequest, "invalid_params", "route name, routeCode and fileUrl are required")
|
||||
}
|
||||
|
||||
existing, err := s.store.GetCourseVariantByCourseSetIDAndRouteCode(ctx, courseSet.ID, route.RouteCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existing != nil {
|
||||
if defaultRouteCode != "" && route.RouteCode == defaultRouteCode {
|
||||
tx, err := s.store.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
if err := s.store.SetCourseSetCurrentVariant(ctx, tx, courseSet.ID, existing.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
source, err := s.CreateCourseSource(ctx, CreateAdminCourseSourceInput{
|
||||
SourceType: sourceType,
|
||||
FileURL: route.FileURL,
|
||||
ImportStatus: "imported",
|
||||
Metadata: route.Metadata,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
isDefault := defaultRouteCode != "" && route.RouteCode == defaultRouteCode
|
||||
_, err = s.CreateCourseVariant(ctx, courseSet.PublicID, CreateAdminCourseVariantInput{
|
||||
SourceID: &source.ID,
|
||||
Name: route.Name,
|
||||
RouteCode: &route.RouteCode,
|
||||
Mode: input.Mode,
|
||||
ControlCount: route.ControlCount,
|
||||
Difficulty: trimStringPtr(route.Difficulty),
|
||||
Status: normalizeCatalogStatus(route.Status),
|
||||
IsDefault: isDefault,
|
||||
Metadata: route.Metadata,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
courseSet, err = s.store.GetCourseSetByPublicID(ctx, courseSet.PublicID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
variants, err := s.store.ListCourseVariantsByCourseSetID(ctx, courseSet.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
views := make([]AdminCourseVariantView, 0, len(variants))
|
||||
for _, variant := range variants {
|
||||
views = append(views, buildAdminCourseVariantView(variant))
|
||||
}
|
||||
placeSummary := buildAdminPlaceSummary(*place)
|
||||
mapSummary, err := s.buildAdminMapAssetSummary(ctx, *mapAsset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
courseBrief, err := s.buildAdminCourseSetBrief(ctx, *courseSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ImportAdminCourseSetBatchResult{
|
||||
Place: placeSummary,
|
||||
MapAsset: mapSummary,
|
||||
CourseSet: courseBrief,
|
||||
Variants: views,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) GetRuntimeBinding(ctx context.Context, runtimeBindingPublicID string) (*AdminRuntimeBindingSummary, error) {
|
||||
item, err := s.store.GetMapRuntimeBindingByPublicID(ctx, strings.TrimSpace(runtimeBindingPublicID))
|
||||
if err != nil {
|
||||
@@ -764,6 +1214,7 @@ func (s *AdminProductionService) buildAdminMapAssetSummary(ctx context.Context,
|
||||
result := AdminMapAssetSummary{
|
||||
ID: item.PublicID,
|
||||
PlaceID: item.PlaceID,
|
||||
PlaceName: item.PlaceName,
|
||||
LegacyMapID: item.LegacyMapPublicID,
|
||||
Code: item.Code,
|
||||
Name: item.Name,
|
||||
@@ -791,6 +1242,24 @@ func (s *AdminProductionService) buildAdminMapAssetSummary(ctx context.Context,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func buildAdminMapLinkedEventBrief(item postgres.MapAssetLinkedEvent) AdminMapLinkedEventBrief {
|
||||
return AdminMapLinkedEventBrief{
|
||||
EventID: item.EventPublicID,
|
||||
Title: item.DisplayName,
|
||||
Summary: item.Summary,
|
||||
Status: item.Status,
|
||||
IsDefaultExperience: item.IsDefaultExperience,
|
||||
ShowInEventList: item.ShowInEventList,
|
||||
CurrentReleaseID: item.CurrentReleasePublicID,
|
||||
ConfigLabel: item.ConfigLabel,
|
||||
RouteCode: item.RouteCode,
|
||||
CurrentPresentationID: item.CurrentPresentationID,
|
||||
CurrentPresentation: item.CurrentPresentationName,
|
||||
CurrentContentBundleID: item.CurrentContentBundleID,
|
||||
CurrentContentBundle: item.CurrentContentBundleName,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AdminProductionService) buildAdminCourseSetBrief(ctx context.Context, item postgres.CourseSet) (AdminCourseSetBrief, error) {
|
||||
result := AdminCourseSetBrief{
|
||||
ID: item.PublicID,
|
||||
|
||||
Reference in New Issue
Block a user