推进活动列表第一刀与联调回归

This commit is contained in:
2026-04-03 19:33:16 +08:00
parent b09c21c814
commit 527b4c78a9
34 changed files with 3094 additions and 224 deletions

View File

@@ -13,6 +13,7 @@ const DEBUG_MOCK_AUTO_CONNECT_STORAGE_KEY = 'cmr.debug.autoConnectMockSources.v1
type EventPreparePageData = {
eventId: string
loading: boolean
canLaunch: boolean
titleText: string
summaryText: string
releaseText: string
@@ -29,6 +30,8 @@ type EventPreparePageData = {
runtimeRouteCodeText: string
selectedVariantId: string
selectedVariantText: string
showVariantSelector: boolean
variantSelectorEmptyText: string
selectableVariants: Array<{
id: string
name: string
@@ -54,6 +57,27 @@ type EventPreparePageData = {
mockSourceStatusText: string
}
function detectMultiVariantContext(result: BackendEventPlayResult): boolean {
const assignmentMode = result.play.assignmentMode
if (assignmentMode === 'manual' || assignmentMode === 'random' || assignmentMode === 'server-assigned') {
return true
}
const variants = result.play.courseVariants || []
if (variants.length > 0) {
return true
}
const haystacks = [
result.event.displayName,
result.event.summary,
result.release ? result.release.configLabel : '',
result.resolvedRelease ? result.resolvedRelease.configLabel : '',
]
return haystacks.some((item) => typeof item === 'string' && item.indexOf('多赛道') >= 0)
}
function formatAssignmentMode(mode?: string | null): string {
if (mode === 'manual') {
return '手动选择'
@@ -77,6 +101,7 @@ function formatVariantSummary(result: BackendEventPlayResult): string {
const title = item.routeCode || item.name
return item.selectable === false ? `${title}(固定)` : title
}).join(' / ')
const selectableCount = variants.filter((item) => item.selectable !== false).length
if (result.play.assignmentMode === 'manual') {
return `当前活动支持 ${variants.length} 条赛道。本阶段前端先展示赛道信息,最终绑定以后端 launch 返回为准:${preview}`
@@ -90,13 +115,17 @@ function formatVariantSummary(result: BackendEventPlayResult): string {
return `当前活动赛道由后台预先指定:${preview}`
}
if (selectableCount > 1) {
return `当前活动支持 ${variants.length} 条赛道。后端当前未明确返回赛道模式,前端先按手动选择兼容显示:${preview}`
}
return preview
}
function formatPresentationSummary(result: BackendEventPlayResult): string {
const currentPresentation = result.currentPresentation
if (!currentPresentation) {
return '当前未声明展示版本'
return '当前发布 release 未绑定展示版本,或当前尚未发布'
}
return `${currentPresentation.presentationId || '--'} / ${currentPresentation.templateKey || '--'} / ${currentPresentation.version || '--'}`
@@ -105,7 +134,7 @@ function formatPresentationSummary(result: BackendEventPlayResult): string {
function formatContentBundleSummary(result: BackendEventPlayResult): string {
const currentContentBundle = result.currentContentBundle
if (!currentContentBundle) {
return '当前未声明内容包版本'
return '当前发布 release 未绑定内容包版本,或当前尚未发布'
}
return `${currentContentBundle.bundleId || '--'} / ${currentContentBundle.bundleType || '--'} / ${currentContentBundle.version || '--'}`
@@ -115,12 +144,13 @@ function resolveSelectedVariantId(
currentVariantId: string,
assignmentMode?: string | null,
variants?: BackendCourseVariantSummary[] | null,
forceVisible?: boolean,
): string {
if (assignmentMode !== 'manual' || !variants || !variants.length) {
if (!shouldShowVariantSelector(assignmentMode, variants, forceVisible)) {
return ''
}
const selectable = variants.filter((item) => item.selectable !== false)
const selectable = (variants || []).filter((item) => item.selectable !== false)
if (!selectable.length) {
return ''
}
@@ -137,8 +167,9 @@ function buildSelectableVariants(
selectedVariantId: string,
assignmentMode?: string | null,
variants?: BackendCourseVariantSummary[] | null,
forceVisible?: boolean,
) {
if (assignmentMode !== 'manual' || !variants || !variants.length) {
if (!shouldShowVariantSelector(assignmentMode, variants, forceVisible) || !variants || !variants.length) {
return []
}
@@ -153,6 +184,32 @@ function buildSelectableVariants(
}))
}
function shouldShowVariantSelector(
assignmentMode?: string | null,
variants?: BackendCourseVariantSummary[] | null,
forceVisible?: boolean,
): boolean {
if (forceVisible) {
return true
}
const normalizedVariants = variants || []
if (!normalizedVariants.length) {
return false
}
if (assignmentMode === 'manual') {
return true
}
if (assignmentMode === 'random' || assignmentMode === 'server-assigned') {
return false
}
return normalizedVariants.filter((item) => item.selectable !== false).length > 1
}
let prepareHeartRateController: HeartRateController | null = null
function getAccessToken(): string | null {
@@ -202,6 +259,7 @@ Page({
data: {
eventId: '',
loading: false,
canLaunch: false,
titleText: '开始前准备',
summaryText: '未加载',
releaseText: '--',
@@ -218,6 +276,8 @@ Page({
runtimeRouteCodeText: '待 launch 确认',
selectedVariantId: '',
selectedVariantText: '当前无需手动指定赛道',
showVariantSelector: false,
variantSelectorEmptyText: '当前无需手动指定赛道',
selectableVariants: [],
locationStatusText: '待进入地图后校验定位权限与实时精度',
heartRateStatusText: '局前心率带连接入口待接入,本轮先保留骨架',
@@ -286,17 +346,25 @@ Page({
},
applyEventPlay(result: BackendEventPlayResult) {
const multiVariantContext = detectMultiVariantContext(result)
const selectedVariantId = resolveSelectedVariantId(
this.data.selectedVariantId,
result.play.assignmentMode,
result.play.courseVariants,
multiVariantContext,
)
const assignmentMode = result.play.assignmentMode ? result.play.assignmentMode : null
const showVariantSelector = shouldShowVariantSelector(
result.play.assignmentMode,
result.play.courseVariants,
multiVariantContext,
)
const logVariantId = assignmentMode === 'manual' && selectedVariantId ? selectedVariantId : null
const selectableVariants = buildSelectableVariants(
selectedVariantId,
result.play.assignmentMode,
result.play.courseVariants,
multiVariantContext,
)
const selectedVariant = selectableVariants.find((item) => item.id === selectedVariantId) || null
reportBackendClientLog({
@@ -315,10 +383,20 @@ Page({
resultEventId: result.event.id || '',
selectedVariantId: logVariantId,
assignmentMode,
variantCount: result.play.courseVariants ? result.play.courseVariants.length : 0,
selectableVariantCount: result.play.courseVariants
? result.play.courseVariants.filter((item) => item.selectable !== false).length
: 0,
showVariantSelector,
multiVariantContext,
},
})
const variantSelectorEmptyText = multiVariantContext
? '当前活动按多赛道处理,但后端暂未返回可选赛道,请稍后刷新或联系后台。'
: '当前无需手动指定赛道'
this.setData({
loading: false,
canLaunch: result.play.canLaunch,
titleText: `${result.event.displayName} / 开始前准备`,
summaryText: result.event.summary || '暂无活动简介',
releaseText: result.resolvedRelease
@@ -327,7 +405,9 @@ Page({
actionText: formatBackendPlayActionText(result.play.primaryAction, result.play.reason),
statusText: formatBackendPlayStatusText(result.play.canLaunch, result.play.primaryAction, result.play.reason),
assignmentMode: result.play.assignmentMode || '',
variantModeText: formatAssignmentMode(result.play.assignmentMode),
variantModeText: result.play.assignmentMode
? formatAssignmentMode(result.play.assignmentMode)
: (showVariantSelector ? '手动选择' : '默认单赛道'),
variantSummaryText: formatVariantSummary(result),
presentationText: formatPresentationSummary(result),
contentBundleText: formatContentBundleSummary(result),
@@ -346,7 +426,9 @@ Page({
selectedVariantId,
selectedVariantText: selectedVariant
? `${selectedVariant.name} / ${selectedVariant.routeCodeText}`
: '当前无需手动指定赛道',
: variantSelectorEmptyText,
showVariantSelector,
variantSelectorEmptyText,
selectableVariants,
})
},
@@ -591,6 +673,17 @@ Page({
return
}
if (!this.data.canLaunch) {
this.setData({
statusText: '当前发布状态不可进入地图',
})
wx.showToast({
title: '当前发布状态不可进入地图',
icon: 'none',
})
return
}
if (!this.data.locationPermissionGranted) {
this.setData({
statusText: '进入地图前请先完成定位授权',
@@ -608,7 +701,7 @@ Page({
try {
const assignmentMode = this.data.assignmentMode ? this.data.assignmentMode : null
const selectedVariantId = assignmentMode === 'manual' && this.data.selectedVariantId
const selectedVariantId = this.data.showVariantSelector && this.data.selectedVariantId
? this.data.selectedVariantId
: null
reportBackendClientLog({
@@ -641,7 +734,7 @@ Page({
baseUrl: loadBackendBaseUrl(),
eventId: this.data.eventId,
accessToken,
variantId: this.data.assignmentMode === 'manual' ? this.data.selectedVariantId : undefined,
variantId: this.data.showVariantSelector ? this.data.selectedVariantId : undefined,
clientType: 'wechat',
deviceKey: 'mini-dev-device-001',
})