Compare commits

...

2 Commits

Author SHA1 Message Date
2c139575f2 个人花样计算逻辑调整 2026-10-08 15:55:11 +08:00
5350bb42b8 秩序册导入流程优化 2026-10-08 10:12:45 +08:00
4 changed files with 14 additions and 17 deletions

View File

@ -155,7 +155,7 @@ const loadEventOptions = async () => {
if (!(data.units || []).length) scheduleError.value = '当前赛事秩序册没有可检录列';
} catch (error) {
assignedCheckinNumbers.value = [];
scheduleError.value = '请先在当前赛事的秩序册管理中完成赛事编排,再添加检录员';
scheduleError.value = '请先完成赛事编排或确认导入秩序册,再添加检录员';
}
};

View File

@ -38,7 +38,7 @@ function selectFile(uploadFile){file.value=uploadFile.raw;result.value=null}
function saveBlob(blob,name){const url=URL.createObjectURL(blob);const a=document.createElement('a');a.href=url;a.download=name;document.body.appendChild(a);a.click();a.remove();URL.revokeObjectURL(url)}
async function downloadTemplate(){saveBlob(await orderBookTemplateGet(),'秩序册导入模板.xlsx')}
async function parseFile(){parsing.value=true;try{const res=await orderBookImportPost(eventId.value,file.value);result.value=res?.data||null;if(result.value)ElMessage.success(result.value.errorCount?'解析完成,请处理错误项':'解析通过,请确认导入')}finally{parsing.value=false}}
async function confirmImport(){await ElMessageBox.confirm('确认导入当前秩序册?同一赛事原有编排数据将按导入规则处理。','确认导入',{type:'warning'});confirming.value=true;try{const res=await orderBookConfirmPost(result.value.batchId);ElMessage.success(`导入完成:${res?.data?.entryCount||0} 条出场记录`);result.value=null;file.value=null}finally{confirming.value=false}}
async function confirmImport(){await ElMessageBox.confirm('确认导入当前秩序册?本次导入将覆盖原有编排,并清除旧场次的裁判分配;导入后可直接配置检录员。','确认导入',{type:'warning'});confirming.value=true;try{const res=await orderBookConfirmPost(result.value.batchId);ElMessage.success(`导入完成:${res?.data?.entryCount||0} 条出场记录`);result.value=null;file.value=null}finally{confirming.value=false}}
</script>
<style scoped lang="scss">

View File

