From 4dc07ebd6cbc9bb71c599648157e4d0b717a8bce Mon Sep 17 00:00:00 2001
From: ltx <1006158920@qq.com>
Date: Fri, 30 Oct 2026 13:07:13 +0800
Subject: [PATCH] =?UTF-8?q?update=EF=BC=9A=E5=88=86=E9=A1=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/match/workbench.js | 6 +
src/views/scoring/screen/index.vue | 25 +++-
src/views/scoring/workbench/index.vue | 188 +++++++++++++-------------
3 files changed, 118 insertions(+), 101 deletions(-)
diff --git a/src/api/match/workbench.js b/src/api/match/workbench.js
index 00f7f88..cb717a5 100644
--- a/src/api/match/workbench.js
+++ b/src/api/match/workbench.js
@@ -7,6 +7,12 @@ export const workbenchSessionsGet = (params) => http.get('/workbench/sessions',
export const workbenchSessionEntriesGet = (sessionId, params = {}, config = {}) =>
http.get(`/workbench/sessions/${sessionId}/entries`, { ...config, params });
+export const workbenchProjectEntriesGet = (eventProjectId, params = {}, config = {}) =>
+ http.get(`/workbench/projects/${eventProjectId}/entries`, { ...config, params });
+
+export const workbenchEntryDetailGet = (sessionEntryId, config = {}) =>
+ http.get(`/workbench/entries/${sessionEntryId}/detail`, config);
+
export const workbenchScreenCastPost = (data) => http.post('/workbench/screencast', data);
export const workbenchScreenCastCurrentGet = (params, config = {}) =>
diff --git a/src/views/scoring/screen/index.vue b/src/views/scoring/screen/index.vue
index 942487f..87c1da6 100644
--- a/src/views/scoring/screen/index.vue
+++ b/src/views/scoring/screen/index.vue
@@ -20,7 +20,7 @@
DQ
- {{ item.label }}{{ item.en }}
{{ animatedValue(`metric:${item.key}`, payload[item.field], item.field === 'deductionFactor' ? 3 : 2) }}
+ {{ item.label }}{{ item.en }}
{{ animatedValue(`metric:${item.key}`, metricDisplayValue(item), item.field === 'deductionFactor' ? 3 : 2) }}
{{ displayKindLabel }}排名
{{ displayKind === 'team' ? 'TEAM RANKING' : 'INDIVIDUAL RANKING' }}共 {{ rankingTotal }} 个{{ displayKind === 'team' ? '队伍' : '参赛者' }} · 第 {{ rankingPageIndex + 1 }}/{{ rankingPageCount }} 页
@@ -58,7 +58,17 @@ function unwrapApiData(response){let value=response;for(let i=0;i<3&&value&&type
function normalizeCast(value){const normalized=normalizePayload(value),castType=Number(normalized?.castType);return normalized&&(castType===1||castType===2)&&normalized.payloadJson!=null?{...normalized,castType}:null}
function cacheKey(scope=venueId){return `yd-event-screen-cast:${eventId}:${scope??'all'}`}
function readCachedCast(){try{const scoped=localStorage.getItem(cacheKey()),fallback=localStorage.getItem(cacheKey(null));const cached=normalizeCast(JSON.parse(scoped||fallback||'null'));return cached&&Date.now()-Number(cached.cachedAt||0)<30000?cached:null}catch{return null}}
-function acceptPublishedCast(value){const next=normalizeCast(value);if(next){cast.value=next;offline.value=false;rankPage.value=0}else cast.value=null}
+function castIdentity(value){const id=value?.screenCastId||value?.castTime;return id==null?null:String(id)}
+function acceptPublishedCast(value){
+ const next=normalizeCast(value);
+ if(!next){cast.value=null;rankPage.value=0;return}
+ offline.value=false;
+ // 同一次投屏的轮询回包不替换画面,也不重播成绩动画或重置排名页码。
+ const sameCast=cast.value&&castIdentity(cast.value)&&castIdentity(cast.value)===castIdentity(next)&&cast.value.castType===next.castType;
+ if(sameCast)return;
+ cast.value=next;
+ rankPage.value=0;
+}
function localPreviewCast(){
const common={screenCastId:'local-screen-preview',eventName:'2026 跃动跳绳公开赛',projectName:'个人花样',groupName:'青年组',sessionNo:'1',venueName:'主赛场 A',scoreRuleCode:'FREESTYLE_SINGLE',displayKind:'individual'};
if(route.query.preview==='ranking')return {...common,castType:2,payloadJson:JSON.stringify([
@@ -92,6 +102,13 @@ const scoreCards=computed(()=>{
return [{key:'difficulty',label:'难度得分',en:'DIFFICULTY SCORE',field:'difficultyScore'},{key:'performance',label:prescribed?'创意编排分':factor?'表现系数':'表现',en:prescribed?'CREATIVE COMPOSITION':factor?'PERFORMANCE FACTOR':'PERFORMANCE SCORE',field:'performanceScore'},{key:'required',label:prescribed?'完成质量分':factor?'规定系数':'规定',en:prescribed?'EXECUTION QUALITY':factor?'REQUIRED FACTOR':'REQUIRED SCORE',field:'requiredScore'},{key:'deduction',label:factor?'扣分系数':'扣分',en:factor?'DEDUCTION FACTOR':'DEDUCTIONS',field:payload.value.deductionFactor!=null?'deductionFactor':'deductionScore'}]
.filter(item=>(item.key!=='difficulty'||!prescribed)&&(item.key!=='required'||!wire));
});
+// 表现原值 P 参与既有总分计算;大屏只把系数类项目的展示值转换为 1+P。
+function metricDisplayValue(item){
+ const raw=payload.value[item.field];
+ if(item.key!=='performance'||!isFactorRule(effectiveCast.value?.scoreRuleCode)||raw===null||raw===undefined||raw==='')return raw;
+ const value=Number(raw);
+ return Number.isFinite(value)?value+1:raw;
+}
const rankingAll=computed(()=>Array.isArray(payload.value)?payload.value:[]),rankingTotal=computed(()=>rankingAll.value.length),rankingPageCount=computed(()=>Math.max(1,Math.ceil(rankingTotal.value/6))),rankingPageIndex=computed(()=>rankPage.value%rankingPageCount.value),rankingRows=computed(()=>rankingAll.value.slice(rankingPageIndex.value*6,rankingPageIndex.value*6+6)),maxRankScore=computed(()=>Math.max(...rankingAll.value.map(row=>Number(row.totalScore??row.score)||0),1));
function displayName(row){return displayKind.value==='team'?(row.teamName||row.participantName||'未命名队伍'):(row.participantName||row.teamName||'未命名选手')}
function displaySubName(row){if(displayKind.value==='team')return row.unitName||'';return row.teamName&&row.teamName!==displayName(row)?row.teamName:(row.unitName||'')}
@@ -105,7 +122,7 @@ function animateScoreNumbers(){
const targets={};
if(viewType.value==='score'){
targets.hero=payload.value.totalScore??payload.value.score;
- for(const item of scoreCards.value)targets[`metric:${item.key}`]=payload.value[item.field];
+ for(const item of scoreCards.value)targets[`metric:${item.key}`]=metricDisplayValue(item);
}else{
rankingRows.value.forEach((row,index)=>{targets[rankAnimationKey(row,index)]=row.totalScore??row.score});
}
@@ -133,7 +150,7 @@ async function loadCast(){if(!eventId||castRequesting)return;castRequesting=true
function onViewportResize(){viewport.value={width:window.innerWidth,height:window.innerHeight}}
function onThemeStorage(event){if(event.key===scoreScreenThemeKey(eventId)||event.key===null)scoreTheme.value=readScoreScreenTheme(eventId)}
watch([castKey,rankingPageIndex],()=>nextTick(animateScoreNumbers),{immediate:true,flush:'post'});
-onMounted(()=>{storesTagsViewRoutes.setCurrenFullscreen(true);if(isLocalPreview)acceptPublishedCast(localPreviewCast());else{acceptPublishedCast(readCachedCast());if('BroadcastChannel' in window){castChannel=new BroadcastChannel(`yd-event-score-screen-${eventId}`);castChannel.onmessage=event=>acceptPublishedCast(event.data)}loadCast();pollTimer=window.setInterval(()=>document.visibilityState==='visible'&&loadCast(),3000);rankTimer=window.setInterval(()=>rankPage.value++,9000)}if('BroadcastChannel' in window){themeChannel=new BroadcastChannel(scoreScreenThemeChannel(eventId));themeChannel.onmessage=event=>{scoreTheme.value=normalizeScoreScreenTheme(event.data)}}window.addEventListener('storage',onThemeStorage);window.addEventListener('resize',onViewportResize);onViewportResize()});
+onMounted(()=>{storesTagsViewRoutes.setCurrenFullscreen(true);if(isLocalPreview)acceptPublishedCast(localPreviewCast());else{acceptPublishedCast(readCachedCast());if('BroadcastChannel' in window){castChannel=new BroadcastChannel(`yd-event-score-screen-${eventId}`);castChannel.onmessage=event=>acceptPublishedCast(event.data)}loadCast();pollTimer=window.setInterval(()=>document.visibilityState==='visible'&&loadCast(),3000);rankTimer=window.setInterval(()=>{if(document.visibilityState==='visible'&&viewType.value==='ranking'&&rankingPageCount.value>1)rankPage.value=(rankPage.value+1)%rankingPageCount.value},9000)}if('BroadcastChannel' in window){themeChannel=new BroadcastChannel(scoreScreenThemeChannel(eventId));themeChannel.onmessage=event=>{scoreTheme.value=normalizeScoreScreenTheme(event.data)}}window.addEventListener('storage',onThemeStorage);window.addEventListener('resize',onViewportResize);onViewportResize()});
onBeforeUnmount(()=>{window.clearInterval(pollTimer);window.clearInterval(rankTimer);window.cancelAnimationFrame(numberAnimationFrame);castChannel?.close();themeChannel?.close();window.removeEventListener('storage',onThemeStorage);window.removeEventListener('resize',onViewportResize)});
diff --git a/src/views/scoring/workbench/index.vue b/src/views/scoring/workbench/index.vue
index 6603bee..ba0148b 100644
--- a/src/views/scoring/workbench/index.vue
+++ b/src/views/scoring/workbench/index.vue
@@ -40,12 +40,11 @@
{{ entries.length }}当前列表
-
loadEntries()" /> loadEntries()"> loadEntries()">查询重置
+
查询重置
投出排名
- 批量确认({{ selectedResultIds.length }})
- 成绩导出
+ 成绩导出
@@ -53,14 +52,13 @@
LIVE当前正在展示:{{ currentCastSummary }}{{ formatTime(currentCast.castTime) }}
查看大屏撤回投屏
-
-
+
{{ rowSessionDisplay(row) }}
{{ row._session?.venueName || '—' }}
{{ row.groupName || row._session?.groupName || '混合组别' }}
{{ row.teamName || row.participantName }}{{ row.entryNo }}
{{ row.unitName || row.teamName || '—' }}
- {{ submittedCount(row) }}/{{ row.judgeScores?.length || 0 }}
+ {{ submittedCount(row) }}/{{ row.judgeScores?.length || 0 }}待重新提交
{{ score(row.result?.difficultyScore) }}
{{ score(row.result?.performanceScore) }}
{{ score(row.result?.requiredScore) }}
@@ -68,10 +66,15 @@
{{ row.result?.isDisqualified ? 'DQ' : score(row.result?.totalScore ?? row.result?.scoreText) }}
{{ row.result.resultStatusName }}计算中
- 投出{{ castEntityLabel }}成绩评分详情
- 确认成绩投出成绩等待成绩详情 handleRowCommand(command, row)">更多发起成绩修正安排重赛导出本场评分单
+ 投出{{ castEntityLabel }}成绩评分详情
+ 确认成绩投出成绩等待成绩详情 handleRowCommand(command, row)">更多发起成绩修正安排重赛导出本场评分单
+
@@ -87,7 +90,7 @@
-
+
{{ detailAggregateText(group.key) }}
@@ -99,7 +102,7 @@
- 裁判席位{{ judgeColumnLabel(selectedJudgeSheet) }}
裁判姓名{{ selectedJudgeSheet.judgeName || '—' }}
评分单状态{{ selectedJudgeSheet.sheetStatusName || '—' }}查看提交的计分板
+ 裁判席位{{ judgeColumnLabel(selectedJudgeSheet) }}
裁判姓名{{ selectedJudgeSheet.judgeName || '—' }}
评分单状态{{ selectedJudgeSheet.requiresResubmission ? '待重新提交(以下为原评分)' : selectedJudgeSheet.sheetStatusName || '—' }}查看提交的计分板
{{ section.title }}{{ section.items.length }} 项
@@ -125,7 +128,7 @@
恢复默认完成
- 取消{{ reasonAction === 'rematch' ? '确认重赛' : '确认作废' }}
+ 取消确认重赛
取消发送修正任务
@@ -133,17 +136,17 @@