experience-map.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import { loadBackendAuthTokens, loadBackendBaseUrl } from '../../utils/backendAuth'
  2. import {
  3. getExperienceMapDetail,
  4. getPublicExperienceMapDetail,
  5. type BackendContentBundleSummary,
  6. type BackendDefaultExperienceSummary,
  7. type BackendExperienceMapDetail,
  8. type BackendPresentationSummary,
  9. } from '../../utils/backendApi'
  10. import { reportBackendClientLog } from '../../utils/backendClientLogs'
  11. type DefaultExperienceCardView = {
  12. eventId: string
  13. titleText: string
  14. subtitleText: string
  15. statusText: string
  16. ctaText: string
  17. eventTypeText: string
  18. presentationText: string
  19. contentBundleText: string
  20. disabled: boolean
  21. }
  22. type ExperienceMapPageData = {
  23. mapId: string
  24. loading: boolean
  25. statusText: string
  26. placeText: string
  27. mapText: string
  28. summaryText: string
  29. tileInfoText: string
  30. cards: DefaultExperienceCardView[]
  31. }
  32. function getAccessToken(): string | null {
  33. const app = getApp<IAppOption>()
  34. const tokens = app.globalData && app.globalData.backendAuthTokens
  35. ? app.globalData.backendAuthTokens
  36. : loadBackendAuthTokens()
  37. return tokens && tokens.accessToken ? tokens.accessToken : null
  38. }
  39. function formatPresentationSummary(summary?: BackendPresentationSummary | null): string {
  40. if (!summary) {
  41. return '当前未声明展示版本'
  42. }
  43. return summary.version || summary.templateKey || summary.presentationId || '当前未声明展示版本'
  44. }
  45. function formatContentBundleSummary(summary?: BackendContentBundleSummary | null): string {
  46. if (!summary) {
  47. return '当前未声明内容包版本'
  48. }
  49. return summary.version || summary.bundleType || summary.bundleId || '当前未声明内容包版本'
  50. }
  51. function buildDefaultExperienceCard(item: BackendDefaultExperienceSummary): DefaultExperienceCardView {
  52. const eventId = item.eventId || ''
  53. return {
  54. eventId,
  55. titleText: item.title || '未命名体验活动',
  56. subtitleText: item.subtitle || '当前暂无副标题',
  57. statusText: item.status || item.statusCode || '状态待确认',
  58. ctaText: item.ctaText || '查看体验',
  59. eventTypeText: item.eventType || '类型待确认',
  60. presentationText: formatPresentationSummary(item.currentPresentation),
  61. contentBundleText: formatContentBundleSummary(item.currentContentBundle),
  62. disabled: !eventId,
  63. }
  64. }
  65. Page({
  66. data: {
  67. mapId: '',
  68. loading: false,
  69. statusText: '准备加载地图详情',
  70. placeText: '地点待确认',
  71. mapText: '地图待确认',
  72. summaryText: '当前暂无地图摘要',
  73. tileInfoText: '瓦片信息待确认',
  74. cards: [],
  75. } as ExperienceMapPageData,
  76. onLoad(query: { mapId?: string }) {
  77. const mapId = query && query.mapId ? decodeURIComponent(query.mapId) : ''
  78. if (!mapId) {
  79. this.setData({
  80. statusText: '缺少 mapId',
  81. })
  82. return
  83. }
  84. this.setData({ mapId })
  85. this.loadMapDetail(mapId)
  86. },
  87. onShow() {
  88. if (this.data.mapId) {
  89. this.loadMapDetail(this.data.mapId)
  90. }
  91. },
  92. async loadMapDetail(mapId?: string) {
  93. const targetMapId = mapId || this.data.mapId
  94. const accessToken = getAccessToken()
  95. this.setData({
  96. loading: true,
  97. statusText: '正在加载地图详情',
  98. })
  99. try {
  100. const baseUrl = loadBackendBaseUrl()
  101. const result = accessToken
  102. ? await getExperienceMapDetail({
  103. baseUrl,
  104. accessToken,
  105. mapAssetId: targetMapId,
  106. })
  107. : await getPublicExperienceMapDetail({
  108. baseUrl,
  109. mapAssetId: targetMapId,
  110. })
  111. this.applyDetail(result)
  112. } catch (error) {
  113. const message = error && (error as { message?: string }).message ? (error as { message: string }).message : '未知错误'
  114. this.setData({
  115. loading: false,
  116. statusText: `地图详情加载失败:${message}`,
  117. cards: [],
  118. })
  119. }
  120. },
  121. applyDetail(result: BackendExperienceMapDetail) {
  122. const cards = (result.defaultExperiences || []).map(buildDefaultExperienceCard)
  123. reportBackendClientLog({
  124. level: 'info',
  125. category: 'experience-map-detail',
  126. message: 'experience map detail loaded',
  127. details: {
  128. guestMode: !getAccessToken(),
  129. mapId: result.mapId || this.data.mapId || '',
  130. placeId: result.placeId || '',
  131. defaultExperienceCount: cards.length,
  132. defaultExperienceEventIds: (result.defaultExperiences || []).map((item) => item.eventId || ''),
  133. },
  134. })
  135. const tileBase = result.tileBaseUrl || ''
  136. const tileMeta = result.tileMetaUrl || ''
  137. const tileInfoText = tileBase || tileMeta
  138. ? `底图 ${tileBase || '--'} / Meta ${tileMeta || '--'}`
  139. : '当前未声明瓦片信息'
  140. this.setData({
  141. loading: false,
  142. statusText: cards.length ? '地图详情加载完成' : '当前地图暂无默认体验活动',
  143. placeText: result.placeName || result.placeId || '地点待确认',
  144. mapText: result.mapName || result.mapId || '地图待确认',
  145. summaryText: result.summary || '当前暂无地图摘要',
  146. tileInfoText,
  147. cards,
  148. })
  149. },
  150. handleRefresh() {
  151. this.loadMapDetail()
  152. },
  153. handleOpenExperience(event: WechatMiniprogram.TouchEvent) {
  154. const eventId = event.currentTarget.dataset.eventId as string | undefined
  155. reportBackendClientLog({
  156. level: 'info',
  157. category: 'experience-map-detail',
  158. message: 'default experience clicked',
  159. eventId: eventId || '',
  160. details: {
  161. mapId: this.data.mapId || '',
  162. clickedEventId: eventId || '',
  163. },
  164. })
  165. if (!eventId) {
  166. wx.showToast({
  167. title: '该体验活动暂无入口',
  168. icon: 'none',
  169. })
  170. return
  171. }
  172. wx.navigateTo({
  173. url: `/pages/event/event?eventId=${encodeURIComponent(eventId)}`,
  174. })
  175. },
  176. })