解决题目数量无法整除总分时出现无限小数的问题 后端: - 新增 ScoreDistributor 分数分配工具类 - 支持整数分配和小数分配两种模式 - 更新 exam_service.py 使用智能分配 - 考试总分固定100分,按题目数量智能分配 前端: - 新增 scoreFormatter.ts 分数格式化工具 - 提供分数显示、等级判断等辅助函数 示例:100分/6题 = [17,17,17,17,16,16] 总和=100
This commit is contained in:
@@ -49,9 +49,7 @@ export interface DepartmentData {
|
||||
pass_rate: number
|
||||
avg_hours: number
|
||||
avg_level: number
|
||||
}
|
||||
|
||||
// 学习趋势
|
||||
}// 学习趋势
|
||||
export interface TrendData {
|
||||
dates: string[]
|
||||
trend: Array<{
|
||||
@@ -175,4 +173,4 @@ export function getTeamDashboard() {
|
||||
*/
|
||||
export function getFullDashboardData() {
|
||||
return request.get<FullDashboardData>('/dashboard/all')
|
||||
}
|
||||
}
|
||||
|
||||
154
frontend/src/utils/scoreFormatter.ts
Normal file
154
frontend/src/utils/scoreFormatter.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* 分数格式化工具
|
||||
*
|
||||
* 用于在前端显示分数时进行格式化,避免显示过长的小数
|
||||
*/
|
||||
|
||||
/**
|
||||
* 格式化分数显示
|
||||
*
|
||||
* @param score 分数
|
||||
* @param decimalPlaces 小数位数,默认1位
|
||||
* @returns 格式化后的分数字符串
|
||||
*
|
||||
* @example
|
||||
* formatScore(16.666666) // "16.7"
|
||||
* formatScore(17) // "17"
|
||||
* formatScore(16.5, 0) // "17"
|
||||
*/
|
||||
export function formatScore(score: number, decimalPlaces: number = 1): string {
|
||||
// 如果是整数,直接返回
|
||||
if (Number.isInteger(score)) {
|
||||
return score.toString()
|
||||
}
|
||||
|
||||
// 四舍五入到指定小数位
|
||||
const rounded = Number(score.toFixed(decimalPlaces))
|
||||
|
||||
// 如果四舍五入后是整数,去掉小数点
|
||||
if (Number.isInteger(rounded)) {
|
||||
return rounded.toString()
|
||||
}
|
||||
|
||||
return rounded.toFixed(decimalPlaces)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化分数显示(带单位)
|
||||
*
|
||||
* @param score 分数
|
||||
* @param unit 单位,默认"分"
|
||||
* @returns 格式化后的分数字符串
|
||||
*
|
||||
* @example
|
||||
* formatScoreWithUnit(16.7) // "16.7分"
|
||||
* formatScoreWithUnit(100) // "100分"
|
||||
*/
|
||||
export function formatScoreWithUnit(score: number, unit: string = '分'): string {
|
||||
return `${formatScore(score)}${unit}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化百分比
|
||||
*
|
||||
* @param value 值(0-1 或 0-100)
|
||||
* @param isPercent 是否已经是百分比形式(0-100),默认false
|
||||
* @returns 格式化后的百分比字符串
|
||||
*
|
||||
* @example
|
||||
* formatPercent(0.8567) // "85.7%"
|
||||
* formatPercent(85.67, true) // "85.7%"
|
||||
*/
|
||||
export function formatPercent(value: number, isPercent: boolean = false): string {
|
||||
const percent = isPercent ? value : value * 100
|
||||
return `${formatScore(percent)}%`
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算及格分数
|
||||
*
|
||||
* @param totalScore 总分
|
||||
* @param passRate 及格率,默认0.6
|
||||
* @returns 及格分数(向上取整)
|
||||
*/
|
||||
export function calculatePassScore(totalScore: number, passRate: number = 0.6): number {
|
||||
return Math.ceil(totalScore * passRate)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否及格
|
||||
*
|
||||
* @param score 得分
|
||||
* @param passScore 及格分数
|
||||
* @returns 是否及格
|
||||
*/
|
||||
export function isPassed(score: number, passScore: number): boolean {
|
||||
return score >= passScore
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分数等级
|
||||
*
|
||||
* @param score 得分
|
||||
* @param totalScore 总分
|
||||
* @returns 等级: 'excellent' | 'good' | 'pass' | 'fail'
|
||||
*/
|
||||
export function getScoreLevel(score: number, totalScore: number): 'excellent' | 'good' | 'pass' | 'fail' {
|
||||
const ratio = score / totalScore
|
||||
|
||||
if (ratio >= 0.9) return 'excellent'
|
||||
if (ratio >= 0.75) return 'good'
|
||||
if (ratio >= 0.6) return 'pass'
|
||||
return 'fail'
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分数等级对应的颜色
|
||||
*
|
||||
* @param level 等级
|
||||
* @returns 颜色值
|
||||
*/
|
||||
export function getScoreLevelColor(level: 'excellent' | 'good' | 'pass' | 'fail'): string {
|
||||
const colors = {
|
||||
excellent: '#67c23a', // 绿色
|
||||
good: '#409eff', // 蓝色
|
||||
pass: '#e6a23c', // 橙色
|
||||
fail: '#f56c6c', // 红色
|
||||
}
|
||||
return colors[level]
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能分配分数(前端预览用)
|
||||
*
|
||||
* @param totalScore 总分
|
||||
* @param questionCount 题目数量
|
||||
* @returns 分数数组
|
||||
*
|
||||
* @example
|
||||
* distributeScores(100, 6) // [17, 17, 17, 17, 16, 16]
|
||||
*/
|
||||
export function distributeScores(totalScore: number, questionCount: number): number[] {
|
||||
if (questionCount <= 0) return []
|
||||
|
||||
const baseScore = Math.floor(totalScore / questionCount)
|
||||
const extraCount = totalScore % questionCount
|
||||
|
||||
const scores: number[] = []
|
||||
for (let i = 0; i < questionCount; i++) {
|
||||
scores.push(i < extraCount ? baseScore + 1 : baseScore)
|
||||
}
|
||||
|
||||
return scores
|
||||
}
|
||||
|
||||
export default {
|
||||
formatScore,
|
||||
formatScoreWithUnit,
|
||||
formatPercent,
|
||||
calculatePassScore,
|
||||
isPassed,
|
||||
getScoreLevel,
|
||||
getScoreLevelColor,
|
||||
distributeScores,
|
||||
}
|
||||
Reference in New Issue
Block a user