更新会员端个人页面中团课签到记录显示

This commit was merged in pull request #50.
This commit is contained in:
2026-07-20 17:27:22 +08:00
parent 4a4697c816
commit 53d1ce6fb2
+75 -3
View File
@@ -71,6 +71,33 @@
<text class="sign-status" :class="record.status">{{ record.statusLabel }}</text>
</view>
</view>
<view v-if="signInRecords.length === 0" class="empty-hint">
<text>暂无签到记录</text>
</view>
</view>
<view class="sign-section">
<view class="sign-header">
<view class="section-title-row">
<text class="section-symbol">&#10003;</text>
<text class="section-title">团课签到记录</text>
</view>
<text class="section-more">最近{{ courseCheckInRecords.length }}</text>
</view>
<view v-for="(record, idx) in courseCheckInRecords" :key="'gc' + idx" class="sign-item">
<view class="sign-left">
<text class="sign-date">{{ record.fullDate }}</text>
<text class="sign-time">{{ record.shortTime }}</text>
</view>
<view class="sign-right">
<text class="sign-type">{{ record.courseName }}</text>
<text class="sign-source">{{ record.location }}</text>
<text class="sign-status success">已签到</text>
</view>
</view>
<view v-if="courseCheckInRecords.length === 0" class="empty-hint">
<text>暂无团课签到记录</text>
</view>
</view>
<view class="bottom-safe"></view>
@@ -116,6 +143,7 @@
<script>
const store = require('../../store/index')
const memberApi = require('../../api/member')
const bookingApi = require('../../api/booking')
const defaultAvatar = require('../../common/img/20200414210134_qbeyi.jpg')
export default {
@@ -131,6 +159,7 @@
totalSignInDays: 0, monthSignInCount: 0
},
signInRecords: [],
courseCheckInRecords: [],
// 编辑弹窗
showEdit: false,
saving: false,
@@ -171,10 +200,20 @@
async loadData() {
this.loading = true
try {
const [memberResult, signInResult] = await Promise.allSettled([
const memberInfo = store.getMemberInfo()
const memberId = memberInfo ? (memberInfo.memberId || memberInfo.id) : null
const promises = [
memberApi.getMemberInfo(),
memberApi.getCheckInRecords({ page: 0, size: 5 })
])
]
if (memberId) {
promises.push(bookingApi.getMemberBookings(memberId))
}
const results = await Promise.allSettled(promises)
const [memberResult, signInResult] = results
if (memberResult.status === 'fulfilled') {
const info = memberResult.value
this.userInfo = {
@@ -203,6 +242,38 @@
statusLabel: r.status === 'SUCCESS' || r.status === 1 ? '成功' : '失败'
}))
}
// 处理团课签到记录(预约状态为「已出席」的课程)
if (results.length >= 3 && results[2].status === 'fulfilled') {
const bookings = results[2].value
const arr = Array.isArray(bookings) ? bookings : (bookings && bookings.content ? bookings.content : [])
this.courseCheckInRecords = arr
.filter(b => String(b.status) === '2')
.map(b => {
const st = b.courseStartTime || ''
const dt = st ? new Date(st.replace(/ /, 'T')) : null
const y = dt && !isNaN(dt) ? String(dt.getFullYear()) : ''
const mo = dt && !isNaN(dt) ? String(dt.getMonth() + 1).padStart(2, '0') : ''
const d = dt && !isNaN(dt) ? String(dt.getDate()).padStart(2, '0') : ''
const hh = dt && !isNaN(dt) ? String(dt.getHours()).padStart(2, '0') : '--'
const mm = dt && !isNaN(dt) ? String(dt.getMinutes()).padStart(2, '0') : '--'
const inTime = b.checkInTime || b.updatedAt || ''
const indt = inTime ? new Date(inTime.replace(/ /, 'T')) : null
let checkInTimeStr = ''
if (indt && !isNaN(indt)) {
checkInTimeStr = String(indt.getMonth() + 1).padStart(2, '0') + '-' +
String(indt.getDate()).padStart(2, '0') + ' ' +
String(indt.getHours()).padStart(2, '0') + ':' +
String(indt.getMinutes()).padStart(2, '0')
}
return {
courseName: b.courseName || '未命名课程',
location: b.location || '',
fullDate: y + '-' + mo + '-' + d,
shortTime: hh + ':' + mm,
checkInTime: checkInTimeStr || (mo + '-' + d)
}
})
}
} catch (e) {
console.error('个人中心数据加载失败:', e)
} finally {
@@ -318,11 +389,12 @@
.sign-date { font-size: 14px; font-weight: 600; color: #1E1E1E; }
.sign-time { font-size: 12px; color: #7A7E84; margin-top: 2px; }
.sign-right { display: flex; align-items: center; }
.sign-type { font-size: 12px; color: #7A7E84; margin-right: 6px; }
.sign-type { font-size: 12px; color: #7A7E84; margin-right: 6px; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sign-source { font-size: 11px; color: #BDBDBD; background: #F5F7FA; padding: 1px 6px; border-radius: 8px; margin-right: 6px; }
.sign-status { font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 20px; }
.sign-status.success { background: rgba(0,230,118,0.15); color: #00C853; }
.sign-status.fail { background: rgba(255,82,82,0.15); color: #FF5252; }
.empty-hint { text-align: center; padding: 20px 0; color: #BDBDBD; font-size: 13px; }
.bottom-safe { height: 50px; }
/* 编辑弹窗 */
.edit-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 1000; display: flex; align-items: center; justify-content: center; }