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' ? '队伍' : '参赛者' }}
@@ -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 }}当前列表
-
查询重置
+
查询重置
投出排名
@@ -53,14 +52,13 @@ LIVE
当前正在展示:{{ currentCastSummary }}{{ formatTime(currentCast.castTime) }}
查看大屏撤回投屏 -
- +
- + @@ -68,10 +66,15 @@
+
+ 共 {{ entryTotal }} 条 · 每页 + +
上一页下一页
跳至页跳转
+
@@ -87,7 +90,7 @@ - + @@ -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 @@ - +
@@ -133,17 +136,17 @@