chore: 支持配置列显示位置
This commit is contained in:
@@ -367,7 +367,17 @@
|
|||||||
"level": 80,
|
"level": 80,
|
||||||
"department": 1,
|
"department": 1,
|
||||||
"bonus": 80
|
"bonus": 80
|
||||||
}
|
},
|
||||||
|
"columnAlignments": {
|
||||||
|
"rank": "center",
|
||||||
|
"avatar": "left",
|
||||||
|
"name": "left",
|
||||||
|
"score": "left",
|
||||||
|
"level": "left",
|
||||||
|
"department": "left",
|
||||||
|
"bonus": "left"
|
||||||
|
},
|
||||||
|
"defaultDisplayRows": 7
|
||||||
},
|
},
|
||||||
"team": {
|
"team": {
|
||||||
"showMemberCount": false,
|
"showMemberCount": false,
|
||||||
@@ -383,7 +393,16 @@
|
|||||||
"memberCount": 60,
|
"memberCount": 60,
|
||||||
"leader": 1,
|
"leader": 1,
|
||||||
"bonus": 80
|
"bonus": 80
|
||||||
}
|
},
|
||||||
|
"columnAlignments": {
|
||||||
|
"rank": "center",
|
||||||
|
"name": "center",
|
||||||
|
"score": "left",
|
||||||
|
"memberCount": "left",
|
||||||
|
"leader": "left",
|
||||||
|
"bonus": "left"
|
||||||
|
},
|
||||||
|
"defaultDisplayRows": 0
|
||||||
},
|
},
|
||||||
"championLogos": {
|
"championLogos": {
|
||||||
"teamChampion": "",
|
"teamChampion": "",
|
||||||
|
|||||||
@@ -90,8 +90,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="config-item">
|
<div class="config-item">
|
||||||
<label class="checkbox-label">
|
<label class="checkbox-label">
|
||||||
<span class="text-gold">移动端最大显示行数:</span>
|
<span class="text-gold">移动端默认显示行数:</span>
|
||||||
<input type="number" v-model.number="localDisplayConfig.individual.maxDisplayRows" min="1" max="50" class="number-input">
|
<input type="number" v-model.number="localDisplayConfig.individual.defaultDisplayRows" min="1" max="50" class="number-input">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="config-item">
|
<div class="config-item">
|
||||||
@@ -111,6 +111,118 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="column-alignment-section">
|
||||||
|
<h4 class="text-gold">列对齐设置</h4>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">排名列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.individual.columnAlignments.rank" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">姓名列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.individual.columnAlignments.name" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">业绩列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.individual.columnAlignments.score" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item" v-if="localDisplayConfig.individual.showLevel">
|
||||||
|
<label class="text-gold">等级列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.individual.columnAlignments.level" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item" v-if="localDisplayConfig.individual.showDepartment">
|
||||||
|
<label class="text-gold">部门列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.individual.columnAlignments.department" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item" v-if="localDisplayConfig.individual.showTeam">
|
||||||
|
<label class="text-gold">战区列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.individual.columnAlignments.team" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">奖金列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.individual.columnAlignments.bonus" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column-alignment-section">
|
||||||
|
<h4 class="text-gold">列对齐设置</h4>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">排名列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.team.columnAlignments.rank" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">战区名列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.team.columnAlignments.name" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">业绩列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.team.columnAlignments.score" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item" v-if="localDisplayConfig.team.showMemberCount">
|
||||||
|
<label class="text-gold">人数列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.team.columnAlignments.memberCount" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item" v-if="localDisplayConfig.team.showLeader">
|
||||||
|
<label class="text-gold">队长列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.team.columnAlignments.leader" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column-alignment-item">
|
||||||
|
<label class="text-gold">奖金列对齐:</label>
|
||||||
|
<select v-model="localDisplayConfig.team.columnAlignments.bonus" class="align-select">
|
||||||
|
<option value="left">靠左</option>
|
||||||
|
<option value="center">居中</option>
|
||||||
|
<option value="right">靠右</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="column-widths-section">
|
<div class="column-widths-section">
|
||||||
<h4 class="text-gold">列宽设置(单位:像素)</h4>
|
<h4 class="text-gold">列宽设置(单位:像素)</h4>
|
||||||
<div class="column-width-item">
|
<div class="column-width-item">
|
||||||
@@ -182,6 +294,12 @@
|
|||||||
<span class="text-gold">显示队长列</span>
|
<span class="text-gold">显示队长列</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="config-item">
|
||||||
|
<label class="checkbox-label">
|
||||||
|
<span class="text-gold">移动端默认显示行数:</span>
|
||||||
|
<input type="number" v-model.number="localDisplayConfig.team.defaultDisplayRows" min="0" max="50" class="number-input" placeholder="留空或0表示显示所有行">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="config-item">
|
<div class="config-item">
|
||||||
<label class="checkbox-label">
|
<label class="checkbox-label">
|
||||||
<span class="text-gold">业绩列显示名称:</span>
|
<span class="text-gold">业绩列显示名称:</span>
|
||||||
@@ -1472,6 +1590,30 @@ const deleteBonusRule = (index) => {
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.column-alignment-section {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 15px;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-alignment-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-select {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #6c5ce7;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #2d3748;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
.column-width-item label {
|
.column-width-item label {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|||||||
@@ -64,25 +64,25 @@
|
|||||||
<h2 class="game-subtitle">👥 战区排名</h2>
|
<h2 class="game-subtitle">👥 战区排名</h2>
|
||||||
<div class="rank-table">
|
<div class="rank-table">
|
||||||
<div class="table-header" :style="{ 'grid-template-columns': teamGridTemplate }">
|
<div class="table-header" :style="{ 'grid-template-columns': teamGridTemplate }">
|
||||||
<span class="rank-col">排名</span>
|
<span class="rank-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.rank || 'left' }">排名</span>
|
||||||
<span class="name-col">战区名称</span>
|
<span class="name-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.name || 'left' }">战区名称</span>
|
||||||
<span class="score-col">{{ localDisplayConfig.team?.totalScoreColumn?.displayName || '业绩' }}</span>
|
<span class="score-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.score || 'left' }">{{ localDisplayConfig.team?.totalScoreColumn?.displayName || '业绩' }}</span>
|
||||||
<span v-if="localDisplayConfig.team?.showMemberCount" class="member-col">人数</span>
|
<span v-if="localDisplayConfig.team?.showMemberCount" class="member-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.memberCount || 'left' }">人数</span>
|
||||||
<span v-if="localDisplayConfig.team?.showLeader" class="leader-col">队长</span>
|
<span v-if="localDisplayConfig.team?.showLeader" class="leader-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.leader || 'left' }">队长</span>
|
||||||
<span v-if="localDisplayConfig.team?.showBonus" class="bonus-col">奖金</span>
|
<span v-if="localDisplayConfig.team?.showBonus" class="bonus-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.bonus || 'left' }">奖金</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="(item, index) in teamRankings" :key="item.id" class="table-row"
|
<div v-for="(item, index) in teamRankings" :key="item.id" class="table-row"
|
||||||
:style="{ 'grid-template-columns': teamGridTemplate }" :class="{
|
:style="{ 'grid-template-columns': teamGridTemplate }" :class="{
|
||||||
'top-three': index < 3,
|
'top-three': index < 3,
|
||||||
'highlight': index === 0
|
'highlight': index === 0
|
||||||
}">
|
}">
|
||||||
<span class="rank-col">{{ index + 1 }}</span>
|
<span class="rank-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.rank || 'left' }">{{ index + 1 }}</span>
|
||||||
<span class="name-col">{{ item.name }}</span>
|
<span class="name-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.name || 'left' }">{{ item.name }}</span>
|
||||||
<span class="score-col">{{ localDisplayConfig.team?.totalScoreColumn?.displayStyle === 'amount' ? '¥' +
|
<span class="score-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.score || 'left' }">{{ localDisplayConfig.team?.totalScoreColumn?.displayStyle === 'amount' ? '¥' +
|
||||||
item.totalScore : item.totalScore }}</span>
|
item.totalScore : item.totalScore }}</span>
|
||||||
<span v-if="localDisplayConfig.team?.showMemberCount" class="member-col">{{ item.memberCount }}人</span>
|
<span v-if="localDisplayConfig.team?.showMemberCount" class="member-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.memberCount || 'left' }">{{ item.memberCount }}人</span>
|
||||||
<span v-if="localDisplayConfig.team?.showLeader" class="leader-col">{{ item.leader }}</span>
|
<span v-if="localDisplayConfig.team?.showLeader" class="leader-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.leader || 'left' }">{{ item.leader }}</span>
|
||||||
<span v-if="localDisplayConfig.team?.showBonus" class="bonus-col">¥{{ item.bonus }}</span>
|
<span v-if="localDisplayConfig.team?.showBonus" class="bonus-col" :style="{ textAlign: localDisplayConfig.team?.columnAlignments?.bonus || 'left' }">¥{{ item.bonus }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -92,56 +92,59 @@
|
|||||||
<div class="individual-rankings">
|
<div class="individual-rankings">
|
||||||
<!-- 英雄冠军 -->
|
<!-- 英雄冠军 -->
|
||||||
<div class="individual-champion">
|
<div class="individual-champion">
|
||||||
<div class="individual-avatar">
|
<div class="individual-avatar champion-container">
|
||||||
<img v-if="individualRankings[0]?.avatar && individualRankings[0].avatar.startsWith('/')"
|
<div class="crown-animation" v-if="individualRankings.length > 0">
|
||||||
:src="individualRankings[0].avatar" alt="冠军头像" class="avatar-image avatar-image-champion"
|
👑
|
||||||
:style="{ width: localDisplayConfig.championLogos?.individualChampionSize + 'px', height: localDisplayConfig.championLogos?.individualChampionSize + 'px' }">
|
</div>
|
||||||
<img v-else-if="localDisplayConfig.championLogos?.individualChampion"
|
<img v-if="individualRankings[0]?.avatar && individualRankings[0].avatar.startsWith('/')"
|
||||||
:src="localDisplayConfig.championLogos.individualChampion" alt="英雄冠军" class="champion-logo"
|
:src="individualRankings[0].avatar" alt="冠军头像" class="avatar-image avatar-image-champion"
|
||||||
:style="{ width: localDisplayConfig.championLogos?.individualChampionSize + 'px', height: localDisplayConfig.championLogos?.individualChampionSize + 'px' }">
|
:style="{ width: localDisplayConfig.championLogos?.individualChampionSize + 'px', height: localDisplayConfig.championLogos?.individualChampionSize + 'px' }">
|
||||||
<span v-else
|
<img v-else-if="localDisplayConfig.championLogos?.individualChampion"
|
||||||
:style="{ fontSize: localDisplayConfig.championLogos?.individualChampionSize ? (localDisplayConfig.championLogos.individualChampionSize * 0.8) + 'px' : '2rem' }">
|
:src="localDisplayConfig.championLogos.individualChampion" alt="英雄冠军" class="champion-logo"
|
||||||
{{ individualRankings[0]?.avatar || '👤' }}
|
:style="{ width: localDisplayConfig.championLogos?.individualChampionSize + 'px', height: localDisplayConfig.championLogos?.individualChampionSize + 'px' }">
|
||||||
</span>
|
<span v-else
|
||||||
|
:style="{ fontSize: localDisplayConfig.championLogos?.individualChampionSize ? (localDisplayConfig.championLogos.individualChampionSize * 0.8) + 'px' : '2rem' }">
|
||||||
|
{{ individualRankings[0]?.avatar || '👤' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="champion-name">
|
||||||
|
{{ individualRankings[0]?.name || '暂无冠军' }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="champion-name">
|
|
||||||
{{ individualRankings[0]?.name || '暂无冠军' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 英雄排名 -->
|
<!-- 英雄排名 -->
|
||||||
<div class="individual-rankings-container">
|
<div class="individual-rankings-container">
|
||||||
<h2 class="game-subtitle">👤 英雄排名</h2>
|
<h2 class="game-subtitle">👤 英雄排名</h2>
|
||||||
<div class="rank-table">
|
<div class="rank-table">
|
||||||
<div class="table-header" :style="{ 'grid-template-columns': individualGridTemplate }">
|
<div class="table-header" :style="{ 'grid-template-columns': individualGridTemplate }">
|
||||||
<span class="rank-col">排名</span>
|
<span class="rank-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.rank || 'left' }">排名</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showAvatar" class="avatar-col">头像</span>
|
<span v-if="localDisplayConfig.individual?.showAvatar" class="avatar-col">头像</span>
|
||||||
<span class="name-col">姓名</span>
|
<span class="name-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.name || 'left' }">姓名</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showTeam" class="team-col">{{
|
<span v-if="localDisplayConfig.individual?.showTeam" class="team-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.team || 'left' }">{{
|
||||||
localDisplayConfig.individual?.teamColumn?.displayName || '战区' }}</span>
|
localDisplayConfig.individual?.teamColumn?.displayName || '战区' }}</span>
|
||||||
<span class="score-col">{{ localDisplayConfig.individual?.scoreColumn?.displayName || '业绩' }}</span>
|
<span class="score-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.score || 'left' }">{{ localDisplayConfig.individual?.scoreColumn?.displayName || '业绩' }}</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showLevel" class="level-col">等级</span>
|
<span v-if="localDisplayConfig.individual?.showLevel" class="level-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.level || 'left' }">等级</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showDepartment" class="dept-col">部门</span>
|
<span v-if="localDisplayConfig.individual?.showDepartment" class="dept-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.department || 'left' }">部门</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showBonus" class="bonus-col">奖金</span>
|
<span v-if="localDisplayConfig.individual?.showBonus" class="bonus-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.bonus || 'left' }">奖金</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="(item, index) in individualRankings.slice(0, localDisplayConfig.individual.maxDisplayRows)" :key="item.id" class="table-row"
|
<div v-for="(item, index) in individualRankings" :key="item.id" class="table-row"
|
||||||
:style="{ 'grid-template-columns': individualGridTemplate }" :class="{
|
:style="{ 'grid-template-columns': individualGridTemplate }" :class="{
|
||||||
'top-three': index < 3,
|
'top-three': index < 3,
|
||||||
'highlight': index === 0
|
'highlight': index === 0
|
||||||
}">
|
}">
|
||||||
<span class="rank-col">{{ index + 1 }}</span>
|
<span class="rank-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.rank || 'left' }">{{ index + 1 }}</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showAvatar" class="avatar-col">
|
<span v-if="localDisplayConfig.individual?.showAvatar" class="avatar-col">
|
||||||
<img v-if="item.avatar && item.avatar.startsWith('/')" :src="item.avatar" alt="头像"
|
<img v-if="item.avatar && item.avatar.startsWith('/')" :src="item.avatar" alt="头像"
|
||||||
class="avatar-image">
|
class="avatar-image">
|
||||||
<span v-else>{{ item.avatar || '👤' }}</span>
|
<span v-else>{{ item.avatar || '👤' }}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="name-col">{{ item.name }}</span>
|
<span class="name-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.name || 'left' }">{{ item.name || '-' }}</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showTeam" class="team-col">{{ item.team || '-' }}</span>
|
<span v-if="localDisplayConfig.individual?.showTeam" class="team-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.team || 'left' }">{{ item.team || '-' }}</span>
|
||||||
<span class="score-col">{{ localDisplayConfig.individual?.scoreColumn?.displayStyle === 'amount' ? '¥' +
|
<span class="score-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.score || 'left' }">{{ localDisplayConfig.individual?.scoreColumn?.displayStyle === 'amount' ? '¥' +
|
||||||
item.score : item.score }}</span>
|
item.score : item.score }}</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showLevel" class="level-col"
|
<span v-if="localDisplayConfig.individual?.showLevel" class="level-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.level || 'left' }"
|
||||||
:class="`level-${item.level}`">{{ item.level }}</span>
|
:class="`level-${item.level}`">{{ item.level }}</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showDepartment" class="dept-col">{{ item.department }}</span>
|
<span v-if="localDisplayConfig.individual?.showDepartment" class="dept-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.department || 'left' }">{{ item.department }}</span>
|
||||||
<span v-if="localDisplayConfig.individual?.showBonus" class="bonus-col">¥{{ item.bonus }}</span>
|
<span v-if="localDisplayConfig.individual?.showBonus" class="bonus-col" :style="{ textAlign: localDisplayConfig.individual?.columnAlignments?.bonus || 'left' }">¥{{ item.bonus }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -170,7 +173,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, onUnmounted, watch, computed, reactive } from 'vue';
|
import { ref, onBeforeMount, onMounted, onUnmounted, watch, computed, reactive } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import {
|
import {
|
||||||
individualRankings as importedIndividualRankings,
|
individualRankings as importedIndividualRankings,
|
||||||
@@ -194,21 +197,29 @@ function createDefaultDisplayConfig() {
|
|||||||
},
|
},
|
||||||
individual: {
|
individual: {
|
||||||
scoreColumn: {
|
scoreColumn: {
|
||||||
displayName: '战绩',
|
displayName: '业绩',
|
||||||
displayStyle: 'number'
|
displayStyle: 'number'
|
||||||
},
|
},
|
||||||
teamColumn: {
|
teamColumn: {
|
||||||
displayName: '战区',
|
displayName: '战区'
|
||||||
displayStyle: 'text'
|
|
||||||
},
|
},
|
||||||
showLevel: true,
|
showLevel: true,
|
||||||
showDepartment: true,
|
showDepartment: true,
|
||||||
showBonus: false,
|
showBonus: false,
|
||||||
showTeam: true, // 默认显示战区列
|
showTeam: true, // 默认显示战区列
|
||||||
showAvatar: false, // 默认不显示头像列
|
showAvatar: false, // 默认不显示头像列
|
||||||
maxDisplayRows: 10, // 默认最多显示10行
|
defaultDisplayRows: 10, // 默认显示10行
|
||||||
columnWidths: {
|
columnWidths: {
|
||||||
team: 120 // 默认战区列宽
|
team: 120 // 默认战区列宽
|
||||||
|
},
|
||||||
|
columnAlignments: {
|
||||||
|
rank: 'left',
|
||||||
|
name: 'left',
|
||||||
|
score: 'left',
|
||||||
|
level: 'left',
|
||||||
|
department: 'left',
|
||||||
|
team: 'left',
|
||||||
|
bonus: 'left'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
team: {
|
team: {
|
||||||
@@ -219,7 +230,16 @@ function createDefaultDisplayConfig() {
|
|||||||
showMemberCount: true,
|
showMemberCount: true,
|
||||||
showLeader: true,
|
showLeader: true,
|
||||||
showBonus: false,
|
showBonus: false,
|
||||||
columnWidths: {}
|
defaultDisplayRows: 0, // 默认显示所有行
|
||||||
|
columnWidths: {},
|
||||||
|
columnAlignments: {
|
||||||
|
rank: 'left',
|
||||||
|
name: 'left',
|
||||||
|
score: 'left',
|
||||||
|
memberCount: 'left',
|
||||||
|
leader: 'left',
|
||||||
|
bonus: 'left'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -257,17 +277,42 @@ function mergeConfig(config1, config2) {
|
|||||||
const individualRankings = ref(importedIndividualRankings || []);
|
const individualRankings = ref(importedIndividualRankings || []);
|
||||||
const teamRankings = ref(importedTeamRankings || []);
|
const teamRankings = ref(importedTeamRankings || []);
|
||||||
// 确保即使displayConfig存在,也要和默认配置合并,保证结构完整性
|
// 确保即使displayConfig存在,也要和默认配置合并,保证结构完整性
|
||||||
const localDisplayConfig = ref(displayConfig
|
const localDisplayConfig = ref(() => {
|
||||||
? mergeConfig(defaultDisplayConfig, JSON.parse(JSON.stringify(displayConfig)))
|
if (displayConfig) {
|
||||||
: defaultDisplayConfig
|
const configCopy = JSON.parse(JSON.stringify(displayConfig));
|
||||||
);
|
const merged = mergeConfig(defaultDisplayConfig, configCopy);
|
||||||
|
|
||||||
|
// 确保所有必要属性都存在
|
||||||
|
if (!merged.individual) merged.individual = { ...defaultDisplayConfig.individual };
|
||||||
|
if (!merged.team) merged.team = { ...defaultDisplayConfig.team };
|
||||||
|
|
||||||
|
// 确保columnAlignments属性存在
|
||||||
|
if (!merged.individual.columnAlignments) {
|
||||||
|
merged.individual.columnAlignments = { ...defaultDisplayConfig.individual.columnAlignments };
|
||||||
|
}
|
||||||
|
if (!merged.team.columnAlignments) {
|
||||||
|
merged.team.columnAlignments = { ...defaultDisplayConfig.team.columnAlignments };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保defaultDisplayRows属性存在
|
||||||
|
if (merged.individual.defaultDisplayRows === undefined) {
|
||||||
|
merged.individual.defaultDisplayRows = defaultDisplayConfig.individual.defaultDisplayRows;
|
||||||
|
}
|
||||||
|
if (merged.team.defaultDisplayRows === undefined) {
|
||||||
|
merged.team.defaultDisplayRows = defaultDisplayConfig.team.defaultDisplayRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
return defaultDisplayConfig;
|
||||||
|
});
|
||||||
const taskSettings = ref({
|
const taskSettings = ref({
|
||||||
mainTitle: '3000万',
|
mainTitle: '3000万',
|
||||||
subtitle: '时间: 2025-11-12 - 2026-02-08'
|
subtitle: '时间: 2025-11-12 - 2026-02-08'
|
||||||
});
|
});
|
||||||
|
|
||||||
// 加载任务设置和初始化所有数据
|
// 加载任务设置和初始化所有数据
|
||||||
onMounted(async () => {
|
onBeforeMount(async () => {
|
||||||
try {
|
try {
|
||||||
// 首先初始化所有数据,确保从服务器获取最新配置
|
// 首先初始化所有数据,确保从服务器获取最新配置
|
||||||
await initializeData();
|
await initializeData();
|
||||||
@@ -291,7 +336,10 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 更新显示配置
|
// 更新显示配置
|
||||||
if (config.displayConfig) {
|
if (config.displayConfig) {
|
||||||
localDisplayConfig.value = mergeConfig(defaultDisplayConfig, JSON.parse(JSON.stringify(config.displayConfig)));
|
const configCopy = JSON.parse(JSON.stringify(config.displayConfig));
|
||||||
|
localDisplayConfig.value = mergeConfig(defaultDisplayConfig, configCopy);
|
||||||
|
|
||||||
|
console.log('localDisplayConfig.value =', localDisplayConfig.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('成功从服务器加载最新数据');
|
console.log('成功从服务器加载最新数据');
|
||||||
@@ -303,6 +351,52 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 确保原有onMounted逻辑不被覆盖
|
// 确保原有onMounted逻辑不被覆盖
|
||||||
|
|
||||||
|
// 更新CSS变量,将默认显示行数传递给样式
|
||||||
|
watch(
|
||||||
|
() => localDisplayConfig.value.individual.defaultDisplayRows,
|
||||||
|
(newRows) => {
|
||||||
|
document.documentElement.style.setProperty('--default-display-rows', newRows);
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 添加监听以同步战区排名默认显示行数配置到CSS变量
|
||||||
|
watch(
|
||||||
|
() => localDisplayConfig.value.team.defaultDisplayRows,
|
||||||
|
(newValue) => {
|
||||||
|
if (newValue && newValue > 0) {
|
||||||
|
document.documentElement.style.setProperty('--team-default-height', `calc(60px * ${newValue})`);
|
||||||
|
document.documentElement.style.setProperty('--team-overflow-y', 'auto');
|
||||||
|
document.documentElement.style.setProperty('--team-overflow-x', 'auto');
|
||||||
|
document.documentElement.style.setProperty('--team-scroll-lock', '');
|
||||||
|
} else {
|
||||||
|
// 根据实际数据条数计算高度,每行60px,加上一些额外空间(20px)
|
||||||
|
const actualHeight = teamRankings.value.length * 60 + 20;
|
||||||
|
document.documentElement.style.setProperty('--team-default-height', `${actualHeight}px`);
|
||||||
|
document.documentElement.style.setProperty('--team-overflow-y', 'hidden');
|
||||||
|
document.documentElement.style.setProperty('--team-overflow-x', 'hidden');
|
||||||
|
document.documentElement.style.setProperty('--team-scroll-lock', 'lock');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 当战区数据变化时,重新计算高度(如果当前是显示所有行模式)
|
||||||
|
watch(
|
||||||
|
() => teamRankings.value.length,
|
||||||
|
() => {
|
||||||
|
const displayRows = localDisplayConfig.value.team.defaultDisplayRows;
|
||||||
|
if (!displayRows || displayRows === 0) {
|
||||||
|
// 根据实际数据条数计算高度,每行60px,加上一些额外空间(20px)
|
||||||
|
const actualHeight = teamRankings.value.length * 60 + 20;
|
||||||
|
document.documentElement.style.setProperty('--team-default-height', `${actualHeight}px`);
|
||||||
|
document.documentElement.style.setProperty('--team-overflow-y', 'hidden');
|
||||||
|
document.documentElement.style.setProperty('--team-overflow-x', 'hidden');
|
||||||
|
document.documentElement.style.setProperty('--team-scroll-lock', 'lock');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 确保奖金规则有默认值
|
// 确保奖金规则有默认值
|
||||||
const displayBonusRules = computed(() => {
|
const displayBonusRules = computed(() => {
|
||||||
return Array.isArray(bonusRules) && bonusRules.length > 0
|
return Array.isArray(bonusRules) && bonusRules.length > 0
|
||||||
@@ -770,8 +864,25 @@ onMounted(async () => {
|
|||||||
try {
|
try {
|
||||||
// 异步初始化数据
|
// 异步初始化数据
|
||||||
await initializeData();
|
await initializeData();
|
||||||
// 更新本地显示配置
|
|
||||||
localDisplayConfig.value = displayConfig ? JSON.parse(JSON.stringify(displayConfig)) : createDefaultDisplayConfig();
|
// 更新本地显示配置,确保columnAlignments属性存在
|
||||||
|
if (displayConfig) {
|
||||||
|
const configCopy = JSON.parse(JSON.stringify(displayConfig));
|
||||||
|
const defaultConfig = createDefaultDisplayConfig();
|
||||||
|
const merged = mergeConfig(defaultConfig, configCopy);
|
||||||
|
|
||||||
|
// 确保columnAlignments属性存在
|
||||||
|
if (!merged.individual.columnAlignments) {
|
||||||
|
merged.individual.columnAlignments = { ...defaultConfig.individual.columnAlignments };
|
||||||
|
}
|
||||||
|
if (!merged.team.columnAlignments) {
|
||||||
|
merged.team.columnAlignments = { ...defaultConfig.team.columnAlignments };
|
||||||
|
}
|
||||||
|
|
||||||
|
localDisplayConfig.value = merged;
|
||||||
|
} else {
|
||||||
|
localDisplayConfig.value = createDefaultDisplayConfig();
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('初始化数据失败:', error);
|
console.error('初始化数据失败:', error);
|
||||||
// 使用默认配置
|
// 使用默认配置
|
||||||
@@ -858,6 +969,51 @@ onUnmounted(() => {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 冠军头像容器 */
|
||||||
|
.champion-container {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 皇冠动画效果 */
|
||||||
|
.crown-animation {
|
||||||
|
position: absolute;
|
||||||
|
top: -25px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
animation: crownFloat 2s ease-in-out infinite;
|
||||||
|
z-index: 10;
|
||||||
|
text-shadow: 0 0 10px var(--gold-primary), 0 0 20px var(--gold-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 皇冠浮动动画 */
|
||||||
|
@keyframes crownFloat {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-50%) translateY(0) rotate(-5deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateX(-50%) translateY(-5px) rotate(5deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(-50%) translateY(0) rotate(-5deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 皇冠发光效果动画 */
|
||||||
|
.crown-animation {
|
||||||
|
animation: crownFloat 2s ease-in-out infinite, crownGlow 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes crownGlow {
|
||||||
|
0%, 100% {
|
||||||
|
text-shadow: 0 0 10px var(--gold-primary), 0 0 20px var(--gold-secondary);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-shadow: 0 0 15px var(--gold-primary), 0 0 30px var(--gold-secondary), 0 0 40px rgba(255, 215, 0, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.champion-logo {
|
.champion-logo {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
@@ -1524,53 +1680,113 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 针对高度大于1080分辨率的精确优化 */
|
/* 针对高度大于1080分辨率的精确优化 */
|
||||||
@media (min-height: 1080px) {
|
|
||||||
|
|
||||||
/* 优化表格布局 - 设置高度确保只显示5行 */
|
|
||||||
.rank-table {
|
|
||||||
min-height: 280px !important;
|
|
||||||
max-height: 280px !important;
|
|
||||||
margin: 0 auto;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 优化表格行高,确保5行内容完美显示 */
|
|
||||||
.table-row {
|
|
||||||
min-height: 38px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 优化前三名特殊样式 */
|
|
||||||
.table-row:nth-child(1),
|
|
||||||
.table-row:nth-child(2),
|
|
||||||
.table-row:nth-child(3) {
|
|
||||||
font-size: 1.05rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 移动端背景图片设置 - 全局样式 */
|
/* 移动端背景图片设置 - 全局样式 */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
|
||||||
/* 战区排名容器设置 - 禁止滚动 */
|
/* 战区排名容器设置 - 根据配置决定显示行数和滚动行为 */
|
||||||
.team-rankings-container .rank-table {
|
.team-rankings-container .rank-table {
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
|
/* 如果配置了具体了默认显示行数,则设置高度和滚动,否则显示所有行 */
|
||||||
|
height: var(--team-default-height, auto) !important;
|
||||||
|
overflow-y: var(--team-overflow-y, hidden);
|
||||||
|
overflow-x: var(--team-overflow-x, auto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 当设置了滚动锁定时,禁止所有滚动 */
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container .rank-table {
|
||||||
|
overflow-y: hidden !important;
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
height: var(--team-default-height, auto) !important;
|
||||||
|
min-width: auto !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保表格内容在锁定模式下正确显示 */
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container .rank-table .table-header,
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container .rank-table .table-row {
|
||||||
|
min-width: auto !important;
|
||||||
|
width: 100% !important;
|
||||||
|
overflow-x: visible !important;
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 英雄排名容器设置 - 允许垂直滚动,设置默认高度显示多行 */
|
||||||
|
.individual-rankings-container .rank-table {
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: auto; /* 允许水平滚动 */
|
||||||
|
position: relative;
|
||||||
|
/* 基于默认显示行数计算合适的高度 */
|
||||||
|
height: calc(60px * var(--default-display-rows, 10));
|
||||||
|
/* 隐藏滚动条但保留滚动功能 */
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端非前三名字体放大 */
|
||||||
|
.team-rankings-container .table-row:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3)),
|
||||||
|
.individual-rankings-container .table-row:not(:nth-child(1)):not(:nth-child(2)):not(:nth-child(3)) {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 移动端名次列水平垂直居中 */
|
||||||
|
.team-rankings-container .table-header > :first-child,
|
||||||
|
.individual-rankings-container .table-header > :first-child,
|
||||||
|
.team-rankings-container .table-row > :first-child,
|
||||||
|
.individual-rankings-container .table-row > :first-child {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 确保前三名特殊样式在移动端正确显示 */
|
/* 确保前三名特殊样式在移动端正确显示 */
|
||||||
.team-rankings-container .table-row.top-three {
|
.team-rankings-container .table-row.top-three,
|
||||||
transform: scale(1);
|
.individual-rankings-container .table-row.top-three {
|
||||||
box-shadow: none;
|
transform: scale(1);
|
||||||
position: static;
|
box-shadow: none;
|
||||||
}
|
position: static;
|
||||||
|
}
|
||||||
.team-rankings-container .table-row:nth-child(1),
|
|
||||||
.team-rankings-container .table-row:nth-child(2),
|
.team-rankings-container .table-row:nth-child(1),
|
||||||
.team-rankings-container .table-row:nth-child(3) {
|
.team-rankings-container .table-row:nth-child(2),
|
||||||
box-shadow: none;
|
.team-rankings-container .table-row:nth-child(3),
|
||||||
z-index: 1;
|
.individual-rankings-container .table-row:nth-child(1),
|
||||||
}
|
.individual-rankings-container .table-row:nth-child(2),
|
||||||
|
.individual-rankings-container .table-row:nth-child(3) {
|
||||||
|
box-shadow: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 当设置为禁止滚动时,确保战区排名容器不允许滚动 */
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container {
|
||||||
|
overflow: visible !important;
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container .rank-table {
|
||||||
|
overflow: hidden !important;
|
||||||
|
display: block;
|
||||||
|
min-width: auto !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保表格头部和行在禁止滚动模式下能够完整显示内容 */
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container .table-header,
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container .table-row {
|
||||||
|
min-width: auto !important;
|
||||||
|
width: 100% !important;
|
||||||
|
overflow-x: visible !important;
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 英雄排名列表隐藏水平滚动条 */
|
||||||
|
.individual-rankings-container .rank-table::-webkit-scrollbar {
|
||||||
|
width: 6px; /* 保留垂直滚动条 */
|
||||||
|
height: 0; /* 隐藏水平滚动条 */
|
||||||
|
}
|
||||||
|
|
||||||
/* 1. 背景图片全屏显示并固定 */
|
/* 1. 背景图片全屏显示并固定 */
|
||||||
.battle-ranking {
|
.battle-ranking {
|
||||||
@@ -1695,6 +1911,18 @@ onUnmounted(() => {
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: rgba(255, 255, 255, 0.95);
|
background: rgba(255, 255, 255, 0.95);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 当设置为禁止滚动时,确保战区排名容器不允许滚动 */
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container {
|
||||||
|
overflow: visible !important;
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[style*="--team-scroll-lock: lock"] .team-rankings-container .rank-table {
|
||||||
|
overflow: hidden !important;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
/* 表格调整 */
|
/* 表格调整 */
|
||||||
.rank-table {
|
.rank-table {
|
||||||
|
|||||||
Reference in New Issue
Block a user