chore: establish V1.1 recovery baseline

This commit is contained in:
2026-09-09 22:05:00 +08:00
commit b46b48eb33
947 changed files with 155471 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
/**
* 签到码页 U31
*/
const api = require('../../utils/api');
Page({
data: {
activityId: '',
activityTitle: '',
locationName: '',
token: '',
expiresAt: '',
loading: true,
error: ''
},
onLoad(options) {
if (options.id) {
this.setData({ activityId: options.id });
this.loadCheckinToken();
}
},
onShow() {
// 每次显示时刷新Token
if (this.data.activityId) {
this.loadCheckinToken();
}
},
async loadCheckinToken() {
this.setData({ loading: true, error: '' });
try {
const token = wx.getStorageSync('accessToken');
const res = await api.post(`/activities/${this.data.activityId}/checkin-token`, {}, {
Authorization: `Bearer ${token}`
});
this.setData({
token: res.token,
activityTitle: res.activityTitle,
locationName: res.locationName,
expiresAt: res.expiresAt,
loading: false
});
} catch (err) {
this.setData({ loading: false, error: err.message || '加载失败' });
}
},
onRefresh() {
this.loadCheckinToken();
},
copyToken() {
wx.setClipboardData({
data: this.data.token,
success: () => wx.showToast({ title: '签到码已复制', icon: 'success' })
});
}
});
+4
View File
@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "活动签到",
"usingComponents": {}
}
+41
View File
@@ -0,0 +1,41 @@
<!-- 签到码页 U31 -->
<view class="page">
<view class="header">
<text class="title">活动签到</text>
</view>
<view wx:if="{{loading}}" class="loading-state">
<text>生成签到码中...</text>
</view>
<view wx:if="{{error}}" class="error-state">
<text>{{error}}</text>
<button class="btn-refresh" bindtap="onRefresh">重试</button>
</view>
<view wx:if="{{!loading && !error}}" class="checkin-card">
<view class="activity-info">
<text class="activity-title">{{activityTitle}}</text>
<text class="activity-location">📍 {{locationName}}</text>
</view>
<view class="qr-section">
<view class="qr-placeholder">
<text class="qr-icon">▣</text>
</view>
<text class="qr-hint">请向工作人员展示此签到码</text>
</view>
<view class="token-section">
<text class="token-label">签到码</text>
<text class="token-value" selectable="true">{{token}}</text>
<button class="btn-copy" bindtap="copyToken">复制签到码</button>
</view>
<view class="expire-info">
<text>有效期:{{formatExpiresAt(expiresAt)}}</text>
</view>
</view>
<button class="btn-refresh-page" bindtap="onRefresh">刷新签到码</button>
</view>
+140
View File
@@ -0,0 +1,140 @@
.page {
padding: 32rpx;
background: #FFF8F7;
min-height: 100vh;
}
.header {
text-align: center;
margin-bottom: 32rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #1A1A1A;
}
.loading-state, .error-state {
text-align: center;
padding: 80rpx;
color: #999;
}
.checkin-card {
background: #fff;
border-radius: 24rpx;
padding: 40rpx;
margin-bottom: 24rpx;
}
.activity-info {
text-align: center;
margin-bottom: 32rpx;
}
.activity-title {
display: block;
font-size: 32rpx;
font-weight: bold;
color: #1A1A1A;
margin-bottom: 8rpx;
}
.activity-location {
display: block;
font-size: 26rpx;
color: #999;
}
.qr-section {
text-align: center;
padding: 32rpx 0;
border-top: 1rpx solid #f5f5f5;
border-bottom: 1rpx solid #f5f5f5;
margin-bottom: 32rpx;
}
.qr-placeholder {
width: 300rpx;
height: 300rpx;
margin: 0 auto 20rpx;
background: #F5F5F5;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
}
.qr-icon {
font-size: 120rpx;
color: #CCC;
}
.qr-hint {
font-size: 26rpx;
color: #999;
}
.token-section {
margin-bottom: 24rpx;
}
.token-label {
font-size: 26rpx;
color: #666;
display: block;
margin-bottom: 12rpx;
}
.token-value {
display: block;
font-size: 24rpx;
color: #333;
background: #F5F5F5;
padding: 20rpx;
border-radius: 12rpx;
word-break: break-all;
margin-bottom: 16rpx;
}
.btn-copy {
width: 100%;
height: 72rpx;
line-height: 72rpx;
background: #FFF3F2;
color: #E96B6B;
border-radius: 36rpx;
font-size: 26rpx;
border: none;
}
.expire-info {
text-align: center;
font-size: 24rpx;
color: #E59A32;
padding: 16rpx;
background: #FFF8E1;
border-radius: 12rpx;
}
.btn-refresh-page {
background: #E96B6B;
color: #fff;
border-radius: 44rpx;
height: 88rpx;
line-height: 88rpx;
font-size: 30rpx;
margin-top: 24rpx;
}
.btn-refresh {
margin-top: 24rpx;
background: #E96B6B;
color: #fff;
border-radius: 44rpx;
height: 72rpx;
line-height: 72rpx;
font-size: 28rpx;
border: none;
}