完善后端联调链路与模拟器多通道支持

This commit is contained in:
2026-04-01 18:48:59 +08:00
parent 94a1f0ba78
commit a70dc8d5d0
51 changed files with 4037 additions and 197 deletions

View File

@@ -0,0 +1,3 @@
{
"navigationBarTitleText": "首页"
}

View File

@@ -0,0 +1,127 @@
import { clearBackendAuthTokens, loadBackendAuthTokens, loadBackendBaseUrl } from '../../utils/backendAuth'
import { getEntryHome, type BackendCardResult, type BackendEntryHomeResult } from '../../utils/backendApi'
const DEFAULT_CHANNEL_CODE = 'mini-demo'
const DEFAULT_CHANNEL_TYPE = 'wechat_mini'
type HomePageData = {
loading: boolean
statusText: string
userNameText: string
tenantText: string
channelText: string
ongoingSessionText: string
recentSessionText: string
cards: BackendCardResult[]
}
function requireAuthToken(): string | null {
const app = getApp<IAppOption>()
const tokens = app.globalData && app.globalData.backendAuthTokens
? app.globalData.backendAuthTokens
: loadBackendAuthTokens()
return tokens && tokens.accessToken ? tokens.accessToken : null
}
Page({
data: {
loading: false,
statusText: '准备加载首页',
userNameText: '--',
tenantText: '--',
channelText: '--',
ongoingSessionText: '无',
recentSessionText: '无',
cards: [],
} as HomePageData,
onLoad() {
this.loadEntryHome()
},
onShow() {
this.loadEntryHome()
},
async loadEntryHome() {
const accessToken = requireAuthToken()
if (!accessToken) {
wx.redirectTo({ url: '/pages/login/login' })
return
}
this.setData({
loading: true,
statusText: '正在加载首页聚合',
})
try {
const result = await getEntryHome({
baseUrl: loadBackendBaseUrl(),
accessToken,
channelCode: DEFAULT_CHANNEL_CODE,
channelType: DEFAULT_CHANNEL_TYPE,
})
this.applyEntryHomeResult(result)
} catch (error) {
const message = error && (error as { message?: string }).message ? (error as { message: string }).message : '未知错误'
this.setData({
loading: false,
statusText: `首页加载失败:${message}`,
})
}
},
applyEntryHomeResult(result: BackendEntryHomeResult) {
this.setData({
loading: false,
statusText: '首页加载完成',
userNameText: result.user.nickname || result.user.publicId || result.user.id,
tenantText: `${result.tenant.name} (${result.tenant.code})`,
channelText: `${result.channel.displayName} / ${result.channel.code}`,
ongoingSessionText: result.ongoingSession
? `${result.ongoingSession.eventName || result.ongoingSession.eventDisplayName || result.ongoingSession.eventId || result.ongoingSession.id || result.ongoingSession.sessionId} / ${result.ongoingSession.status || result.ongoingSession.sessionStatus}`
: '无',
recentSessionText: result.recentSession
? `${result.recentSession.eventName || result.recentSession.eventDisplayName || result.recentSession.eventId || result.recentSession.id || result.recentSession.sessionId} / ${result.recentSession.status || result.recentSession.sessionStatus}`
: '无',
cards: result.cards || [],
})
},
handleRefresh() {
this.loadEntryHome()
},
handleOpenCard(event: WechatMiniprogram.TouchEvent) {
const eventId = event.currentTarget.dataset.eventId as string | undefined
if (!eventId) {
wx.showToast({
title: '该卡片暂无活动入口',
icon: 'none',
})
return
}
wx.navigateTo({
url: `/pages/event/event?eventId=${encodeURIComponent(eventId)}`,
})
},
handleOpenRecentResult() {
wx.navigateTo({
url: '/pages/result/result',
})
},
handleLogout() {
clearBackendAuthTokens()
const app = getApp<IAppOption>()
if (app.globalData) {
app.globalData.backendAuthTokens = null
}
wx.redirectTo({
url: '/pages/login/login',
})
},
})

View File

@@ -0,0 +1,32 @@
<scroll-view class="page" scroll-y>
<view class="shell">
<view class="hero">
<view class="hero__eyebrow">Entry Home</view>
<view class="hero__title">{{userNameText}}</view>
<view class="hero__desc">{{tenantText}}</view>
<view class="hero__desc">{{channelText}}</view>
</view>
<view class="panel">
<view class="panel__title">当前状态</view>
<view class="summary">{{statusText}}</view>
<view class="summary">进行中:{{ongoingSessionText}}</view>
<view class="summary">最近一局:{{recentSessionText}}</view>
<view class="actions">
<button class="btn btn--secondary" bindtap="handleRefresh">刷新首页</button>
<button class="btn btn--ghost" bindtap="handleOpenRecentResult">查看结果</button>
<button class="btn btn--ghost" bindtap="handleLogout">退出登录</button>
</view>
</view>
<view class="panel">
<view class="panel__title">活动入口</view>
<view wx:if="{{!cards.length}}" class="summary">当前没有首页卡片</view>
<view wx:for="{{cards}}" wx:key="id" class="card" bindtap="handleOpenCard" data-event-id="{{item.event && item.event.id ? item.event.id : ''}}">
<view class="card__title">{{item.title}}</view>
<view class="card__subtitle">{{item.subtitle || (item.event && item.event.displayName ? item.event.displayName : '暂无副标题')}}</view>
<view class="card__meta">{{item.type}} / {{item.displaySlot}}</view>
</view>
</view>
</view>
</scroll-view>

View File

@@ -0,0 +1,111 @@
page {
min-height: 100vh;
background: linear-gradient(180deg, #eff4fb 0%, #e8eff7 100%);
}
.page {
min-height: 100vh;
}
.shell {
display: grid;
gap: 24rpx;
padding: 28rpx 24rpx 40rpx;
}
.hero,
.panel {
display: grid;
gap: 16rpx;
padding: 24rpx;
border-radius: 24rpx;
}
.hero {
background: linear-gradient(135deg, #163a66 0%, #1f5da1 100%);
color: #ffffff;
}
.hero__eyebrow {
font-size: 22rpx;
letter-spacing: 0.16em;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.72);
}
.hero__title {
font-size: 40rpx;
font-weight: 700;
}
.hero__desc {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.84);
}
.panel {
background: rgba(255, 255, 255, 0.94);
box-shadow: 0 14rpx 32rpx rgba(40, 63, 95, 0.08);
}
.panel__title {
font-size: 30rpx;
font-weight: 700;
color: #17345a;
}
.summary {
font-size: 24rpx;
line-height: 1.6;
color: #30465f;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
.btn {
margin: 0;
min-height: 76rpx;
padding: 0 24rpx;
line-height: 76rpx;
border-radius: 18rpx;
font-size: 26rpx;
}
.btn::after {
border: 0;
}
.btn--secondary {
background: #dfeaf8;
color: #173d73;
}
.btn--ghost {
background: #ffffff;
color: #52657d;
border: 2rpx solid #d8e2ec;
}
.card {
display: grid;
gap: 10rpx;
padding: 20rpx;
border-radius: 20rpx;
background: #f6f9fc;
}
.card__title {
font-size: 28rpx;
font-weight: 700;
color: #17345a;
}
.card__subtitle,
.card__meta {
font-size: 22rpx;
color: #64748b;
}