@ -15,8 +15,7 @@ export function judgeScoreText(sheet, ruleCode) {
if (!isFactorRule(ruleCode)) return fixedScore(sheet.totalScore);
const role = String(sheet.judgeRoleType || '').toUpperCase();
if (role === 'T') {
if (sheet.deductionScore == null) return '—';
return fixedScore(Math.max(0, 1 - Number(sheet.deductionScore)), 3);
return fixedScore(sheet.deductionScore, 3);
}
if (role === 'P') return fixedScore(sheet.performanceScore);
if (role.startsWith('D')) return fixedScore(sheet.difficultyScore);
@ -31,12 +30,14 @@ export function calculationSummary(json) {
if (!factors) return '';
const lines = [`公式:${data.formula};D=${fixedScore(factors.d)},P=${fixedScore(factors.p)},Q=${fixedScore(factors.q)},M=${fixedScore(factors.m, 3)}`];
const failure = data.failureAggregation;
if (failure?.performanceAverageFailureCount != null) {
lines.push(`失误:表现裁判 [${failure.performanceFailureCounts.join('、')}],平均 ${failure.performanceAverageFailureCount};主裁 ${failure.chiefFailureCount};合计 ${failure.combinedFailureCount} → ${failure.roundedFailureCount} 次;失误扣分 ${fixedScore(failure.failureDeduction, 3)},其他扣分 ${fixedScore(failure.otherDeduction, 3)}`);
if (failure?.finalAverageFailureCount != null) {
lines.push(`失误:表现裁判 [${failure.performanceFailureCounts.join('、')}],主裁 ${failure.chiefFailureCount};合计 ${failure.combinedFailureCount} ÷ ${failure.totalJudgeCount} 人 = ${failure.finalAverageFailureCount} → ${failure.roundedFailureCount} 次;失误扣分 ${fixedScore(failure.failureDeduction, 3)},其他扣分 ${fixedScore(failure.otherDeduction, 3)}`);
} else if (failure?.performanceAverageFailureCount != null) {
lines.push(`失误(历史口径):表现裁判 [${failure.performanceFailureCounts.join('、')}] 平均 ${failure.performanceAverageFailureCount};主裁 ${failure.chiefFailureCount};合并 ${failure.combinedFailureCount} → ${failure.roundedFailureCount} 次;失误扣分 ${fixedScore(failure.failureDeduction, 3)},其他扣分 ${fixedScore(failure.otherDeduction, 3)}`);
} else if (failure) {
lines.push(`失误(历史口径):表现裁判 [${failure.performanceFailureCounts.join('、')}],主裁 ${failure.chiefFailureCount};平均 ${failure.averageFailureCount} → ${failure.roundedFailureCount} 次;失误扣分 ${fixedScore(failure.failureDeduction, 3)},其他扣分 ${fixedScore(failure.otherDeduction, 3)}`);
}
lines.push(data.calculationVersion ? '按 BUG-71:因子先舍入,再计算总分。' : '历史计算快照:可能尚未按新规则重算。');
lines.push(data.calculationVersion ? '因子按快照版本规则舍入后计算总分。' : '历史计算快照:可能尚未按新规则重算。');
return lines.join('\n');
} catch { return ''; }
}

View File

@ -61,14 +61,10 @@
</el-table-column>
</el-table-column>
<el-table-column label="裁判提交" width="92" align="center"><template #default="{ row }"><span :class="['submit-progress', { done: allSubmitted(row) }]">{{ submittedCount(row) }}/{{ row.judgeScores?.length || 0 }}</span></template></el-table-column>
<el-table-column v-if="showDifficulty" label="难度分(得分)" min-width="116" align="center"><template #default="{ row }">{{ score(row.result?.difficultyScore) }}</template></el-table-column>
<el-table-column :label="performanceScoreLabel" min-width="100" align="center"><template #default="{ row }">{{ score(row.result?.performanceScore) }}</template></el-table-column>
<el-table-column :label="requiredScoreLabel" min-width="100" align="center"><template #default="{ row }">{{ score(row.result?.requiredScore) }}</template></el-table-column>
<el-table-column :label="deductionScoreLabel" min-width="100" align="center"><template #default="{ row }">{{ score(row.result?.deductionScore) }}</template></el-table-column>
<el-table-column v-if="showDifficulty" label="难度分" width="88" align="center"><template #default="{ row }">{{ score(row.result?.difficultyScore) }}</template></el-table-column>
<el-table-column :label="showFactorScores ? '表现系数 P' : '表现分'" width="110" align="center"><template #default="{ row }">{{ score(row.result?.performanceScore) }}</template></el-table-column>
<el-table-column :label="showFactorScores ? '规定系数 Q' : '规定分'" width="110" align="center"><template #default="{ row }">{{ score(row.result?.requiredScore) }}</template></el-table-column>
<el-table-column :label="showFactorScores ? '得分系数 M' : '扣分'" width="110" align="center"><template #default="{ row }">{{ isFactorRule(row._session?.scoreRuleCode) ? fixedScore(row.result?.deductionFactor, 3) : score(row.result?.deductionScore) }}</template></el-table-column>
<el-table-column v-if="showDifficulty" label="难度分 D" min-width="100" align="center"><template #default="{ row }">{{ score(row.result?.difficultyScore) }}</template></el-table-column>
<el-table-column :label="showFactorScores ? '表现系数 P' : performanceScoreLabel" min-width="110" align="center"><template #default="{ row }">{{ score(row.result?.performanceScore) }}</template></el-table-column>
<el-table-column :label="showFactorScores ? '规定系数 Q' : requiredScoreLabel" min-width="110" align="center"><template #default="{ row }">{{ score(row.result?.requiredScore) }}</template></el-table-column>
<el-table-column :label="showFactorScores ? '得分系数 M' : deductionScoreLabel" min-width="110" align="center"><template #default="{ row }">{{ isFactorRule(row._session?.scoreRuleCode) ? fixedScore(row.result?.deductionFactor, 3) : score(row.result?.deductionScore) }}</template></el-table-column>
<el-table-column label="总分" width="96" align="center"><template #default="{ row }"><b class="total" :class="{ dq: row.result?.isDisqualified }">{{ row.result?.isDisqualified ? 'DQ' : score(row.result?.totalScore ?? row.result?.scoreText) }}</b></template></el-table-column>
<el-table-column label="排名" width="72" align="center"><template #default="{ row }"><span v-if="row.result?.rank" :class="['rank-number', `rank-${row.result.rank}`]">{{ row.result.rank }}</span><span v-else class="muted">—</span></template></el-table-column>
<el-table-column label="状态" width="96" fixed="right" align="center"><template #default="{ row }"><el-tag v-if="row.result" :type="resultTag(row.result.resultStatus)" effect="light">{{ row.result.resultStatusName }}</el-tag><span v-else class="muted">计算中</span></template></el-table-column>
@ -200,7 +196,7 @@ const detailJudgeGroups=computed(()=>{
{key:'difficulty',label:'难度分(得分)',summaryLabel:'得分'},
{key:'performance',label:prescribed?'创意编排分':'表现分(系数)',summaryLabel:'得分'},
{key:'required',label:prescribed?'完成质量分':'规定(系数)',summaryLabel:'得分'},
{key:'deduction',label:prescribed?'扣分':'扣分(系数)',summaryLabel:'合计'},
{key:'deduction',label:prescribed?'扣分':'扣分明细',summaryLabel:prescribed?'合计':'综合扣分'},
];
const result=groups.filter(group=>group.key!=='difficulty'||!prescribed).map(group=>({...group,judges:sheets.filter(sheet=>judgeGroupKey(sheet)===group.key)}));
const others=sheets.filter(sheet=>judgeGroupKey(sheet)==='other');
@ -326,7 +322,7 @@ function submittedCount(row){return (row.judgeScores||[]).filter(x=>x.sheetStatu
function hasSubmittedJudgeScores(row){return (row.judgeScores||[]).some(x=>x.scoreSheetId>0&&x.sheetStatus>=10&&x.sheetStatus<90)}
function allSubmitted(row){return !!row.judgeScores?.length&&submittedCount(row)===row.judgeScores.length}
function judgeColumnLabel(sheet){return sheet?.judgeRole||sheet?.judgeRoleName||'裁判'}
function judgeDisplayValue(sheet,groupKey){if(!sheet)return null;if(groupKey==='difficulty')return sheet.difficultyScore;if(groupKey==='performance')return sheet.performanceScore;if(groupKey==='required')return sheet.requiredScore;if(groupKey==='deduction')return detailRow.value?.result?.deductionScore??sheet.deductionScore;return sheet.totalScore}
function judgeDisplayValue(sheet,groupKey){if(!sheet)return null;if(groupKey==='difficulty')return sheet.difficultyScore;if(groupKey==='performance')return sheet.performanceScore;if(groupKey==='required')return sheet.requiredScore;if(groupKey==='deduction')return sheet.deductionScore;return sheet.totalScore}
function detailAggregateScore(groupKey){const result=detailRow.value?.result;if(!result)return null;return ({difficulty:result.difficultyScore,performance:result.performanceScore,required:result.requiredScore,deduction:result.deductionScore,other:null})[groupKey]}
function showJudgeDetail(sheet){if(!sheet||sheet.sheetStatus<10)return;selectedJudgeSheet.value=sheet;judgeDetailVisible.value=true}
async function viewJudgeScoreBoard(){