新增e2e测试脚本,修复部分问题
This commit was merged in pull request #51.
This commit is contained in:
@@ -30,8 +30,45 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 业绩数据 -->
|
||||
<view class="performance-card">
|
||||
<view class="section-header">
|
||||
<text class="section-title">本月业绩</text>
|
||||
<text class="period-text">{{ performance.periodLabel }}</text>
|
||||
</view>
|
||||
<view class="perf-grid">
|
||||
<view class="perf-item">
|
||||
<text class="perf-number">{{ performance.totalLessons }}</text>
|
||||
<text class="perf-label">授课量</text>
|
||||
</view>
|
||||
<view class="perf-item">
|
||||
<text class="perf-number">{{ performance.totalAttendees }}</text>
|
||||
<text class="perf-label">学员人次</text>
|
||||
</view>
|
||||
<view class="perf-item" @click="showFormula('attendance')">
|
||||
<text class="perf-number">{{ performance.attendanceRate != null ? performance.attendanceRate + '%' : 'N/A' }}</text>
|
||||
<text class="perf-label">出勤率 ▸</text>
|
||||
<view v-if="performance.attendanceRate != null" class="perf-bar-wrap">
|
||||
<view class="perf-bar" :style="{ width: performance.attendanceRate + '%', background: getRateColor(performance.attendanceRate) }"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="perf-item" @click="showFormula('fullness')">
|
||||
<text class="perf-number">{{ performance.fullnessRate != null ? performance.fullnessRate + '%' : 'N/A' }}</text>
|
||||
<text class="perf-label">满员率 ▸</text>
|
||||
<view v-if="performance.fullnessRate != null" class="perf-bar-wrap">
|
||||
<view class="perf-bar" :style="{ width: performance.fullnessRate + '%', background: getRateColor(performance.fullnessRate) }"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="score-row" @click="showFormula('composite')">
|
||||
<text class="score-label">综合评分 ▸</text>
|
||||
<text class="score-badge" :class="scoreClass">{{ scoreText }}</text>
|
||||
<text v-if="scoreText !== '--'" class="score-icon">★</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 违规统计 -->
|
||||
<view class="stats-card">
|
||||
<view v-if="violations.length > 0" class="stats-card">
|
||||
<view class="stat-item">
|
||||
<text class="stat-number">{{ violations.length }}</text>
|
||||
<text class="stat-label">违规次数</text>
|
||||
@@ -39,15 +76,11 @@
|
||||
</view>
|
||||
|
||||
<!-- 违规记录列表 -->
|
||||
<view class="section-header">
|
||||
<view v-if="violations.length > 0" 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-if="violations.length > 0" 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>
|
||||
@@ -59,6 +92,24 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 计算方式弹窗 -->
|
||||
<view v-if="formulaVisible" class="formula-overlay" @click="closeFormula">
|
||||
<view class="formula-dialog" @click.stop>
|
||||
<view class="formula-header">
|
||||
<text class="formula-title">{{ formulaTitle }}</text>
|
||||
<text class="formula-close" @click="closeFormula">✕</text>
|
||||
</view>
|
||||
<view class="formula-body">
|
||||
<text class="formula-text">{{ formulaContent }}</text>
|
||||
<view class="formula-divider"></view>
|
||||
<text class="formula-example">{{ formulaExample }}</text>
|
||||
</view>
|
||||
<view class="formula-footer">
|
||||
<button class="formula-btn" @click="closeFormula">知道了</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退出登录 -->
|
||||
<view class="logout-area">
|
||||
<button class="logout-btn" @click="handleLogout">退出登录</button>
|
||||
@@ -85,7 +136,21 @@
|
||||
coachId: ''
|
||||
},
|
||||
violations: [],
|
||||
loadingViolations: true
|
||||
loadingViolations: true,
|
||||
performance: {
|
||||
totalLessons: 0,
|
||||
totalAttendees: 0,
|
||||
attendanceRate: null,
|
||||
fullnessRate: null,
|
||||
periodLabel: ''
|
||||
},
|
||||
compositeScore: null,
|
||||
scoreText: '--',
|
||||
scoreClass: '',
|
||||
formulaVisible: false,
|
||||
formulaTitle: '',
|
||||
formulaContent: '',
|
||||
formulaExample: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
@@ -109,10 +174,61 @@
|
||||
}
|
||||
this.coachInfo = store.getCoachInfo() || { username: '教练', coachId: '' }
|
||||
this.loadViolations()
|
||||
this.loadPerformance()
|
||||
},
|
||||
methods: {
|
||||
goBack() { uni.navigateBack() },
|
||||
|
||||
async loadPerformance() {
|
||||
try {
|
||||
const coachId = store.getCoachId()
|
||||
if (!coachId) return
|
||||
const data = await coachApi.getCoachPerformance(coachId, 'MONTH')
|
||||
if (data) {
|
||||
this.$set(this.performance, 'totalLessons', data.completedCourses != null ? data.completedCourses : 0)
|
||||
this.$set(this.performance, 'totalAttendees', data.attendedStudents != null ? data.attendedStudents : 0)
|
||||
this.$set(this.performance, 'attendanceRate', data.attendanceRate != null ? Math.round(data.attendanceRate) : null)
|
||||
this.$set(this.performance, 'fullnessRate', data.fillRate != null ? Math.round(data.fillRate) : null)
|
||||
const score = data.compositeScore != null ? Math.round(data.compositeScore * 10) / 10 : null
|
||||
this.compositeScore = score
|
||||
this.scoreText = score != null ? score.toFixed(1) : '--'
|
||||
if (score == null) {
|
||||
this.scoreClass = ''
|
||||
} else if (score >= 80) {
|
||||
this.scoreClass = 'score-great'
|
||||
} else if (score >= 60) {
|
||||
this.scoreClass = 'score-good'
|
||||
} else {
|
||||
this.scoreClass = 'score-low'
|
||||
}
|
||||
this.$set(this.performance, 'periodLabel', '本月')
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('加载业绩数据失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
showFormula(type) {
|
||||
if (type === 'attendance') {
|
||||
this.formulaTitle = '出勤率计算方式'
|
||||
this.formulaContent = '出勤率 = 出席人次 ÷ 非取消预约总数 × 100%'
|
||||
this.formulaExample = '示例:本月有 10 人预约了你的课程,其中 2 人取消预约,8 人中实际出席 7 人\n\n出勤率 = 7 ÷ (10 - 2) × 100% = 87.5%'
|
||||
} else if (type === 'fullness') {
|
||||
this.formulaTitle = '满员率计算方式'
|
||||
this.formulaContent = '满员率 = 各课程(出席人数 ÷ 课程最大容量)的平均值 × 100%'
|
||||
this.formulaExample = '示例:本月你完成了 2 节课\n- 课程 A:容量 20 人,实际出席 12 人 → 60%\n- 课程 B:容量 15 人,实际出席 9 人 → 60%\n\n满员率 = (60% + 60%) ÷ 2 = 60%'
|
||||
} else if (type === 'composite') {
|
||||
this.formulaTitle = '综合评分计算方式'
|
||||
this.formulaContent = '综合评分 = 授课量评分 × 40% + 出勤率评分 × 30% + 满员率评分 × 30%'
|
||||
this.formulaExample = '计算步骤:\n1. 授课量归一化:你的授课量 ÷ 全部教练最高授课量 × 100\n2. 出勤率与满员率各取实际百分值\n3. 加权求和\n\n示例:\n授课量评分 80 × 0.4 = 32\n出勤率 85 × 0.3 = 25.5\n满员率 60 × 0.3 = 18\n\n综合评分 = 32 + 25.5 + 18 = 75.5'
|
||||
}
|
||||
this.formulaVisible = true
|
||||
},
|
||||
|
||||
closeFormula() {
|
||||
this.formulaVisible = false
|
||||
},
|
||||
|
||||
async loadViolations() {
|
||||
this.loadingViolations = true
|
||||
try {
|
||||
@@ -245,6 +361,91 @@
|
||||
color: #1E1E1E;
|
||||
}
|
||||
|
||||
/* 业绩卡片 */
|
||||
.performance-card {
|
||||
background: #FFFFFF;
|
||||
border-radius: 20px;
|
||||
padding: 20px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
||||
}
|
||||
.period-text {
|
||||
font-size: 12px;
|
||||
color: #7A7E84;
|
||||
}
|
||||
.perf-grid {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 14px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.perf-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
.perf-number {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #1E1E1E;
|
||||
}
|
||||
.perf-label {
|
||||
font-size: 11px;
|
||||
color: #7A7E84;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.perf-bar-wrap {
|
||||
width: 40px;
|
||||
height: 3px;
|
||||
background: #EEEEEE;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.perf-bar {
|
||||
height: 100%;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.score-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #F5F7FA;
|
||||
border-radius: 16px;
|
||||
padding: 16px 20px;
|
||||
margin-top: 12px;
|
||||
border-top: none;
|
||||
}
|
||||
.score-label {
|
||||
font-size: 15px;
|
||||
color: #7A7E84;
|
||||
font-weight: 500;
|
||||
}
|
||||
.score-badge {
|
||||
font-size: 38px;
|
||||
font-weight: 800;
|
||||
background: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
padding: 4px 18px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
||||
}
|
||||
.score-badge.score-great {
|
||||
color: #00C853;
|
||||
background: #E8F5E9;
|
||||
}
|
||||
.score-badge.score-good {
|
||||
color: #FF9800;
|
||||
background: #FFF3E0;
|
||||
}
|
||||
.score-badge.score-low {
|
||||
color: #F44336;
|
||||
background: #FFEBEE;
|
||||
}
|
||||
.score-icon {
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
/* 违规统计 */
|
||||
.stats-card {
|
||||
background: #1A1A1A;
|
||||
@@ -323,6 +524,81 @@
|
||||
color: #7A7E84;
|
||||
}
|
||||
|
||||
/* 计算方式弹窗 */
|
||||
.formula-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 999;
|
||||
}
|
||||
.formula-dialog {
|
||||
width: 85%;
|
||||
background: #FFFFFF;
|
||||
border-radius: 20px;
|
||||
padding: 24px 20px 20px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
|
||||
}
|
||||
.formula-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.formula-title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #1E1E1E;
|
||||
}
|
||||
.formula-close {
|
||||
font-size: 20px;
|
||||
color: #7A7E84;
|
||||
padding: 4px;
|
||||
}
|
||||
.formula-body {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.formula-text {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1E1E1E;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.formula-divider {
|
||||
height: 1px;
|
||||
background: #EEEEEE;
|
||||
margin: 14px 0;
|
||||
}
|
||||
.formula-example {
|
||||
font-size: 13px;
|
||||
color: #7A7E84;
|
||||
line-height: 1.7;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.formula-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.formula-btn {
|
||||
width: 100%;
|
||||
height: 44px;
|
||||
background: #00C853;
|
||||
color: #FFFFFF;
|
||||
border-radius: 40px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
}
|
||||
.formula-btn::after { border: none; }
|
||||
|
||||
/* 退出登录 */
|
||||
.logout-area {
|
||||
padding: 20px 0;
|
||||
|
||||
Reference in New Issue
Block a user