fix: 客户分析页面样式调整

This commit is contained in:
lzhizhao 2025-10-01 22:12:12 +08:00
parent 5127607c14
commit 077750fffd
1 changed files with 245 additions and 138 deletions

View File

@ -21,26 +21,6 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="统计类型">
<el-select
style="margin-right: 20px"
v-model="formInline.elementType"
placeholder="请选择统计类型"
>
<el-option
v-for="item in [
{ value: '1', label: '浏览数量' },
{ value: '2', label: '浏览人数' },
{ value: '3', label: '新客数量' },
{ value: '4', label: '支付订单人数' },
]"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button @click="getList" type="primary">查询</el-button> <el-button @click="getList" type="primary">查询</el-button>
<el-button @click="batchExport" type="success">导出</el-button> <el-button @click="batchExport" type="success">导出</el-button>
@ -49,104 +29,108 @@
</div> </div>
<div class="stat-list"> <div class="stat-list">
<div class="stat-item"> <div class="stat-item">
<i style="font-size: 22px" class="el-icon-camera-solid"></i> <div class="stat-icon-wrapper icon-1">
<i class="el-icon-view"></i>
</div>
<div class="stat-right"> <div class="stat-right">
<div class="stat-title">展现量 </div> <div class="stat-title">展现量 ()</div>
<div class="stat-value"> <div class="stat-value">
<span style="font-size: 20px">{{ <span class="value-main">{{ analysis.viewCount || "0" }}</span>
analysis.viewCount ? analysis.viewCount : "0"
}}</span>
<span <span
v-if="analysis.viewCountRatio < '0%'" class="value-ratio"
style="font-size: 16px; margin: 0 5px; color: green" v-if="analysis.viewCountRatio"
></span :class="getRatioClass(analysis.viewCountRatio)"
> >
<span style="font-size: 16px; margin: 0 5px; color: red" v-else <i :class="getRatioIcon(analysis.viewCountRatio)"></i>
></span {{ analysis.viewCountRatio }}
> </span>
<span style="font-size: 16px">{{ analysis.viewCountRatio }}</span>
</div> </div>
</div> </div>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<i style="font-size: 22px" class="el-icon-user-solid"></i> <div class="stat-icon-wrapper icon-2">
<i class="el-icon-user"></i>
</div>
<div class="stat-right"> <div class="stat-right">
<div class="stat-title">浏览人数 </div> <div class="stat-title">浏览人数 ()</div>
<div class="stat-value"> <div class="stat-value">
<span style="font-size: 20px">{{ analysis.peopleCount }}</span> <span class="value-main">{{ analysis.peopleCount || "0" }}</span>
<span <span
v-if="analysis.peopleCountRatio < '0%'" class="value-ratio"
style="font-size: 16px; margin: 0 5px; color: green" v-if="analysis.peopleCountRatio"
></span :class="getRatioClass(analysis.peopleCountRatio)"
> >
<span style="font-size: 16px; margin: 0 5px; color: red" v-else <i :class="getRatioIcon(analysis.peopleCountRatio)"></i>
></span {{ analysis.peopleCountRatio }}
> </span>
<span style="font-size: 16px">{{ analysis.peopleCountRatio }}</span>
</div> </div>
</div> </div>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<i style="font-size: 22px" class="el-icon-user-solid"></i> <div class="stat-icon-wrapper icon-3">
<i class="el-icon-star-off"></i>
</div>
<div class="stat-right"> <div class="stat-right">
<div class="stat-title">新客数量 </div> <div class="stat-title">新客数量 ()</div>
<div class="stat-value"> <div class="stat-value">
<span style="font-size: 20px">{{ <span class="value-main">{{
analysis.newPeopleCount ? analysis.newPeopleCount : "0" analysis.newPeopleCount || "0"
}}</span> }}</span>
<span <span
v-if="analysis.newPeopleCountRatio < '0%'" class="value-ratio"
style="font-size: 16px; margin: 0 5px; color: green" v-if="analysis.newPeopleCountRatio"
></span :class="getRatioClass(analysis.newPeopleCountRatio)"
> >
<span style="font-size: 16px; margin: 0 5px; color: red" v-else <i :class="getRatioIcon(analysis.newPeopleCountRatio)"></i>
></span {{ analysis.newPeopleCountRatio }}
> </span>
<span style="font-size: 16px">{{ </div>
analysis.newPeopleCountRatio </div>
</div>
<div class="stat-item">
<div class="stat-icon-wrapper icon-4">
<i class="el-icon-s-custom"></i>
</div>
<div class="stat-right">
<div class="stat-title">支付订单人数 ()</div>
<div class="stat-value">
<span class="value-main">{{ analysis.payCount || "0" }}</span>
</div>
</div>
</div>
<div class="stat-item">
<div class="stat-icon-wrapper icon-5">
<i class="el-icon-s-order"></i>
</div>
<div class="stat-right">
<div class="stat-title">支付订单转化率 (%)</div>
<div class="stat-value">
<span class="value-main">{{
analysis.payConversion || "0"
}}</span> }}</span>
</div> </div>
</div> </div>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<i style="font-size: 22px" class="el-icon-user-solid"></i> <div class="stat-icon-wrapper icon-6">
<i class="el-icon-refresh"></i>
</div>
<div class="stat-right"> <div class="stat-right">
<div class="stat-title">支付订单人数 </div> <div class="stat-title">客户复购率 (%)</div>
<div style="font-size: 20px" class="stat-value"> <div class="stat-value">
{{ analysis.payCount ? analysis.payCount : "0" }} <span class="value-main">{{
</div> analysis.repurchaseRate || "0"
</div> }}</span>
</div>
<div class="stat-item">
<i style="font-size: 22px" class="el-icon-s-order"></i>
<div class="stat-right">
<div class="stat-title">支付订单转化率 %</div>
<div style="font-size: 20px" class="stat-value">
{{ analysis.payConversion ? analysis.payConversion : "0" }}
</div>
</div>
</div>
<div class="stat-item">
<i style="font-size: 22px" class="el-icon-s-order"></i>
<div class="stat-right">
<div class="stat-title">客户复购率 %</div>
<div style="font-size: 20px" class="stat-value">
{{ analysis.repurchaseRate ? analysis.repurchaseRate : "0" }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<el-row class="echarts-line"> <div class="echarts-grid">
<div <div class="echarts-item" id="echarts-LineChart-1"></div>
id="echarts-LineChart" <div class="echarts-item" id="echarts-LineChart-2"></div>
style=" <div class="echarts-item" id="echarts-LineChart-3"></div>
width: 100%; <div class="echarts-item" id="echarts-LineChart-4"></div>
height: calc(100vh - 500px); </div>
margin-top: 20px;
border: 1px solid #ccc;
"
/>
</el-row>
</div> </div>
</template> </template>
@ -162,94 +146,136 @@ export default {
value: "", value: "",
formInline: { formInline: {
dateType: "1", dateType: "1",
elementType: "1",
}, },
analysis: {}, analysis: {},
trend: [], trend: [],
charts: [], // ECharts
}; };
}, },
mounted() { mounted() {
this.getList(); this.getList();
}, },
beforeDestroy() {
// ECharts
this.charts.forEach((chart) => {
chart.dispose();
});
},
methods: { methods: {
getList() { getList() {
console.log("1213");
this.$api.dataCenter this.$api.dataCenter
.customerAnalysis({ dateType: this.formInline.dateType }) .customerAnalysis({ dateType: this.formInline.dateType })
.then((res) => { .then((res) => {
this.analysis = res.data.data; this.analysis = res.data.data;
}); });
this.$api.dataCenter.customerTrend(this.formInline).then((res) => {
this.trend = res.data.data; const elementTypes = ["1", "2", "3", "4"];
this.init(res.data.data); const chartPromises = elementTypes.map((type) =>
}); this.$api.dataCenter.customerTrend({ ...this.formInline, elementType: type })
},
init(data) {
this.$nextTick(() => {
// 线
const myChat = echarts.init(
document.getElementById("echarts-LineChart")
); );
myChat.setOption(this.LineChart(data));
window.addEventListener("resize", () => { Promise.all(chartPromises).then((responses) => {
myChat.resize(); const chartData = responses.map((res) => res.data.data);
}); this.init(chartData);
}); });
}, },
LineChart(data) { init(allData) {
//
this.charts.forEach((chart) => {
chart.dispose();
});
this.charts = [];
const titles = ["浏览数量", "浏览人数", "新客数量", "支付订单人数"];
const colors = ["#5470C6", "#91CC75", "#FAC858", "#EE6666"];
this.$nextTick(() => {
allData.forEach((data, index) => {
const chartDom = document.getElementById(
`echarts-LineChart-${index + 1}`
);
if (chartDom) {
const myChart = echarts.init(chartDom);
const options = this.LineChart(
data,
titles[index],
colors[index]
);
myChart.setOption(options);
this.charts.push(myChart);
}
});
window.addEventListener("resize", this.resizeCharts);
});
},
resizeCharts() {
this.charts.forEach((chart) => {
chart.resize();
});
},
LineChart(data, title, color) {
return { return {
title: { title: {
text: "数据趋势分析", text: title + "趋势",
left: "left",
}, },
tooltip: { tooltip: {
trigger: "axis", trigger: "axis",
}, },
legend: { legend: {
data: [this.elementTypeName(this.formInline.elementType)], data: [title],
top: "top",
right: "10",
}, },
grid: { grid: {
left: "3%", left: "3%",
right: "4%", right: "4%",
bottom: "3%", bottom: "3%",
top: "20%",
containLabel: true, containLabel: true,
}, },
toolbox: { toolbox: {
feature: { feature: {},
saveAsImage: {},
},
}, },
xAxis: { xAxis: {
type: "category", type: "category",
boundaryGap: false, boundaryGap: false,
data: data.map((item) => { data: data.map((item) => item.countDate),
return item.countDate;
}),
}, },
yAxis: { yAxis: {
type: "value", type: "value",
}, },
series: [ series: [
{ {
name: this.elementTypeName(this.formInline.elementType), name: title,
type: "line", type: "line",
stack: "Total", smooth: true,
data: data.map((item) => { stack: "Total", //
return item.value; data: data.map((item) => item.value),
}), itemStyle: {
color: color,
},
lineStyle: {
color: color,
},
areaStyle: {
color: color,
opacity: 0.3,
},
}, },
], ],
}; };
}, },
elementTypeName(row) { getRatioClass(ratio) {
if (row == "1") { if (!ratio || typeof ratio !== "string") return "";
return "浏览数量"; return ratio.startsWith("-") ? "is-down" : "is-up";
} else if (row == "2") { },
return "浏览人数"; getRatioIcon(ratio) {
} else if (row == "3") { if (!ratio || typeof ratio !== "string") return "";
return "新客数量"; return ratio.startsWith("-")
} else if (row == "4") { ? "el-icon-bottom-right"
return "支付订单人数"; : "el-icon-top-right";
}
}, },
async batchExport() { async batchExport() {
let trendData = this.trend.map((item) => { let trendData = this.trend.map((item) => {
@ -297,32 +323,113 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.stat-list { .stat-list {
display: flex; display: grid;
align-items: center; grid-template-columns: repeat(3, 1fr);
/* justify-content: space-between; */ gap: 20px;
flex-wrap: wrap;
margin-top: 20px; margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
} }
.stat-item { .stat-item {
width: 25%;
margin: 30px 30px;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 20px;
background-color: #f8f9fa;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
&:hover {
transform: translateY(-5px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
}
} }
.stat-icon {
background: rgb(99 152 252); .stat-icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 60px; width: 60px;
height: 60px; height: 60px;
border-radius: 3px; border-radius: 50%;
color: #fff;
font-size: 28px;
flex-shrink: 0;
&.icon-1 {
background: linear-gradient(45deg, #4facfe, #00f2fe);
}
&.icon-2 {
background: linear-gradient(45deg, #43e97b, #38f9d7);
}
&.icon-3 {
background: linear-gradient(45deg, #fa709a, #fee140);
}
&.icon-4 {
background: linear-gradient(45deg, #84fab0, #8fd3f4);
}
&.icon-5 {
background: linear-gradient(45deg, #a18cd1, #fbc2eb);
}
&.icon-6 {
background: linear-gradient(45deg, #ff9a9e, #fecfef);
}
} }
.stat-right { .stat-right {
margin-left: 12px; margin-left: 20px;
font-size: 18px; overflow: hidden;
} }
.stat-title { .stat-title {
color: #969696; color: #6c757d;
margin-bottom: 10px; font-size: 14px;
margin-bottom: 8px;
white-space: nowrap;
}
.stat-value {
display: flex;
align-items: baseline;
font-weight: bold;
.value-main {
font-size: 26px;
color: #343a40;
margin-right: 8px;
}
.value-ratio {
font-size: 14px;
display: flex;
align-items: center;
&.is-up {
color: #dc3545;
}
&.is-down {
color: #28a745;
}
i {
margin-right: 4px;
font-weight: bold;
}
}
}
.echarts-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-top: 30px;
}
.echarts-item {
height: 400px;
padding: 20px;
border: 1px solid #e9ecef;
border-radius: 8px;
background-color: #fff;
} }
</style> </style>