508 lines
12 KiB
Vue
508 lines
12 KiB
Vue
<template>
|
||
<div class="coreItem">
|
||
<!-- 单独渲染第一个item -->
|
||
<div class="item" v-for="(item, index) in itemList">
|
||
<div class="unit">{{ item.unit }}</div>
|
||
<div class="item-content">
|
||
<div class="content-wrapper">
|
||
<div class="left">
|
||
<div class="number">{{ item.targetValue }}</div>
|
||
<div class="title">预算值</div>
|
||
</div>
|
||
<div class="line"></div>
|
||
<div class="right">
|
||
<div class="number" :style="{ color: getColor(item.currentValue, item.targetValue) }">
|
||
{{ item.currentValue }}
|
||
</div>
|
||
<div class="title">实际值</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="progress-group">
|
||
<div class="progress-container">
|
||
<!-- 进度条颜色和宽度动态绑定 -->
|
||
<div class="progress-bar" :style="{
|
||
width: itemList[0].progress + '%',
|
||
background: getColor(item.progress)
|
||
}"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="yield" style="display: flex;justify-content: space-between;">
|
||
<div class="progress-percent">完成率</div>
|
||
<!-- 百分比颜色动态绑定 -->
|
||
<div class="progress-percent" :style="{
|
||
color: getColor(item.progress)
|
||
}">
|
||
{{ item.progress }}%
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="item" v-for="(item, index) in itemList2" :key="index" :style="index === 0 ? { width: '100%' } : {}">
|
||
<div class="unit">{{ item.unit }}</div>
|
||
<div class="item-content">
|
||
<div class="content-wrapper">
|
||
<div class="left">
|
||
<div class="number">{{ item.targetValue }}</div>
|
||
<div class="title">预算值</div>
|
||
</div>
|
||
<div class="line"></div>
|
||
<div class="right">
|
||
<div class="number" :style="{ color: getColor(item.currentValue, item.targetValue) }">
|
||
{{ item.currentValue }}
|
||
</div>
|
||
<div class="title">实际值</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="progress-group">
|
||
<div class="progress-container" :style="index === 0 ? { width: '100%' } : {}">
|
||
<!-- 进度条颜色和宽度动态绑定 -->
|
||
<div class="progress-bar" :style="{
|
||
width: itemList2[0].progress + '%',
|
||
background: getColor(item.progress)
|
||
}"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="yield" style="display: flex;justify-content: space-between;">
|
||
<div class="progress-percent">完成率</div>
|
||
<!-- 百分比颜色动态绑定 -->
|
||
<div class="progress-percent" :style="{
|
||
color: getColor(item.progress)
|
||
}">
|
||
{{ item.progress }}%
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: "Container",
|
||
components: {},
|
||
props: ["orderOutput","dateData"],
|
||
data() {
|
||
return {
|
||
progress: 90, // 进度值基础参数
|
||
itemList: [],
|
||
itemList2: []//7月以后得
|
||
};
|
||
},
|
||
watch: {
|
||
orderOutput: {
|
||
handler(newValue, oldValue) {
|
||
this.getItemData(newValue)
|
||
},
|
||
deep: true // 若对象内属性变化需触发,需加 deep: true
|
||
}
|
||
},
|
||
methods: {
|
||
getItemData(data) {
|
||
// 26年7月份以后用海外组的那个
|
||
if (this.dateData.startTime>=new Date('2026-07-01 00:00:00').getTime()) {
|
||
this.itemList2 = [
|
||
{
|
||
unit: "总进度",
|
||
targetValue: data.totalProgress.target,
|
||
currentValue: data.totalProgress.real,
|
||
progress: data.totalProgress.rate,
|
||
},
|
||
{
|
||
unit: "一组",
|
||
targetValue: data.group1.target,
|
||
currentValue: data.group1.real,
|
||
progress: data.group1.rate
|
||
},
|
||
{
|
||
unit: "二组",
|
||
targetValue: data.group2.target,
|
||
currentValue: data.group2.real,
|
||
progress: data.group2.rate
|
||
},
|
||
{
|
||
unit: "海外组",
|
||
targetValue: data.overseaGroup.target,
|
||
currentValue: data.overseaGroup.real,
|
||
progress: data.overseaGroup.rate
|
||
}
|
||
]
|
||
this.itemList = []
|
||
}else{
|
||
this.itemList = [
|
||
{
|
||
unit: "总进度",
|
||
targetValue: data.totalProgress.target,
|
||
currentValue: data.totalProgress.real,
|
||
progress: data.totalProgress.rate,
|
||
},
|
||
{
|
||
unit: "一组",
|
||
targetValue: data.group1.target,
|
||
currentValue: data.group1.real,
|
||
progress: data.group1.rate
|
||
},
|
||
{
|
||
unit: "二组",
|
||
targetValue: data.group2.target,
|
||
currentValue: data.group2.real,
|
||
progress: data.group2.rate
|
||
},
|
||
{
|
||
unit: "三组",
|
||
targetValue: data.group3.target,
|
||
currentValue: data.group3.real,
|
||
progress: data.group3.rate
|
||
},
|
||
{
|
||
unit: "四组",
|
||
targetValue: data.group4.target,
|
||
currentValue: data.group4.real,
|
||
progress: data.group4.rate
|
||
},
|
||
{
|
||
unit: "五组",
|
||
targetValue: data.group5.target,
|
||
currentValue: data.group5.real,
|
||
progress: data.group5.rate
|
||
}
|
||
]
|
||
this.itemList2 = []
|
||
}
|
||
},
|
||
// 颜色判断核心方法:实际值≥预算值返回绿色,否则返回橙色
|
||
getColor(progress) {
|
||
return progress >= 100
|
||
? "rgba(98, 213, 180, 1)"
|
||
: "rgba(249, 164, 74, 1)";
|
||
},
|
||
getTableData(data) {
|
||
this.$emit('handleShowTable',data)
|
||
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
/* 第一个item单独样式(可选) */
|
||
.item:first-of-type {
|
||
// background: #f0f7ff; /* 示例背景色 */
|
||
}
|
||
|
||
.coreItem {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
gap: 8px;
|
||
}
|
||
|
||
.item {
|
||
width: 227px;
|
||
height: 122px;
|
||
background: #f9fcff;
|
||
padding: 12px;
|
||
box-sizing: border-box;
|
||
|
||
.unit {
|
||
height: 18px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 18px;
|
||
color: #000000;
|
||
line-height: 18px;
|
||
letter-spacing: 1px;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.groupName {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 18px;
|
||
color: #000000;
|
||
line-height: 18px;
|
||
letter-spacing: 1px;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.left-target {
|
||
.number {
|
||
height: 22px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 600;
|
||
font-size: 24px;
|
||
color: rgba(103, 103, 103, 0.79);
|
||
line-height: 22px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
|
||
.title {
|
||
height: 14px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
color: #868687;
|
||
line-height: 14px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
|
||
.left-real {
|
||
.number {
|
||
height: 22px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 600;
|
||
font-size: 24px;
|
||
line-height: 22px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
/* 颜色由动态绑定控制,此处不设置固定值 */
|
||
}
|
||
|
||
.title {
|
||
height: 14px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
color: #868687;
|
||
line-height: 14px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
|
||
.right {
|
||
width: 100%;
|
||
.bg-default {
|
||
background-image: url("../../../assets/img/order-item-bg.png");
|
||
}
|
||
|
||
// 实际值 >= 预算值:绿色背景图
|
||
.bg-green {
|
||
background-image: url("../../../assets/img/order-item-greenbg.png");
|
||
}
|
||
.groupName {
|
||
width: 129px;
|
||
height: 32px;
|
||
// background: url(../../../assets/img/order-item-bg.png) no-repeat;
|
||
background-size: 100% 100%;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
color: #000000;
|
||
text-align: center;
|
||
|
||
.title {
|
||
margin-top: 10px;
|
||
height: 12px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
margin-right: 8px;
|
||
color: #000000;
|
||
line-height: 12px;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.unit {
|
||
margin-top: 10px;
|
||
margin-right: 14px;
|
||
height: 12px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
color: #000000;
|
||
line-height: 12px;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
|
||
.right-city {
|
||
.city {
|
||
height: 14px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
color: #575757;
|
||
line-height: 14px;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.title {
|
||
height: 14px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
color: #868687;
|
||
line-height: 14px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
}
|
||
|
||
.item-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
height: calc(100% - 26px);
|
||
}
|
||
|
||
.content-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
flex: 1;
|
||
}
|
||
|
||
.line {
|
||
width: 1px;
|
||
height: 46px;
|
||
background: linear-gradient(to bottom,
|
||
rgba(255, 0, 0, 0),
|
||
#cbcbcb);
|
||
}
|
||
|
||
.cityLine {
|
||
width: 1px;
|
||
margin-top: 40px;
|
||
height: 76px;
|
||
background: linear-gradient(to bottom,
|
||
rgba(255, 0, 0, 0),
|
||
#cbcbcb);
|
||
}
|
||
|
||
.left,
|
||
.right {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 2px;
|
||
flex: 1;
|
||
}
|
||
|
||
.number {
|
||
height: 22px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 600;
|
||
font-size: 24px;
|
||
color: rgba(103, 103, 103, 0.79);
|
||
line-height: 22px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
|
||
.title {
|
||
height: 14px;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
color: #868687;
|
||
line-height: 14px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
|
||
.progress-group {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.progress-container {
|
||
width: 230px;
|
||
height: 10px;
|
||
background: #ECEFF7;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.progress-bar {
|
||
height: 100%;
|
||
border-radius: 8px;
|
||
/* 背景色由动态绑定控制,移除固定值 */
|
||
}
|
||
|
||
.city-progress-group {
|
||
margin-top: 2px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.city-progress-container {
|
||
width: 112px;
|
||
height: 10px;
|
||
background: #ECEFF7;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.city-progress-bar {
|
||
height: 100%;
|
||
border-radius: 8px;
|
||
opacity: 1;
|
||
/* 背景色由动态绑定控制,移除固定值 */
|
||
}
|
||
|
||
.progress-percent {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 12px;
|
||
line-height: 1;
|
||
/* 颜色由动态绑定控制,此处不设置固定值 */
|
||
}
|
||
|
||
.yield {
|
||
margin-top: 3px;
|
||
}
|
||
|
||
.numerator {
|
||
/* 颜色由动态绑定控制,此处不设置固定值 */
|
||
}
|
||
|
||
.city-yield {
|
||
/* 颜色由动态绑定控制,此处不设置固定值 */
|
||
}
|
||
}
|
||
|
||
.groupData {
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 右上角折现边框(主边框) */
|
||
// .groupData::before {
|
||
// content: "";
|
||
// position: absolute;
|
||
// top: 0;
|
||
// left: 0;
|
||
// width: 100%;
|
||
// height: 100%;
|
||
// background-color: #000000;
|
||
// clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 20px, 100% 100%, 0 100%);
|
||
// }
|
||
|
||
/* 右上角折现细节 */
|
||
.groupData::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
width: 20px;
|
||
height: 20px;
|
||
background: #EFF3F8;
|
||
transform: rotate(-45deg) translate(50%, -50%);
|
||
transform-origin: top right;
|
||
}
|
||
</style>
|