推进活动系统最小成品闭环与游客体验
This commit is contained in:
216
backend/internal/store/postgres/map_experience_store.go
Normal file
216
backend/internal/store/postgres/map_experience_store.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type MapExperienceRow struct {
|
||||
PlacePublicID string
|
||||
PlaceName string
|
||||
MapAssetPublicID string
|
||||
MapAssetName string
|
||||
MapCoverURL *string
|
||||
MapSummary *string
|
||||
TileBaseURL *string
|
||||
TileMetaURL *string
|
||||
EventPublicID *string
|
||||
EventDisplayName *string
|
||||
EventSummary *string
|
||||
EventStatus *string
|
||||
EventIsDefaultExperience bool
|
||||
EventShowInEventList bool
|
||||
EventReleasePayloadJSON *string
|
||||
EventPresentationID *string
|
||||
EventPresentationName *string
|
||||
EventPresentationType *string
|
||||
EventPresentationSchema *string
|
||||
EventContentBundleID *string
|
||||
EventContentBundleName *string
|
||||
EventContentEntryURL *string
|
||||
EventContentAssetRootURL *string
|
||||
EventContentMetadataJSON *string
|
||||
}
|
||||
|
||||
func (s *Store) ListMapExperienceRows(ctx context.Context, limit int) ([]MapExperienceRow, error) {
|
||||
if limit <= 0 || limit > 200 {
|
||||
limit = 50
|
||||
}
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT
|
||||
p.place_public_id,
|
||||
p.name,
|
||||
ma.map_asset_public_id,
|
||||
ma.name,
|
||||
COALESCE(ma.cover_url, p.cover_url) AS cover_url,
|
||||
COALESCE(ma.description, p.description) AS summary,
|
||||
tr.tile_base_url,
|
||||
tr.meta_url,
|
||||
e.event_public_id,
|
||||
e.display_name,
|
||||
e.summary,
|
||||
e.status,
|
||||
COALESCE(e.is_default_experience, false),
|
||||
COALESCE(e.show_in_event_list, true),
|
||||
er.payload_jsonb::text,
|
||||
ep.presentation_public_id,
|
||||
ep.name,
|
||||
ep.presentation_type,
|
||||
ep.schema_jsonb::text,
|
||||
cb.content_bundle_public_id,
|
||||
cb.name,
|
||||
cb.entry_url,
|
||||
cb.asset_root_url,
|
||||
cb.metadata_jsonb::text
|
||||
FROM map_assets ma
|
||||
JOIN places p ON p.id = ma.place_id
|
||||
LEFT JOIN tile_releases tr ON tr.id = ma.current_tile_release_id
|
||||
LEFT JOIN map_runtime_bindings mrb
|
||||
ON mrb.map_asset_id = ma.id
|
||||
AND mrb.status = 'active'
|
||||
LEFT JOIN event_releases er
|
||||
ON er.runtime_binding_id = mrb.id
|
||||
AND er.status = 'published'
|
||||
LEFT JOIN events e
|
||||
ON e.current_release_id = er.id
|
||||
AND e.status = 'active'
|
||||
LEFT JOIN event_presentations ep ON ep.id = er.presentation_id
|
||||
LEFT JOIN content_bundles cb ON cb.id = er.content_bundle_id
|
||||
WHERE ma.status = 'active'
|
||||
AND (e.id IS NULL OR e.show_in_event_list = true)
|
||||
ORDER BY p.name ASC, ma.name ASC, COALESCE(e.is_default_experience, false) DESC, e.display_name ASC
|
||||
LIMIT $1
|
||||
`, limit)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list map experience rows: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
items := make([]MapExperienceRow, 0, limit)
|
||||
for rows.Next() {
|
||||
var item MapExperienceRow
|
||||
if err := rows.Scan(
|
||||
&item.PlacePublicID,
|
||||
&item.PlaceName,
|
||||
&item.MapAssetPublicID,
|
||||
&item.MapAssetName,
|
||||
&item.MapCoverURL,
|
||||
&item.MapSummary,
|
||||
&item.TileBaseURL,
|
||||
&item.TileMetaURL,
|
||||
&item.EventPublicID,
|
||||
&item.EventDisplayName,
|
||||
&item.EventSummary,
|
||||
&item.EventStatus,
|
||||
&item.EventIsDefaultExperience,
|
||||
&item.EventShowInEventList,
|
||||
&item.EventReleasePayloadJSON,
|
||||
&item.EventPresentationID,
|
||||
&item.EventPresentationName,
|
||||
&item.EventPresentationType,
|
||||
&item.EventPresentationSchema,
|
||||
&item.EventContentBundleID,
|
||||
&item.EventContentBundleName,
|
||||
&item.EventContentEntryURL,
|
||||
&item.EventContentAssetRootURL,
|
||||
&item.EventContentMetadataJSON,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("scan map experience row: %w", err)
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("iterate map experience rows: %w", err)
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (s *Store) ListMapExperienceRowsByMapPublicID(ctx context.Context, mapAssetPublicID string) ([]MapExperienceRow, error) {
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT
|
||||
p.place_public_id,
|
||||
p.name,
|
||||
ma.map_asset_public_id,
|
||||
ma.name,
|
||||
COALESCE(ma.cover_url, p.cover_url) AS cover_url,
|
||||
COALESCE(ma.description, p.description) AS summary,
|
||||
tr.tile_base_url,
|
||||
tr.meta_url,
|
||||
e.event_public_id,
|
||||
e.display_name,
|
||||
e.summary,
|
||||
e.status,
|
||||
COALESCE(e.is_default_experience, false),
|
||||
COALESCE(e.show_in_event_list, true),
|
||||
er.payload_jsonb::text,
|
||||
ep.presentation_public_id,
|
||||
ep.name,
|
||||
ep.presentation_type,
|
||||
ep.schema_jsonb::text,
|
||||
cb.content_bundle_public_id,
|
||||
cb.name,
|
||||
cb.entry_url,
|
||||
cb.asset_root_url,
|
||||
cb.metadata_jsonb::text
|
||||
FROM map_assets ma
|
||||
JOIN places p ON p.id = ma.place_id
|
||||
LEFT JOIN tile_releases tr ON tr.id = ma.current_tile_release_id
|
||||
LEFT JOIN map_runtime_bindings mrb
|
||||
ON mrb.map_asset_id = ma.id
|
||||
AND mrb.status = 'active'
|
||||
LEFT JOIN event_releases er
|
||||
ON er.runtime_binding_id = mrb.id
|
||||
AND er.status = 'published'
|
||||
LEFT JOIN events e
|
||||
ON e.current_release_id = er.id
|
||||
AND e.status = 'active'
|
||||
LEFT JOIN event_presentations ep ON ep.id = er.presentation_id
|
||||
LEFT JOIN content_bundles cb ON cb.id = er.content_bundle_id
|
||||
WHERE ma.map_asset_public_id = $1
|
||||
AND ma.status = 'active'
|
||||
AND (e.id IS NULL OR e.show_in_event_list = true)
|
||||
ORDER BY COALESCE(e.is_default_experience, false) DESC, e.display_name ASC
|
||||
`, mapAssetPublicID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list map experience rows by map public id: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
items := make([]MapExperienceRow, 0, 8)
|
||||
for rows.Next() {
|
||||
var item MapExperienceRow
|
||||
if err := rows.Scan(
|
||||
&item.PlacePublicID,
|
||||
&item.PlaceName,
|
||||
&item.MapAssetPublicID,
|
||||
&item.MapAssetName,
|
||||
&item.MapCoverURL,
|
||||
&item.MapSummary,
|
||||
&item.TileBaseURL,
|
||||
&item.TileMetaURL,
|
||||
&item.EventPublicID,
|
||||
&item.EventDisplayName,
|
||||
&item.EventSummary,
|
||||
&item.EventStatus,
|
||||
&item.EventIsDefaultExperience,
|
||||
&item.EventShowInEventList,
|
||||
&item.EventReleasePayloadJSON,
|
||||
&item.EventPresentationID,
|
||||
&item.EventPresentationName,
|
||||
&item.EventPresentationType,
|
||||
&item.EventPresentationSchema,
|
||||
&item.EventContentBundleID,
|
||||
&item.EventContentBundleName,
|
||||
&item.EventContentEntryURL,
|
||||
&item.EventContentAssetRootURL,
|
||||
&item.EventContentMetadataJSON,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("scan map experience detail row: %w", err)
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("iterate map experience detail rows: %w", err)
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
Reference in New Issue
Block a user