Files
yudao-dev/src/views/home/costComponents/costBar.vue
‘937886381’ 694beb5851 修改
2025-11-24 14:10:46 +08:00

266 lines
6.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="coreBar">
<div class="barTop">
<div class="right-container">
<div class="legend">
<span class="legend-item">
<span class="legend-icon square target"></span>
目标
</span>
<span class="legend-item">
<span class="legend-icon square achieved"></span>
实际
</span>
</div>
<div class="button-group">
<div class="item-button category-btn">
<span class="item-text" style="width: 88px;">类目选择</span>
</div>
<div class="dropdown-container">
<div class="item-button profit-btn active" @click.stop="isDropdownShow = !isDropdownShow">
<span class="item-text profit-text">{{ selectedProfit || '请选择' }}</span>
<span class="dropdown-arrow" :class="{ 'rotate': isDropdownShow }"></span>
</div>
<div class="dropdown-options" v-if="isDropdownShow">
<div class="dropdown-option" v-for="(item, index) in profitOptions" :key="index"
@click.stop="selectProfit(item)">
{{ item }}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="lineBottom" style="height: 100%; width: 1590px">
<!-- 传递筛选后的数据给图表组件 -->
<costBaseBarChart :yName="yName" :chartData="filteredData" style="height: 99%; width: 1590px" />
</div>
</div>
</template>
<script>
import costBaseBarChart from './costBaseBarChart.vue';
export default {
name: "Container",
components: { costBaseBarChart },
props: ['dateData', 'yName', 'categoryData'],
data() {
return {
isDropdownShow: false,
selectedProfit: null, // 选中的名称初始为null
};
},
computed: {
// 从categoryData中提取name作为下拉选项
profitOptions() {
return this.categoryData.map(item => item.name) || [];
},
// 根据选中的名称筛选数据
filteredData() {
if (!this.selectedProfit || !this.categoryData.length) {
// 未选择时默认取第一个分类的数据(或空)
return this.categoryData[0] || {};
}
// 找到选中名称对应的分类数据
return this.categoryData.find(item => item.name === this.selectedProfit) || {};
}
},
watch: {
categoryData: {
handler() {
// 当分类数据变化时,若没有选中项则默认选中第一个
if (this.categoryData.length && !this.selectedProfit) {
this.selectedProfit = this.categoryData[0].name;
}
},
deep: true,
immediate: true
}
},
methods: {
selectProfit(item) {
this.selectedProfit = item;
this.isDropdownShow = false;
}
},
mounted() {
// 点击外部关闭下拉菜单
const handleOutsideClick = (e) => {
if (!this.$el.contains(e.target)) {
this.isDropdownShow = false;
}
};
document.addEventListener('click', handleOutsideClick);
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('click', handleOutsideClick);
});
}
};
</script>
<style scoped lang="scss">
/* 原有样式保持不变 */
.coreBar {
display: flex;
flex-direction: column;
width: 100%;
padding: 12px;
.barTop {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 16px;
width: 100%;
.right-container {
display: flex;
align-items: center;
gap: 24px;
}
.legend {
display: flex;
gap: 16px;
align-items: center;
margin: 0;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.8);
text-align: left;
font-style: normal;
white-space: nowrap;
}
.legend-icon {
display: inline-block;
}
.legend-icon.square {
width: 8px;
height: 8px;
}
.target {
background: #2889FF;
}
.achieved {
background: rgba(40, 203, 151, 1);
}
.button-group {
display: flex;
position: relative;
gap: 2px;
align-items: center;
height: 24px;
background: #ecf4fe;
margin: 0;
.dropdown-container {
position: relative;
z-index: 10;
}
.item-button {
cursor: pointer;
height: 24px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 12px;
line-height: 24px;
font-style: normal;
letter-spacing: 2px;
padding: 0 24px 0 12px;
overflow: hidden;
.item-text {
display: inline-block;
}
}
.category-btn {
width: 88px;
border-top-left-radius: 12px;
border-bottom-left-radius: 12px;
background: #ffffff;
color: #0b58ff;
text-align: center;
}
.profit-btn {
width: 102px;
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
position: relative;
background: #ffffff;
color: #0b58ff;
text-align: left;
&.active {
background: #3071ff;
color: rgba(249, 252, 255, .8);
}
.profit-text {
text-align: left;
width: 100%;
}
}
.dropdown-arrow {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
width: 0;
height: 0;
border-left: 6px solid currentColor;
border-top: 4px solid transparent;
border-bottom: 4px solid transparent;
border-right: 4px solid transparent;
transition: transform 0.2s ease;
&.rotate {
transform: rotate(90deg);
}
}
.dropdown-options {
position: absolute;
top: 100%;
right: 0;
margin-top: 2px;
width: 102px;
background: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
.dropdown-option {
padding: 6px 12px;
font-size: 12px;
color: #333;
cursor: pointer;
text-align: left;
letter-spacing: 1px;
&:hover {
background: #f5f7fa;
color: #3071ff;
}
}
}
}
}
}
</style>