Files
gym-manage/gym-manage-coach-uniapp/pages/profile/profile.vue
T

348 lines
7.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="profile-page">
<view class="header-wrap" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-bar" :style="{ height: navBarHeight + 'px' }">
<text class="back-btn" @click="goBack">&#8592;</text>
<text class="nav-title">个人中心</text>
</view>
</view>
<scroll-view class="content" scroll-y :style="{ height: 'calc(100vh - ' + totalHeaderHeight + 'px)' }">
<view class="content-inner">
<!-- 教练信息卡片 -->
<view class="user-card">
<view class="user-header">
<view class="avatar">
<text class="avatar-text">CC</text>
</view>
<view class="user-info">
<text class="user-name">{{ coachInfo.username }}</text>
<view class="user-tag">
<text>教练</text>
</view>
</view>
</view>
<view class="user-details">
<view class="detail-row">
<text class="detail-label">教练 ID</text>
<text class="detail-value">{{ coachInfo.coachId }}</text>
</view>
</view>
</view>
<!-- 违规统计 -->
<view class="stats-card">
<view class="stat-item">
<text class="stat-number">{{ violations.length }}</text>
<text class="stat-label">违规次数</text>
</view>
</view>
<!-- 违规记录列表 -->
<view class="section-header">
<text class="section-title">违规记录</text>
</view>
<view v-if="violations.length === 0 && !loadingViolations" class="empty-wrap">
<text class="empty-text">暂无违规记录</text>
</view>
<view v-else class="violation-list">
<view v-for="(v, idx) in violations" :key="idx" class="violation-card">
<view class="violation-header">
<text class="violation-course">{{ v.course_name || '未知课程' }}</text>
<view class="violation-tag" :class="v._violationClass">
<text>{{ v._violationLabel }}</text>
</view>
</view>
<text class="violation-time">{{ formatViolationTime(v.violation_time) }}</text>
</view>
</view>
<!-- 退出登录 -->
<view class="logout-area">
<button class="logout-btn" @click="handleLogout">退出登录</button>
</view>
<view class="bottom-safe"></view>
</view>
</scroll-view>
</view>
</template>
<script>
const store = require('../../store/index')
const coachApi = require('../../api/coach')
export default {
data() {
return {
statusBarHeight: 0,
navBarHeight: 44,
totalHeaderHeight: 44,
coachInfo: {
username: '加载中...',
coachId: ''
},
violations: [],
loadingViolations: true
}
},
onLoad() {
const systemInfo = uni.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 20
let navBarHeight = 44
// #ifdef MP-WEIXIN
const menuButton = uni.getMenuButtonBoundingClientRect()
if (menuButton) {
navBarHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.height
}
// #endif
this.statusBarHeight = statusBarHeight
this.navBarHeight = navBarHeight
this.totalHeaderHeight = statusBarHeight + navBarHeight
},
onShow() {
if (!store.isLoggedIn) {
uni.reLaunch({ url: '/pages/login/login' })
return
}
this.coachInfo = store.getCoachInfo() || { username: '教练', coachId: '' }
this.loadViolations()
},
methods: {
goBack() { uni.navigateBack() },
async loadViolations() {
this.loadingViolations = true
try {
const coachId = store.getCoachId()
if (!coachId) return
const result = await coachApi.getCoachViolations(coachId)
const list = Array.isArray(result) ? result : (result && result.content ? result.content : [])
// 预计算违规 class 和 labeluni-app 模板不支持 :class 中调用方法
const classMap = { COACH_LATE: 'late', COACH_ABSENT: 'absent', NOT_MANUAL_END: 'no-manual-end' }
const labelMap = { COACH_LATE: '迟到', COACH_ABSENT: '缺席', NOT_MANUAL_END: '未手动结课' }
this.violations = list.map(v => ({
...v,
_violationClass: classMap[v.violation_reason] || '',
_violationLabel: labelMap[v.violation_reason] || v.violation_reason || '违规'
}))
} catch (e) {
console.error('加载违规记录失败:', e)
} finally {
this.loadingViolations = false
}
},
handleLogout() {
uni.showModal({
title: '提示',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
store.clearLogin()
uni.reLaunch({ url: '/pages/login/login' })
}
}
})
},
formatViolationTime(timeStr) {
if (!timeStr) return ''
return timeStr.replace('T', ' ').substring(0, 19)
}
}
}
</script>
<style scoped>
.profile-page {
min-height: 100vh;
background: #F5F7FA;
overflow-x: hidden;
}
.header-wrap {
background: #1A1A1A;
}
.nav-bar {
padding: 0 16px;
display: flex;
align-items: center;
}
.back-btn {
font-size: 20px;
color: #FFFFFF;
margin-right: 12px;
}
.nav-title {
font-size: 18px;
font-weight: 700;
color: #FFFFFF;
}
.content-inner {
padding: 16px 14px 0;
}
/* 用户卡片 */
.user-card {
background: #FFFFFF;
border-radius: 20px;
padding: 20px;
margin-bottom: 16px;
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
}
.user-header {
display: flex;
align-items: center;
margin-bottom: 16px;
}
.avatar {
width: 56px;
height: 56px;
border-radius: 50%;
background: rgba(0,230,118,0.15);
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
}
.avatar-text {
font-size: 20px;
font-weight: 700;
color: #00C853;
}
.user-info {
flex: 1;
}
.user-name {
font-size: 18px;
font-weight: 700;
color: #1E1E1E;
}
.user-tag {
font-size: 13px;
color: #00C853;
font-weight: 500;
}
.user-details {
background: #F5F7FA;
border-radius: 12px;
padding: 14px 16px;
}
.detail-row {
display: flex;
justify-content: space-between;
}
.detail-label {
font-size: 13px;
color: #7A7E84;
}
.detail-value {
font-size: 14px;
font-weight: 600;
color: #1E1E1E;
}
/* 违规统计 */
.stats-card {
background: #1A1A1A;
border-radius: 20px;
padding: 18px 20px;
margin-bottom: 16px;
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
}
.stat-number {
font-size: 28px;
font-weight: 700;
color: #F44336;
}
.stat-label {
font-size: 12px;
color: rgba(255,255,255,0.6);
margin-top: 4px;
}
/* 违规记录 */
.section-header {
margin-bottom: 12px;
}
.section-title {
font-size: 16px;
font-weight: 700;
color: #1E1E1E;
}
.empty-wrap {
display: flex;
justify-content: center;
padding: 30px 0;
}
.empty-text {
font-size: 14px;
color: #7A7E84;
}
.violation-list {
margin-bottom: 16px;
}
.violation-card {
background: #FFFFFF;
border-radius: 12px;
padding: 12px 16px;
margin-bottom: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
}
.violation-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
}
.violation-course {
font-size: 14px;
font-weight: 600;
color: #1E1E1E;
}
.violation-tag {
padding: 3px 10px;
border-radius: 12px;
font-size: 11px;
font-weight: 600;
}
.violation-tag.late { background: rgba(255,152,0,0.15); color: #FF9800; }
.violation-tag.absent { background: rgba(244,67,54,0.15); color: #F44336; }
.violation-tag.no-manual-end { background: rgba(33,150,243,0.15); color: #2196F3; }
.violation-time {
font-size: 12px;
color: #7A7E84;
}
/* 退出登录 */
.logout-area {
padding: 20px 0;
}
.logout-btn {
width: 100%;
height: 50px;
background: #FFFFFF;
color: #F44336;
border-radius: 40px;
font-size: 16px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #F44336;
}
.logout-btn::after { border: none; }
.bottom-safe {
height: 30px;
}
</style>