This commit is contained in:
@@ -149,10 +149,8 @@ class Project(models.Model):
|
|||||||
计算项目得分
|
计算项目得分
|
||||||
计算公式:
|
计算公式:
|
||||||
1. 获取所有评委对该项目的打分
|
1. 获取所有评委对该项目的打分
|
||||||
2. 按维度加权平均
|
2. 每个评委的得分 = sum(维度分数 × 维度权重)
|
||||||
这里简化处理:
|
3. 项目最终得分 = 所有评委得分的平均值
|
||||||
总分 = (所有评委的总加权分之和) / 评委人数
|
|
||||||
其中每个评委对项目的打分 = sum(维度分 * 维度权重)
|
|
||||||
"""
|
"""
|
||||||
# 获取所有评分
|
# 获取所有评分
|
||||||
scores = self.scores.all()
|
scores = self.scores.all()
|
||||||
@@ -171,16 +169,9 @@ class Project(models.Model):
|
|||||||
# 获取该评委对该项目的所有维度打分
|
# 获取该评委对该项目的所有维度打分
|
||||||
judge_scores = scores.filter(judge=judge)
|
judge_scores = scores.filter(judge=judge)
|
||||||
|
|
||||||
current_judge_total_score = 0
|
|
||||||
current_judge_total_weight = 0
|
|
||||||
|
|
||||||
for score in judge_scores:
|
for score in judge_scores:
|
||||||
current_judge_total_score += score.score * score.dimension.weight
|
# 直接用原始分数乘以权重相加
|
||||||
current_judge_total_weight += score.dimension.weight
|
judge_score += score.score * score.dimension.weight
|
||||||
|
|
||||||
if current_judge_total_weight > 0:
|
|
||||||
judge_score = current_judge_total_score / current_judge_total_weight
|
|
||||||
# 如果是百分制,这里算出来就是0-100
|
|
||||||
|
|
||||||
total_weighted_score += judge_score
|
total_weighted_score += judge_score
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,14 @@
|
|||||||
<!-- Dimensions loaded via JS -->
|
<!-- Dimensions loaded via JS -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="totalScoreDisplay" class="mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200">
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-sm font-medium text-blue-800">综合得分</span>
|
||||||
|
<span id="totalScoreValue" class="text-2xl font-bold text-blue-600">0</span>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-blue-500 mt-1">各维度分数×权重相加,提交后计算所有评委平均值</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label for="comment" class="block text-sm font-medium text-gray-700">评语建议</label>
|
<label for="comment" class="block text-sm font-medium text-gray-700">评语建议</label>
|
||||||
<textarea id="comment" name="comment" rows="4"
|
<textarea id="comment" name="comment" rows="4"
|
||||||
@@ -297,6 +305,46 @@
|
|||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
<script src="https://cdn.staticfile.net/marked/11.1.1/marked.min.js"></script>
|
<script src="https://cdn.staticfile.net/marked/11.1.1/marked.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 更新单个维度分数显示并计算总分
|
||||||
|
*/
|
||||||
|
function updateDimensionScore(dimensionId, maxScore, weight, value) {
|
||||||
|
// 更新分数显示
|
||||||
|
document.getElementById('score_val_' + dimensionId).innerText = value;
|
||||||
|
// 重新计算总分
|
||||||
|
calculateTotalScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算评委的综合得分
|
||||||
|
* 公式:直接用原始分数乘以权重相加 (与后端逻辑一致)
|
||||||
|
*/
|
||||||
|
function calculateTotalScore() {
|
||||||
|
const dimensionsContainer = document.getElementById('scoreDimensions');
|
||||||
|
const dimensionDivs = dimensionsContainer.querySelectorAll('[data-dimension-id]');
|
||||||
|
|
||||||
|
let totalScore = 0;
|
||||||
|
|
||||||
|
dimensionDivs.forEach(div => {
|
||||||
|
const weight = parseFloat(div.dataset.weight);
|
||||||
|
const dimensionId = div.dataset.dimensionId;
|
||||||
|
|
||||||
|
// 获取当前分数
|
||||||
|
const scoreInput = document.querySelector('input[name="score_' + dimensionId + '"]');
|
||||||
|
if (scoreInput) {
|
||||||
|
const score = parseFloat(scoreInput.value) || 0;
|
||||||
|
// 直接用原始分数乘以权重相加
|
||||||
|
totalScore += score * weight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新显示
|
||||||
|
const totalScoreElement = document.getElementById('totalScoreValue');
|
||||||
|
if (totalScoreElement) {
|
||||||
|
totalScoreElement.innerText = totalScore.toFixed(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换 AI 总结内容的显示状态(折叠/展开)
|
* 切换 AI 总结内容的显示状态(折叠/展开)
|
||||||
* 通过添加或移除 line-clamp-5 类来实现截断或完整显示,并更新按钮的文字和图标。
|
* 通过添加或移除 line-clamp-5 类来实现截断或完整显示,并更新按钮的文字和图标。
|
||||||
@@ -555,14 +603,14 @@ async function viewProject(id) {
|
|||||||
|
|
||||||
// Render Score Inputs
|
// Render Score Inputs
|
||||||
const dimensionsHtml = data.dimensions.map(d => `
|
const dimensionsHtml = data.dimensions.map(d => `
|
||||||
<div class="bg-white p-3 rounded-lg border border-gray-200">
|
<div class="bg-white p-3 rounded-lg border border-gray-200" data-dimension-id="${d.id}" data-max-score="${d.max_score}" data-weight="${d.weight}">
|
||||||
<div class="flex justify-between items-center mb-2">
|
<div class="flex justify-between items-center mb-2">
|
||||||
<label class="text-sm font-medium text-gray-700">${d.name}</label>
|
<label class="text-sm font-medium text-gray-700">${d.name}</label>
|
||||||
<span class="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded">权重: ${d.weight}</span>
|
<span class="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded">满分: ${d.max_score} | 权重: ${d.weight}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<input type="range" min="0" max="${d.max_score}" step="1" value="${d.current_score || 0}"
|
<input type="range" min="0" max="${d.max_score}" step="1" value="${d.current_score || 0}"
|
||||||
oninput="document.getElementById('score_val_${d.id}').innerText = this.value"
|
oninput="updateDimensionScore('${d.id}', '${d.max_score}', '${d.weight}', this.value)"
|
||||||
name="score_${d.id}" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-600">
|
name="score_${d.id}" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-600">
|
||||||
<div class="w-12 text-right">
|
<div class="w-12 text-right">
|
||||||
<span id="score_val_${d.id}" class="text-lg font-bold text-blue-600">${d.current_score || 0}</span>
|
<span id="score_val_${d.id}" class="text-lg font-bold text-blue-600">${d.current_score || 0}</span>
|
||||||
@@ -573,6 +621,9 @@ async function viewProject(id) {
|
|||||||
`).join('');
|
`).join('');
|
||||||
document.getElementById('scoreDimensions').innerHTML = dimensionsHtml;
|
document.getElementById('scoreDimensions').innerHTML = dimensionsHtml;
|
||||||
|
|
||||||
|
// 计算初始总分
|
||||||
|
calculateTotalScore();
|
||||||
|
|
||||||
document.getElementById('comment').value = data.current_comment || '';
|
document.getElementById('comment').value = data.current_comment || '';
|
||||||
|
|
||||||
// Handle Grading Permission
|
// Handle Grading Permission
|
||||||
|
|||||||
@@ -119,16 +119,16 @@ if DB_HOST:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# DB_HOST = os.environ.get('DB_HOST', '121.43.104.161')
|
DB_HOST = os.environ.get('DB_HOST', '121.43.104.161')
|
||||||
# if DB_HOST:
|
if DB_HOST:
|
||||||
# DATABASES['default'] = {
|
DATABASES['default'] = {
|
||||||
# 'ENGINE': 'django.db.backends.postgresql',
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
# 'NAME': os.environ.get('DB_NAME', 'market'),
|
'NAME': os.environ.get('DB_NAME', 'market'),
|
||||||
# 'USER': os.environ.get('DB_USER', 'market'),
|
'USER': os.environ.get('DB_USER', 'market'),
|
||||||
# 'PASSWORD': os.environ.get('DB_PASSWORD', '123market'),
|
'PASSWORD': os.environ.get('DB_PASSWORD', '123market'),
|
||||||
# 'HOST': DB_HOST,
|
'HOST': DB_HOST,
|
||||||
# 'PORT': os.environ.get('DB_PORT', '6433'),
|
'PORT': os.environ.get('DB_PORT', '6433'),
|
||||||
# }
|
}
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
|
|||||||
Reference in New Issue
Block a user