响应式
This commit is contained in:
@@ -6,6 +6,50 @@ function TopData({ onProgressRate }) {
|
|||||||
const [progressRate, setProgressRate] = useState('0.00')
|
const [progressRate, setProgressRate] = useState('0.00')
|
||||||
|
|
||||||
const MOBILE_BREAKPOINT = 768
|
const MOBILE_BREAKPOINT = 768
|
||||||
|
const weekContainersRef = useRef(null)
|
||||||
|
|
||||||
|
// 动态调整周圈大小以适应容器宽度
|
||||||
|
const adjustWeekCirclesSize = () => {
|
||||||
|
const weekContainers = document.querySelectorAll('.weeks-container')
|
||||||
|
|
||||||
|
weekContainers.forEach(container => {
|
||||||
|
const containerWidth = container.offsetWidth
|
||||||
|
const weekCircles = container.querySelectorAll('.week-circle')
|
||||||
|
if (weekCircles.length === 0) return
|
||||||
|
|
||||||
|
const gap = 3
|
||||||
|
const totalGap = gap * (weekCircles.length - 1)
|
||||||
|
const circleCount = weekCircles.length
|
||||||
|
|
||||||
|
const idealSize = (containerWidth - totalGap) / circleCount
|
||||||
|
const minSize = 10
|
||||||
|
const maxSize = 24
|
||||||
|
|
||||||
|
let finalSize = Math.max(minSize, Math.min(idealSize, maxSize))
|
||||||
|
|
||||||
|
const totalContentWidth = (finalSize * circleCount) + totalGap
|
||||||
|
let scale = 1
|
||||||
|
|
||||||
|
if (totalContentWidth > containerWidth) {
|
||||||
|
scale = containerWidth / totalContentWidth
|
||||||
|
scale = Math.max(0.5, scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
weekCircles.forEach(circle => {
|
||||||
|
circle.style.width = finalSize + 'px'
|
||||||
|
circle.style.height = finalSize + 'px'
|
||||||
|
circle.style.fontSize = (finalSize * 0.4) + 'px'
|
||||||
|
circle.style.borderWidth = Math.max(1, finalSize / 8) + 'px'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (scale < 1) {
|
||||||
|
container.style.transform = `scaleX(${scale})`
|
||||||
|
container.style.transformOrigin = 'left'
|
||||||
|
} else {
|
||||||
|
container.style.transform = 'none'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 获取当前周数
|
// 获取当前周数
|
||||||
const getCurrentWeek = () => {
|
const getCurrentWeek = () => {
|
||||||
@@ -94,6 +138,27 @@ function TopData({ onProgressRate }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initData()
|
initData()
|
||||||
|
|
||||||
|
// 初始调整周圈大小
|
||||||
|
setTimeout(() => {
|
||||||
|
adjustWeekCirclesSize()
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
// 监听窗口大小变化
|
||||||
|
let resizeTimer
|
||||||
|
const handleResize = () => {
|
||||||
|
clearTimeout(resizeTimer)
|
||||||
|
resizeTimer = setTimeout(() => {
|
||||||
|
adjustWeekCirclesSize()
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', handleResize)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', handleResize)
|
||||||
|
clearTimeout(resizeTimer)
|
||||||
|
}
|
||||||
}, [onProgressRate])
|
}, [onProgressRate])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+315
-11
@@ -73,6 +73,7 @@ body {
|
|||||||
grid-template-columns: 2fr 1fr;
|
grid-template-columns: 2fr 1fr;
|
||||||
gap: clamp(6px, 1.5vw, 14px);
|
gap: clamp(6px, 1.5vw, 14px);
|
||||||
margin-bottom: clamp(10px, 1.5vw, 20px);
|
margin-bottom: clamp(10px, 1.5vw, 20px);
|
||||||
|
min-height: 0; /* 允许grid子项收缩 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.sales-info {
|
.sales-info {
|
||||||
@@ -237,6 +238,7 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
overflow: hidden; /* 防止溢出 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.countdown h3 {
|
.countdown h3 {
|
||||||
@@ -244,6 +246,7 @@ body {
|
|||||||
color: #e7552f;
|
color: #e7552f;
|
||||||
margin-bottom: clamp(10px, 1.5vw, 15px);
|
margin-bottom: clamp(10px, 1.5vw, 15px);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
white-space: nowrap; /* 标题不换行 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 季度容器 */
|
/* 季度容器 */
|
||||||
@@ -263,6 +266,7 @@ body {
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
border-bottom: 1px solid #523A14;
|
border-bottom: 1px solid #523A14;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
overflow: hidden; /* 防止内容溢出 */
|
||||||
}
|
}
|
||||||
.last-quarter{
|
.last-quarter{
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
@@ -285,26 +289,34 @@ body {
|
|||||||
/* 周数圆圈容器 */
|
/* 周数圆圈容器 */
|
||||||
.weeks-container {
|
.weeks-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap; /* 不换行 */
|
||||||
gap: clamp(3px, 0.5vw, 5px);
|
gap: clamp(2px, 0.4vw, 5px);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
overflow-x: hidden; /* 隐藏溢出内容 */
|
||||||
|
overflow-y: hidden;
|
||||||
|
min-width: 0; /* 允许flex子项缩小 */
|
||||||
|
justify-content: flex-start; /* 从左侧开始排列 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 单个周数圆圈 */
|
/* 单个周数圆圈 */
|
||||||
.week-circle {
|
.week-circle {
|
||||||
width: clamp(18px, 2.5vw, 24px);
|
width: clamp(12px, 2.5vw, 24px);
|
||||||
height: clamp(18px, 2.5vw, 24px);
|
height: clamp(12px, 2.5vw, 24px);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 2px solid #815B37;
|
border: 2px solid #815B37;
|
||||||
background: rgba(129, 91, 55, 0.2);
|
background: rgba(129, 91, 55, 0.2);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: clamp(0.625rem, 1vw, 0.75rem);
|
font-size: clamp(0.5rem, 1vw, 0.75rem);
|
||||||
color: #f5bbab;
|
color: #f5bbab;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
flex-shrink: 1; /* 允许周圈缩小以适应容器 */
|
||||||
|
min-width: 10px; /* 最小尺寸 */
|
||||||
|
min-height: 10px;
|
||||||
|
flex-basis: clamp(12px, 2.5vw, 24px); /* 弹性基础尺寸 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.week-circle:hover {
|
.week-circle:hover {
|
||||||
@@ -505,16 +517,40 @@ body {
|
|||||||
font-size: clamp(0.875rem, 2.5vw, 1.125rem);
|
font-size: clamp(0.875rem, 2.5vw, 1.125rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 年度进度移动端优化 - 确保不换行 */
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1.2vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.75rem, 1.5vw, 1rem);
|
||||||
|
margin-bottom: clamp(8px, 1.2vw, 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(4px, 1vw, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(4px, 0.8vw, 6px);
|
||||||
|
padding-bottom: clamp(6px, 1vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
.quarter-label {
|
.quarter-label {
|
||||||
font-size: clamp(0.75rem, 2vw, 0.875rem);
|
font-size: clamp(0.7rem, 1.5vw, 0.85rem);
|
||||||
padding: clamp(2px, 0.5vw, 4px) clamp(6px, 1.5vw, 10px);
|
padding: clamp(2px, 0.4vw, 4px) clamp(6px, 1.2vw, 10px);
|
||||||
min-width: clamp(30px, 5vw, 40px);
|
min-width: clamp(28px, 5vw, 38px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.week-circle {
|
.week-circle {
|
||||||
width: clamp(16px, 4vw, 20px);
|
width: clamp(14px, 3.5vw, 18px);
|
||||||
height: clamp(16px, 4vw, 20px);
|
height: clamp(14px, 3.5vw, 18px);
|
||||||
font-size: clamp(0.5rem, 1.5vw, 0.625rem);
|
font-size: clamp(0.5rem, 1.2vw, 0.625rem);
|
||||||
|
border-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(2px, 0.5vw, 4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ranking-item {
|
.ranking-item {
|
||||||
@@ -592,6 +628,274 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 笔记本小屏幕特别优化 (1024px - 1366px) */
|
||||||
|
@media screen and (min-width: 1024px) and (max-width: 1366px) {
|
||||||
|
/* 年度进度区域紧凑显示 */
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.7rem, 1vw, 0.9rem);
|
||||||
|
margin-bottom: clamp(6px, 1vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(3px, 0.8vw, 4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(3px, 0.6vw, 5px);
|
||||||
|
padding-bottom: clamp(5px, 0.7vw, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.7rem, 1vw, 0.85rem);
|
||||||
|
padding: clamp(2px, 0.3vw, 3px) clamp(5px, 0.8vw, 8px);
|
||||||
|
min-width: clamp(28px, 4vw, 35px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(14px, 2vw, 18px);
|
||||||
|
height: clamp(14px, 2vw, 18px);
|
||||||
|
font-size: clamp(0.5rem, 0.8vw, 0.625rem);
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(1px, 0.3vw, 3px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 高分辨率小笔记本优化 (125%-200% DPI缩放) */
|
||||||
|
@media screen and (min-width: 1280px) and (max-width: 1600px) {
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1vw, 10px);
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.75rem, 1.1vw, 1.1rem);
|
||||||
|
margin-bottom: clamp(8px, 1.2vw, 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(4px, 0.9vw, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(4px, 0.7vw, 7px);
|
||||||
|
padding-bottom: clamp(6px, 0.8vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.72rem, 1.05vw, 0.9rem);
|
||||||
|
padding: clamp(2px, 0.35vw, 4px) clamp(6px, 0.85vw, 10px);
|
||||||
|
min-width: clamp(30px, 4.2vw, 38px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(15px, 2.1vw, 20px);
|
||||||
|
height: clamp(15px, 2.1vw, 20px);
|
||||||
|
font-size: clamp(0.5rem, 0.85vw, 0.65rem);
|
||||||
|
border-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(2px, 0.35vw, 4px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 极致紧凑模式 - 高DPI小屏幕 */
|
||||||
|
@media screen and (min-width: 1200px) and (max-width: 1440px) and (min-aspect-ratio: 16/10) {
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(5px, 0.9vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.7rem, 1vw, 0.95rem);
|
||||||
|
margin-bottom: clamp(6px, 1vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(3px, 0.7vw, 5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(3px, 0.6vw, 6px);
|
||||||
|
padding-bottom: clamp(5px, 0.7vw, 7px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.68rem, 1vw, 0.82rem);
|
||||||
|
padding: clamp(2px, 0.3vw, 4px) clamp(5px, 0.8vw, 9px);
|
||||||
|
min-width: clamp(28px, 4vw, 35px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(14px, 2vw, 18px);
|
||||||
|
height: clamp(14px, 2vw, 18px);
|
||||||
|
font-size: clamp(0.48rem, 0.8vw, 0.6rem);
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(1.5px, 0.3vw, 3px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 窄容器优化 - 适配所有高DPI小笔记本 */
|
||||||
|
@media screen and (max-width: 1400px) {
|
||||||
|
.top-data {
|
||||||
|
grid-template-columns: 2fr minmax(280px, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 极窄容器优化 */
|
||||||
|
@media screen and (max-width: 1200px) {
|
||||||
|
.top-data {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 响应式布局 - 不同屏幕尺寸优化 ========== */
|
||||||
|
|
||||||
|
/* 小屏幕笔记本 (1366x768, 1440x900) */
|
||||||
|
@media screen and (min-width: 769px) and (max-width: 1600px) {
|
||||||
|
.cont {
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: clamp(0.8rem, 1.1vw, 0.95rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(220px, 28vw, 280px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 年度进度区域优化 */
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.75rem, 1.1vw, 1.1rem);
|
||||||
|
margin-bottom: clamp(8px, 1.2vw, 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(4px, 0.8vw, 6px);
|
||||||
|
padding-bottom: clamp(6px, 0.8vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.75rem, 1.1vw, 0.95rem);
|
||||||
|
padding: clamp(2px, 0.4vw, 4px) clamp(6px, 0.9vw, 10px);
|
||||||
|
min-width: clamp(32px, 4.5vw, 40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(16px, 2.2vw, 22px);
|
||||||
|
height: clamp(16px, 2.2vw, 22px);
|
||||||
|
font-size: clamp(0.5625rem, 0.9vw, 0.6875rem);
|
||||||
|
border-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(2px, 0.4vw, 4px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标准全高清 (1920x1080) */
|
||||||
|
@media screen and (min-width: 1601px) and (max-width: 2100px) {
|
||||||
|
.cont {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 1700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(250px, 28vw, 320px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2K 屏幕 (2560x1440) */
|
||||||
|
@media screen and (min-width: 2101px) and (max-width: 3200px) {
|
||||||
|
.cont {
|
||||||
|
width: 85%;
|
||||||
|
max-width: 2200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: clamp(0.9rem, 1.2vw, 1.1rem);
|
||||||
|
padding: clamp(6px, 0.9vw, 8px) clamp(12px, 1.6vw, 18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-data {
|
||||||
|
gap: clamp(10px, 1.5vw, 18px);
|
||||||
|
margin-bottom: clamp(15px, 1.8vw, 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(280px, 28vw, 380px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4K 屏幕 (3840x2160 及以上) */
|
||||||
|
@media screen and (min-width: 3201px) {
|
||||||
|
.cont {
|
||||||
|
width: 80%;
|
||||||
|
max-width: 3000px;
|
||||||
|
padding: clamp(1.5rem, 2vw, 3rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: clamp(1rem, 1.5vw, 1.3rem);
|
||||||
|
padding: clamp(8px, 1vw, 10px) clamp(15px, 2vw, 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-data {
|
||||||
|
gap: clamp(15px, 2vw, 25px);
|
||||||
|
margin-bottom: clamp(20px, 2.5vw, 30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sales-info {
|
||||||
|
padding: clamp(15px, 2vw, 25px);
|
||||||
|
gap: clamp(15px, 2vw, 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(12px, 1.8vw, 15px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-ranking,
|
||||||
|
.person-ranking {
|
||||||
|
padding: clamp(15px, 2vw, 30px);
|
||||||
|
margin-bottom: clamp(15px, 2vw, 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(350px, 30vw, 500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-item {
|
||||||
|
padding: clamp(12px, 1.5vw, 18px) clamp(15px, 2vw, 22px);
|
||||||
|
font-size: clamp(0.85rem, 1.2vw, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-number {
|
||||||
|
width: clamp(22px, 3.5vw, 28px);
|
||||||
|
height: clamp(22px, 3.5vw, 28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4K屏幕下的文字大小优化 */
|
||||||
|
.target-amount,
|
||||||
|
.total-amount {
|
||||||
|
font-size: clamp(1.5rem, 3vw, 2.5rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 头部和尾部图片 */
|
/* 头部和尾部图片 */
|
||||||
.header-image {
|
.header-image {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
const emit = defineEmits(['progress-rate'])
|
const emit = defineEmits(['progress-rate'])
|
||||||
|
|
||||||
@@ -79,6 +79,49 @@ const getCurrentWeek = () => {
|
|||||||
|
|
||||||
const currentWeek = ref(getCurrentWeek())
|
const currentWeek = ref(getCurrentWeek())
|
||||||
|
|
||||||
|
// 动态调整周圈大小以适应容器宽度
|
||||||
|
const adjustWeekCirclesSize = () => {
|
||||||
|
const weekContainers = document.querySelectorAll('.weeks-container')
|
||||||
|
|
||||||
|
weekContainers.forEach(container => {
|
||||||
|
const containerWidth = container.offsetWidth
|
||||||
|
const weekCircles = container.querySelectorAll('.week-circle')
|
||||||
|
if (weekCircles.length === 0) return
|
||||||
|
|
||||||
|
const gap = 3
|
||||||
|
const totalGap = gap * (weekCircles.length - 1)
|
||||||
|
const circleCount = weekCircles.length
|
||||||
|
|
||||||
|
const idealSize = (containerWidth - totalGap) / circleCount
|
||||||
|
const minSize = 10
|
||||||
|
const maxSize = 24
|
||||||
|
|
||||||
|
let finalSize = Math.max(minSize, Math.min(idealSize, maxSize))
|
||||||
|
|
||||||
|
const totalContentWidth = (finalSize * circleCount) + totalGap
|
||||||
|
let scale = 1
|
||||||
|
|
||||||
|
if (totalContentWidth > containerWidth) {
|
||||||
|
scale = containerWidth / totalContentWidth
|
||||||
|
scale = Math.max(0.5, scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
weekCircles.forEach(circle => {
|
||||||
|
circle.style.width = finalSize + 'px'
|
||||||
|
circle.style.height = finalSize + 'px'
|
||||||
|
circle.style.fontSize = (finalSize * 0.4) + 'px'
|
||||||
|
circle.style.borderWidth = Math.max(1, finalSize / 8) + 'px'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (scale < 1) {
|
||||||
|
container.style.transform = `scaleX(${scale})`
|
||||||
|
container.style.transformOrigin = 'left'
|
||||||
|
} else {
|
||||||
|
container.style.transform = 'none'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 季度数据
|
// 季度数据
|
||||||
const quarters = ref([
|
const quarters = ref([
|
||||||
{ id: 'q1', label: 'Q1', start: 1, end: 13, weeks: [] },
|
{ id: 'q1', label: 'Q1', start: 1, end: 13, weeks: [] },
|
||||||
@@ -162,5 +205,27 @@ onMounted(async () => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
startProgressAnimation(parseFloat(rate))
|
startProgressAnimation(parseFloat(rate))
|
||||||
}, 800)
|
}, 800)
|
||||||
|
|
||||||
|
// 初始调整周圈大小
|
||||||
|
setTimeout(() => {
|
||||||
|
adjustWeekCirclesSize()
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
// 监听窗口大小变化
|
||||||
|
let resizeTimer
|
||||||
|
const handleResize = () => {
|
||||||
|
clearTimeout(resizeTimer)
|
||||||
|
resizeTimer = setTimeout(() => {
|
||||||
|
adjustWeekCirclesSize()
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', handleResize)
|
||||||
|
|
||||||
|
// 组件卸载时清理
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', handleResize)
|
||||||
|
clearTimeout(resizeTimer)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+315
-11
@@ -73,6 +73,7 @@ body {
|
|||||||
grid-template-columns: 2fr 1fr;
|
grid-template-columns: 2fr 1fr;
|
||||||
gap: clamp(6px, 1.5vw, 14px);
|
gap: clamp(6px, 1.5vw, 14px);
|
||||||
margin-bottom: clamp(10px, 1.5vw, 20px);
|
margin-bottom: clamp(10px, 1.5vw, 20px);
|
||||||
|
min-height: 0; /* 允许grid子项收缩 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.sales-info {
|
.sales-info {
|
||||||
@@ -237,6 +238,7 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
overflow: hidden; /* 防止溢出 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.countdown h3 {
|
.countdown h3 {
|
||||||
@@ -244,6 +246,7 @@ body {
|
|||||||
color: #e7552f;
|
color: #e7552f;
|
||||||
margin-bottom: clamp(10px, 1.5vw, 15px);
|
margin-bottom: clamp(10px, 1.5vw, 15px);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
white-space: nowrap; /* 标题不换行 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 季度容器 */
|
/* 季度容器 */
|
||||||
@@ -263,6 +266,7 @@ body {
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
border-bottom: 1px solid #523A14;
|
border-bottom: 1px solid #523A14;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
overflow: hidden; /* 防止内容溢出 */
|
||||||
}
|
}
|
||||||
.last-quarter{
|
.last-quarter{
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
@@ -285,26 +289,34 @@ body {
|
|||||||
/* 周数圆圈容器 */
|
/* 周数圆圈容器 */
|
||||||
.weeks-container {
|
.weeks-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap; /* 不换行 */
|
||||||
gap: clamp(3px, 0.5vw, 5px);
|
gap: clamp(2px, 0.4vw, 5px);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
overflow-x: hidden; /* 隐藏溢出内容 */
|
||||||
|
overflow-y: hidden;
|
||||||
|
min-width: 0; /* 允许flex子项缩小 */
|
||||||
|
justify-content: flex-start; /* 从左侧开始排列 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 单个周数圆圈 */
|
/* 单个周数圆圈 */
|
||||||
.week-circle {
|
.week-circle {
|
||||||
width: clamp(18px, 2.5vw, 24px);
|
width: clamp(12px, 2.5vw, 24px);
|
||||||
height: clamp(18px, 2.5vw, 24px);
|
height: clamp(12px, 2.5vw, 24px);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 2px solid #815B37;
|
border: 2px solid #815B37;
|
||||||
background: rgba(129, 91, 55, 0.2);
|
background: rgba(129, 91, 55, 0.2);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: clamp(0.625rem, 1vw, 0.75rem);
|
font-size: clamp(0.5rem, 1vw, 0.75rem);
|
||||||
color: #f5bbab;
|
color: #f5bbab;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
flex-shrink: 1; /* 允许周圈缩小以适应容器 */
|
||||||
|
min-width: 10px; /* 最小尺寸 */
|
||||||
|
min-height: 10px;
|
||||||
|
flex-basis: clamp(12px, 2.5vw, 24px); /* 弹性基础尺寸 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.week-circle:hover {
|
.week-circle:hover {
|
||||||
@@ -505,16 +517,40 @@ body {
|
|||||||
font-size: clamp(0.875rem, 2.5vw, 1.125rem);
|
font-size: clamp(0.875rem, 2.5vw, 1.125rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 年度进度移动端优化 - 确保不换行 */
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1.2vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.75rem, 1.5vw, 1rem);
|
||||||
|
margin-bottom: clamp(8px, 1.2vw, 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(4px, 1vw, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(4px, 0.8vw, 6px);
|
||||||
|
padding-bottom: clamp(6px, 1vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
.quarter-label {
|
.quarter-label {
|
||||||
font-size: clamp(0.75rem, 2vw, 0.875rem);
|
font-size: clamp(0.7rem, 1.5vw, 0.85rem);
|
||||||
padding: clamp(2px, 0.5vw, 4px) clamp(6px, 1.5vw, 10px);
|
padding: clamp(2px, 0.4vw, 4px) clamp(6px, 1.2vw, 10px);
|
||||||
min-width: clamp(30px, 5vw, 40px);
|
min-width: clamp(28px, 5vw, 38px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.week-circle {
|
.week-circle {
|
||||||
width: clamp(16px, 4vw, 20px);
|
width: clamp(14px, 3.5vw, 18px);
|
||||||
height: clamp(16px, 4vw, 20px);
|
height: clamp(14px, 3.5vw, 18px);
|
||||||
font-size: clamp(0.5rem, 1.5vw, 0.625rem);
|
font-size: clamp(0.5rem, 1.2vw, 0.625rem);
|
||||||
|
border-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(2px, 0.5vw, 4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ranking-item {
|
.ranking-item {
|
||||||
@@ -592,6 +628,274 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 笔记本小屏幕特别优化 (1024px - 1366px) */
|
||||||
|
@media screen and (min-width: 1024px) and (max-width: 1366px) {
|
||||||
|
/* 年度进度区域紧凑显示 */
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.7rem, 1vw, 0.9rem);
|
||||||
|
margin-bottom: clamp(6px, 1vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(3px, 0.8vw, 4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(3px, 0.6vw, 5px);
|
||||||
|
padding-bottom: clamp(5px, 0.7vw, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.7rem, 1vw, 0.85rem);
|
||||||
|
padding: clamp(2px, 0.3vw, 3px) clamp(5px, 0.8vw, 8px);
|
||||||
|
min-width: clamp(28px, 4vw, 35px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(14px, 2vw, 18px);
|
||||||
|
height: clamp(14px, 2vw, 18px);
|
||||||
|
font-size: clamp(0.5rem, 0.8vw, 0.625rem);
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(1px, 0.3vw, 3px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 高分辨率小笔记本优化 (125%-200% DPI缩放) */
|
||||||
|
@media screen and (min-width: 1280px) and (max-width: 1600px) {
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1vw, 10px);
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.75rem, 1.1vw, 1.1rem);
|
||||||
|
margin-bottom: clamp(8px, 1.2vw, 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(4px, 0.9vw, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(4px, 0.7vw, 7px);
|
||||||
|
padding-bottom: clamp(6px, 0.8vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.72rem, 1.05vw, 0.9rem);
|
||||||
|
padding: clamp(2px, 0.35vw, 4px) clamp(6px, 0.85vw, 10px);
|
||||||
|
min-width: clamp(30px, 4.2vw, 38px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(15px, 2.1vw, 20px);
|
||||||
|
height: clamp(15px, 2.1vw, 20px);
|
||||||
|
font-size: clamp(0.5rem, 0.85vw, 0.65rem);
|
||||||
|
border-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(2px, 0.35vw, 4px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 极致紧凑模式 - 高DPI小屏幕 */
|
||||||
|
@media screen and (min-width: 1200px) and (max-width: 1440px) and (min-aspect-ratio: 16/10) {
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(5px, 0.9vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.7rem, 1vw, 0.95rem);
|
||||||
|
margin-bottom: clamp(6px, 1vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarters-container {
|
||||||
|
gap: clamp(3px, 0.7vw, 5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(3px, 0.6vw, 6px);
|
||||||
|
padding-bottom: clamp(5px, 0.7vw, 7px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.68rem, 1vw, 0.82rem);
|
||||||
|
padding: clamp(2px, 0.3vw, 4px) clamp(5px, 0.8vw, 9px);
|
||||||
|
min-width: clamp(28px, 4vw, 35px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(14px, 2vw, 18px);
|
||||||
|
height: clamp(14px, 2vw, 18px);
|
||||||
|
font-size: clamp(0.48rem, 0.8vw, 0.6rem);
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(1.5px, 0.3vw, 3px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 窄容器优化 - 适配所有高DPI小笔记本 */
|
||||||
|
@media screen and (max-width: 1400px) {
|
||||||
|
.top-data {
|
||||||
|
grid-template-columns: 2fr minmax(280px, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 极窄容器优化 */
|
||||||
|
@media screen and (max-width: 1200px) {
|
||||||
|
.top-data {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========== 响应式布局 - 不同屏幕尺寸优化 ========== */
|
||||||
|
|
||||||
|
/* 小屏幕笔记本 (1366x768, 1440x900) */
|
||||||
|
@media screen and (min-width: 769px) and (max-width: 1600px) {
|
||||||
|
.cont {
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: clamp(0.8rem, 1.1vw, 0.95rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(220px, 28vw, 280px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 年度进度区域优化 */
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(6px, 1vw, 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown h3 {
|
||||||
|
font-size: clamp(0.75rem, 1.1vw, 1.1rem);
|
||||||
|
margin-bottom: clamp(8px, 1.2vw, 12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-item {
|
||||||
|
gap: clamp(4px, 0.8vw, 6px);
|
||||||
|
padding-bottom: clamp(6px, 0.8vw, 8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-label {
|
||||||
|
font-size: clamp(0.75rem, 1.1vw, 0.95rem);
|
||||||
|
padding: clamp(2px, 0.4vw, 4px) clamp(6px, 0.9vw, 10px);
|
||||||
|
min-width: clamp(32px, 4.5vw, 40px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-circle {
|
||||||
|
width: clamp(16px, 2.2vw, 22px);
|
||||||
|
height: clamp(16px, 2.2vw, 22px);
|
||||||
|
font-size: clamp(0.5625rem, 0.9vw, 0.6875rem);
|
||||||
|
border-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weeks-container {
|
||||||
|
gap: clamp(2px, 0.4vw, 4px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标准全高清 (1920x1080) */
|
||||||
|
@media screen and (min-width: 1601px) and (max-width: 2100px) {
|
||||||
|
.cont {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 1700px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(250px, 28vw, 320px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2K 屏幕 (2560x1440) */
|
||||||
|
@media screen and (min-width: 2101px) and (max-width: 3200px) {
|
||||||
|
.cont {
|
||||||
|
width: 85%;
|
||||||
|
max-width: 2200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: clamp(0.9rem, 1.2vw, 1.1rem);
|
||||||
|
padding: clamp(6px, 0.9vw, 8px) clamp(12px, 1.6vw, 18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-data {
|
||||||
|
gap: clamp(10px, 1.5vw, 18px);
|
||||||
|
margin-bottom: clamp(15px, 1.8vw, 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(280px, 28vw, 380px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4K 屏幕 (3840x2160 及以上) */
|
||||||
|
@media screen and (min-width: 3201px) {
|
||||||
|
.cont {
|
||||||
|
width: 80%;
|
||||||
|
max-width: 3000px;
|
||||||
|
padding: clamp(1.5rem, 2vw, 3rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: clamp(1rem, 1.5vw, 1.3rem);
|
||||||
|
padding: clamp(8px, 1vw, 10px) clamp(15px, 2vw, 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-data {
|
||||||
|
gap: clamp(15px, 2vw, 25px);
|
||||||
|
margin-bottom: clamp(20px, 2.5vw, 30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sales-info {
|
||||||
|
padding: clamp(15px, 2vw, 25px);
|
||||||
|
gap: clamp(15px, 2vw, 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.countdown {
|
||||||
|
padding: clamp(12px, 1.8vw, 15px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-ranking,
|
||||||
|
.person-ranking {
|
||||||
|
padding: clamp(15px, 2vw, 30px);
|
||||||
|
margin-bottom: clamp(15px, 2vw, 25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
min-height: clamp(350px, 30vw, 500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ranking-item {
|
||||||
|
padding: clamp(12px, 1.5vw, 18px) clamp(15px, 2vw, 22px);
|
||||||
|
font-size: clamp(0.85rem, 1.2vw, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rank-number {
|
||||||
|
width: clamp(22px, 3.5vw, 28px);
|
||||||
|
height: clamp(22px, 3.5vw, 28px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4K屏幕下的文字大小优化 */
|
||||||
|
.target-amount,
|
||||||
|
.total-amount {
|
||||||
|
font-size: clamp(1.5rem, 3vw, 2.5rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 头部和尾部图片 */
|
/* 头部和尾部图片 */
|
||||||
.header-image {
|
.header-image {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|||||||
Reference in New Issue
Block a user