fix: 客户分析页面样式调整
This commit is contained in:
parent
5127607c14
commit
077750fffd
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue