mirror of
https://github.com/schroinerxy/cloud-mail.git
synced 2026-06-22 03:45:52 +08:00
844 lines
20 KiB
Vue
844 lines
20 KiB
Vue
<template>
|
||
<div v-if="analysisLoading" class="analysis-loading">
|
||
<loading />
|
||
</div>
|
||
<el-scrollbar v-else style="height: 100%;">
|
||
<div class="analysis" :key="boxKey">
|
||
<div class="number">
|
||
<div class="number-item">
|
||
<div class="top">
|
||
<div class="left">
|
||
<div>收件数量</div>
|
||
<div>
|
||
<el-statistic :formatter="value => Math.round(value)" :value="receiveData"/>
|
||
</div>
|
||
</div>
|
||
<div class="right">
|
||
<div class="count-icon">
|
||
<Icon icon="hugeicons:mailbox-01" width="25" height="25"></Icon>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="delete-ratio">
|
||
<div>正常 <span class="normal">{{numberCount.normalReceiveTotal}}</span></div>
|
||
<div>删除 <span class="deleted">{{numberCount.delReceiveTotal}}</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="number-item">
|
||
<div class="top">
|
||
<div class="left">
|
||
<div>发件数量</div>
|
||
<div>
|
||
<el-statistic :formatter="value => Math.round(value)" :value="sendData"/>
|
||
</div>
|
||
</div>
|
||
<div class="right">
|
||
<div class="count-icon">
|
||
<Icon icon="cil:send" width="25" height="25"></Icon>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="delete-ratio">
|
||
<div>正常 <span class="normal">{{numberCount.normalSendTotal}}</span></div>
|
||
<div>删除 <span class="deleted">{{numberCount.delSendTotal}}</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="number-item">
|
||
<div class="top">
|
||
<div class="left">
|
||
<div>邮箱数量</div>
|
||
<div>
|
||
<el-statistic :formatter="value => Math.round(value)" :value="accountData"/>
|
||
</div>
|
||
</div>
|
||
<div class="right">
|
||
<div class="count-icon">
|
||
<Icon icon="lets-icons:e-mail" width="23" height="23"></Icon>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="delete-ratio">
|
||
<div>正常 <span class="normal">{{numberCount.normalAccountTotal}}</span></div>
|
||
<div>删除 <span class="deleted">{{numberCount.delAccountTotal}}</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="number-item">
|
||
<div class="top">
|
||
<div class="left">
|
||
<div>用户数量</div>
|
||
<div>
|
||
<el-statistic :formatter="value => Math.round(value)" :value="userData"/>
|
||
</div>
|
||
</div>
|
||
<div class="right">
|
||
<div class="count-icon">
|
||
<Icon icon="iconoir:user" width="25" height="25"></Icon>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="delete-ratio">
|
||
<div>正常 <span class="normal">{{numberCount.normalUserTotal}}</span></div>
|
||
<div>删除 <span class="deleted">{{numberCount.delUserTotal}}</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="picture">
|
||
<div class="picture-item">
|
||
<div class="title" style="display: flex;justify-content: space-between;">
|
||
<span>邮件来源</span>
|
||
<span class="source-button" v-if="false">
|
||
<el-radio-group v-model="checkedSourceType" >
|
||
<el-radio-button label="发件人" value="sender" />
|
||
<el-radio-button label="邮箱" value="email" />
|
||
</el-radio-group>
|
||
</span>
|
||
</div>
|
||
<div class="sender-pie">
|
||
|
||
</div>
|
||
</div>
|
||
<div class="picture-item">
|
||
<div class="title">用户增长</div>
|
||
<div class="increase-line">
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="picture-cs">
|
||
<div class="picture-cs-item">
|
||
<div class="title">邮件增长</div>
|
||
<div class="email-column"></div>
|
||
</div>
|
||
<div class="picture-cs-item">
|
||
<div class="title">今日发件</div>
|
||
<div class="send-count"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-scrollbar>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {Icon} from "@iconify/vue";
|
||
import {useTransition} from "@vueuse/core";
|
||
import {defineOptions, onActivated, onDeactivated, onMounted, reactive, ref, watch} from "vue";
|
||
import echarts from "@/echarts/index.js";
|
||
import dayjs from "dayjs";
|
||
import {analysisEcharts} from "@/request/analysis.js";
|
||
import {useUiStore} from "@/store/ui.js";
|
||
import {debounce} from "lodash-es";
|
||
import loading from "@/components/loading/index.vue";
|
||
import {useRoute} from "vue-router";
|
||
|
||
defineOptions({
|
||
name: 'analysis'
|
||
})
|
||
|
||
const route = useRoute();
|
||
const uiStore = useUiStore()
|
||
const checkedSourceType = ref('sender')
|
||
const receiveTotal = ref(0)
|
||
const sendTotal = ref(0)
|
||
const accountTotal = ref(0)
|
||
const userTotal = ref(0)
|
||
const analysisLoading = ref(true)
|
||
|
||
const numberCount = reactive({
|
||
normalReceiveTotal: 0,
|
||
normalSendTotal: 0,
|
||
normalAccountTotal: 0,
|
||
normalUserTotal: 0,
|
||
delReceiveTotal: 0,
|
||
delSendTotal: 0,
|
||
delAccountTotal: 0,
|
||
delUserTotal: 0
|
||
})
|
||
|
||
|
||
const receiveData = useTransition(receiveTotal, {
|
||
duration: 1500,
|
||
})
|
||
|
||
const sendData = useTransition(sendTotal, {
|
||
duration: 1500,
|
||
})
|
||
|
||
const accountData = useTransition(accountTotal, {
|
||
duration: 1500,
|
||
})
|
||
|
||
const userData = useTransition(userTotal, {
|
||
duration: 1500,
|
||
})
|
||
|
||
const senderData = ref(null)
|
||
const userLineData = reactive({
|
||
xdata: [],
|
||
sdata: []
|
||
})
|
||
|
||
const emailColumnData = {
|
||
barWidth: window.innerWidth > 767 ? '40%' : '60%',
|
||
receiveData: [],
|
||
sendData: [],
|
||
daysData: []
|
||
}
|
||
|
||
let daySendTotal = 0
|
||
let leaveWidth = 0
|
||
let senderPie = null
|
||
let increaseLine = null
|
||
let emailColumn = null
|
||
let sendGauge = null
|
||
let first = true
|
||
let boxKey = ref(0)
|
||
let senderPieLeft = window.innerWidth < 500 ? `${window.innerWidth - 110}` : '72%'
|
||
|
||
onMounted(() => {
|
||
analysisEcharts().then(data => {
|
||
receiveTotal.value = data.numberCount.receiveTotal
|
||
sendTotal.value = data.numberCount.sendTotal
|
||
accountTotal.value = data.numberCount.accountTotal
|
||
userTotal.value = data.numberCount.userTotal
|
||
numberCount.normalReceiveTotal = data.numberCount.normalReceiveTotal
|
||
numberCount.normalSendTotal = data.numberCount.normalSendTotal
|
||
numberCount.normalAccountTotal = data.numberCount.normalAccountTotal
|
||
numberCount.normalUserTotal = data.numberCount.normalUserTotal
|
||
numberCount.delReceiveTotal = data.numberCount.delReceiveTotal
|
||
numberCount.delSendTotal = data.numberCount.delSendTotal
|
||
numberCount.delAccountTotal = data.numberCount.delAccountTotal
|
||
numberCount.delUserTotal = data.numberCount.delUserTotal
|
||
senderData.value = data.receiveRatio.nameRatio.map(item => {
|
||
return {
|
||
name: item.name || ' ',
|
||
value: item.total
|
||
}
|
||
})
|
||
|
||
userLineData.xdata = data.userDayCount.map(item => dayjs(item.date).format("M.D"))
|
||
userLineData.sdata = data.userDayCount.map(item => item.total)
|
||
|
||
emailColumnData.daysData = data.emailDayCount.receiveDayCount.map(item => dayjs(item.date).format("M.D"))
|
||
emailColumnData.receiveData = data.emailDayCount.receiveDayCount.map(item => item.total)
|
||
emailColumnData.sendData = data.emailDayCount.sendDayCount.map(item => item.total)
|
||
|
||
daySendTotal = data.daySendTotal
|
||
analysisLoading.value = false
|
||
initPicture();
|
||
first = false
|
||
})
|
||
|
||
})
|
||
|
||
function initPicture() {
|
||
if(route.name !== 'analysis') return
|
||
boxKey.value ++
|
||
setTimeout(() => {
|
||
createSenderPie()
|
||
createIncreaseLine()
|
||
createEmailColumnChart();
|
||
createSendGauge();
|
||
})
|
||
}
|
||
|
||
const widthChange = debounce(initPicture, 500, {
|
||
leading: false,
|
||
trailing: true
|
||
})
|
||
|
||
|
||
watch(() => uiStore.asideShow, () => {
|
||
if (window.innerWidth > 1024) {
|
||
widthChange()
|
||
}
|
||
})
|
||
|
||
onActivated(() => {
|
||
if (first) return
|
||
if (window.innerWidth !== leaveWidth && leaveWidth !== 0) {
|
||
widthChange()
|
||
} else if (!senderPie) {
|
||
widthChange()
|
||
}
|
||
})
|
||
|
||
onDeactivated(() => {
|
||
leaveWidth = window.innerWidth
|
||
})
|
||
|
||
window.onresize = () => {
|
||
setStyle()
|
||
widthChange()
|
||
}
|
||
|
||
function setStyle() {
|
||
senderPieLeft = window.innerWidth < 500 ? `${window.innerWidth - 110}` : '72%'
|
||
emailColumnData.barWidth = window.innerWidth > 767 ? '40%' : '60%'
|
||
}
|
||
|
||
const measureCtx = document.createElement('canvas').getContext('2d');
|
||
measureCtx.font = '12px sans-serif';
|
||
|
||
function truncateTextByWidth(text,maxWidth = 140) {
|
||
|
||
let width = measureCtx.measureText(text).width;
|
||
if (width <= maxWidth) return text;
|
||
|
||
let result = '';
|
||
for (let i = 0; i < text.length; i++) {
|
||
result += text[i];
|
||
if (measureCtx.measureText(result + '…').width > maxWidth) {
|
||
return result.slice(0, -1) + '…';
|
||
}
|
||
}
|
||
return text;
|
||
}
|
||
|
||
function createSenderPie() {
|
||
|
||
if (senderPie) {
|
||
senderPie.dispose()
|
||
}
|
||
|
||
senderPie = echarts.init(document.querySelector(".sender-pie"))
|
||
let option = {
|
||
tooltip: {
|
||
trigger: 'item',
|
||
formatter: params => {
|
||
return `${params.marker} ${params.name}: ${params.value} (${params.percent}%)`;
|
||
}
|
||
},
|
||
legend: {
|
||
type: 'scroll',
|
||
orient: 'vertical',
|
||
left: '10',
|
||
top: '20',
|
||
formatter: function (name) {
|
||
return truncateTextByWidth(name)
|
||
}
|
||
},
|
||
series: [
|
||
{
|
||
data: senderData.value,
|
||
name: '',
|
||
type: 'pie',
|
||
radius: ['40%', '65%'],
|
||
center: [ senderPieLeft, '45%'],
|
||
avoidLabelOverlap: false,
|
||
itemStyle: {
|
||
borderRadius: 4,
|
||
borderColor: '#fff',
|
||
borderWidth: 2
|
||
},
|
||
label: {
|
||
show: false,
|
||
position: 'outside', // 标签显示在外部
|
||
formatter: '{d}%', // 显示名称和占比
|
||
color: '#333',
|
||
fontSize: 14 // 设置字体大小
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: false,
|
||
fontSize: 40,
|
||
fontWeight: 'bold'
|
||
}
|
||
},
|
||
labelLine: {
|
||
show: true
|
||
},
|
||
color: ['#3CB2FF', '#13DEB9', '#FBBF24', '#FF7F50', '#BAE6FD', '#C084FC'] // 添加符合主题的配色
|
||
}
|
||
]
|
||
}
|
||
senderPie.setOption(option)
|
||
}
|
||
|
||
function createIncreaseLine() {
|
||
|
||
if (increaseLine) {
|
||
increaseLine.dispose()
|
||
}
|
||
|
||
increaseLine = echarts.init(document.querySelector(".increase-line"))
|
||
|
||
let option = {
|
||
tooltip: {
|
||
trigger: 'axis', // 设置触发方式为 'axis',在坐标轴上显示信息
|
||
axisPointer: {
|
||
type: 'cross', // 指示器的类型为交叉型,适用于折线图等
|
||
crossStyle: {
|
||
color: '#999' // 设置指示器线的颜色
|
||
},
|
||
axis: 'x',
|
||
},
|
||
formatter: function (params) {
|
||
let result = ''
|
||
params.forEach(item => {
|
||
result = `${item.marker} 用户数: ${item.value}`;
|
||
});
|
||
return result;
|
||
},
|
||
backgroundColor: '#fff', // 设置背景颜色
|
||
borderColor: '#ccc', // 设置边框颜色
|
||
borderWidth: 1, // 设置边框宽度
|
||
padding: 10, // 设置内边距
|
||
textStyle: {
|
||
color: '#333', // 设置文字颜色
|
||
}
|
||
},
|
||
grid: {
|
||
top: '8%',
|
||
right: '20',
|
||
left: '35',
|
||
bottom: '35'
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: userLineData.xdata,
|
||
axisTick: {
|
||
show: false,
|
||
alignWithLabel: false, // 刻度线与标签对齐,
|
||
lineStyle: {
|
||
color: 'red',
|
||
}
|
||
},
|
||
axisPointer: {
|
||
label: {
|
||
show: false
|
||
}
|
||
},
|
||
axisLine: {
|
||
lineStyle: {
|
||
color: '#909399',
|
||
width: 1,
|
||
type: 'solid'
|
||
}
|
||
},
|
||
axisLabel: {
|
||
formatter: function (value, index) {
|
||
if (index === 0) {
|
||
return ' ' + value;
|
||
}
|
||
if (index === userLineData.xdata.length - 1) {
|
||
return value + ' '
|
||
}
|
||
return value;
|
||
},
|
||
},
|
||
boundaryGap: false,
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
axisLabel: {
|
||
margin: 5, // 增加y轴刻度数字与网格线之间的间距
|
||
},
|
||
boundaryGap: [0, 0.1],
|
||
max: (params) => {
|
||
if (params.max < 8 ) {
|
||
return 10
|
||
}
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#909399',
|
||
width: 1,
|
||
}
|
||
},
|
||
axisPointer: {
|
||
label: {
|
||
show: true,
|
||
formatter: (e) => {
|
||
return Math.round(e.value)
|
||
}
|
||
}
|
||
},
|
||
splitLine: {
|
||
show: true, // 显示网格线
|
||
lineStyle: {
|
||
type: 'dashed', // 设置网格线为虚线
|
||
color: '#ccc' // 设置虚线的颜色
|
||
}
|
||
}
|
||
},
|
||
series: [
|
||
{
|
||
|
||
data: userLineData.sdata,
|
||
type: 'line',
|
||
smooth: 0.1,
|
||
symbol: 'none',
|
||
lineStyle: {
|
||
color: '#1D84FF',
|
||
width: 2.5
|
||
},
|
||
areaStyle: {
|
||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||
{
|
||
offset: 0,
|
||
color: 'rgba(29, 132, 255, 0.3)'
|
||
},
|
||
{
|
||
offset: 1,
|
||
color: 'rgba(29, 132, 255, 0.03)'
|
||
}
|
||
])
|
||
},
|
||
color: ['#1D84FF'],
|
||
}
|
||
]
|
||
};
|
||
increaseLine.setOption(option);
|
||
}
|
||
|
||
function createEmailColumnChart() {
|
||
|
||
if (emailColumn) {
|
||
emailColumn.dispose()
|
||
}
|
||
|
||
emailColumn = echarts.init(document.querySelector(".email-column"));
|
||
|
||
const option = {
|
||
tooltip: {
|
||
formatter: function (params) {
|
||
params.marker
|
||
return `${params.marker} ${params.seriesName}: ${params.value}`
|
||
}
|
||
},
|
||
legend: {
|
||
data: ['接收', '发送'],
|
||
top: '0'
|
||
},
|
||
grid: {
|
||
left: '18',
|
||
right: '18',
|
||
bottom: '15',
|
||
top: '50',
|
||
containLabel: true
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: emailColumnData.daysData,
|
||
axisTick: {
|
||
show: false
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#909399',
|
||
width: 1,
|
||
}
|
||
},
|
||
},
|
||
yAxis: {
|
||
max: (params) => {
|
||
if (params.max < 8 ) {
|
||
return 10
|
||
}
|
||
},
|
||
type: 'value',
|
||
boundaryGap: [0, 0.1],
|
||
},
|
||
series: [
|
||
{
|
||
name: '接收',
|
||
type: 'bar',
|
||
stack: 'total', // 堆叠组标识(必须相同)
|
||
barWidth: emailColumnData.barWidth,
|
||
emphasis: {
|
||
itemStyle: {
|
||
shadowBlur: 10,
|
||
shadowColor: 'rgba(0,0,0,0.3)',
|
||
}
|
||
},
|
||
data: emailColumnData.receiveData,
|
||
itemStyle: {
|
||
color: '#3CB2FF',
|
||
}
|
||
},
|
||
{
|
||
name: '发送',
|
||
type: 'bar',
|
||
stack: 'total', // 堆叠组标识(必须相同)
|
||
barWidth: '45%',
|
||
emphasis: {
|
||
itemStyle: {
|
||
shadowBlur: 10,
|
||
shadowColor: 'rgba(0,0,0,0.3)'
|
||
}
|
||
},
|
||
data: emailColumnData.sendData,
|
||
itemStyle: {
|
||
color: '#13deb9',
|
||
}
|
||
}
|
||
]
|
||
};
|
||
|
||
emailColumn.setOption(option);
|
||
}
|
||
|
||
function createSendGauge() {
|
||
if(sendGauge) {
|
||
sendGauge.dispose()
|
||
}
|
||
sendGauge = echarts.init(document.querySelector(".send-count"));
|
||
let option = {
|
||
tooltip: {},
|
||
series: [{
|
||
name: '今日发件',
|
||
type: 'gauge',
|
||
max: 100,
|
||
// 进度条颜色(新增)
|
||
progress: {
|
||
show: true,
|
||
roundCap: true,
|
||
itemStyle: {
|
||
color: '#3CB2FF'
|
||
}
|
||
},
|
||
// 指针颜色(新增)
|
||
pointer: {
|
||
itemStyle: {
|
||
color: '#3CB2FF'
|
||
}
|
||
},
|
||
// 轴线背景色(新增)
|
||
axisLine: {
|
||
roundCap: true,
|
||
lineStyle: {
|
||
color: [[1, '#E6EBF8']]
|
||
}
|
||
},
|
||
// 刻度颜色(新增)
|
||
axisTick: {
|
||
lineStyle: {
|
||
color: '#999'
|
||
}
|
||
},
|
||
// 中心文字颜色(新增)
|
||
detail: {
|
||
valueAnimation: true,
|
||
formatter: '{value}',
|
||
color: '#333' // 黑色文字
|
||
},
|
||
data: [{
|
||
value: daySendTotal,
|
||
name: '次数',
|
||
// 名称标签颜色(新增)
|
||
title: {
|
||
color: '#333' // 灰色标签
|
||
}
|
||
}]
|
||
}],
|
||
color: ['#3CB2FF']
|
||
};
|
||
sendGauge.setOption(option);
|
||
}
|
||
|
||
|
||
</script>
|
||
<style>
|
||
.percentage-value {
|
||
display: block;
|
||
margin-top: 10px;
|
||
font-size: 28px;
|
||
}
|
||
.percentage-label {
|
||
display: block;
|
||
margin-top: 10px;
|
||
font-size: 12px;
|
||
}
|
||
</style>
|
||
<style scoped lang="scss">
|
||
.analysis-loading {
|
||
height: 100%;
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.analysis {
|
||
height: 100%;
|
||
padding: 20px 20px 30px;
|
||
gap: 20px;
|
||
background: #FAFCFF;
|
||
display: grid;
|
||
grid-auto-rows: min-content;
|
||
@media (max-width: 1024px) {
|
||
padding: 15px 15px 30px;
|
||
gap: 15px
|
||
}
|
||
.title {
|
||
margin-top: 10px;
|
||
margin-left: 15px;
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
}
|
||
.number {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||
gap: 20px;
|
||
@media (max-width: 1024px) {
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 15px;
|
||
}
|
||
@media (max-width: 767px) {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
.number-item {
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
border: 1px solid var(--el-border-color);
|
||
padding: 25px 20px;
|
||
.top {
|
||
display: grid;
|
||
justify-content: space-between;
|
||
align-content: center;
|
||
grid-template-columns: auto auto;
|
||
|
||
.left {
|
||
display: grid;
|
||
gap: 5px;
|
||
grid-auto-rows: min-content;
|
||
|
||
> div:last-child {
|
||
font-size: 13px;
|
||
}
|
||
|
||
:deep(.el-statistic__number) {
|
||
font-size: 26px;
|
||
}
|
||
}
|
||
|
||
.right {
|
||
display: grid;
|
||
align-items: center;
|
||
.count-icon {
|
||
top: 3px;
|
||
position: relative;
|
||
display: grid;
|
||
align-items: center;
|
||
padding: 14px;
|
||
border-radius: 8px;
|
||
background: var(--el-color-primary-light-9);
|
||
color: var(--el-color-primary);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
.delete-ratio {
|
||
width: 100%;
|
||
display: grid;
|
||
grid-template-columns: auto auto;
|
||
justify-content: start;
|
||
gap: 20px;
|
||
padding-top: 5px;
|
||
.normal {
|
||
width: fit-content;
|
||
color: var(--el-color-success);
|
||
font-weight: bold;
|
||
margin-left: 3px;
|
||
}
|
||
|
||
.deleted {
|
||
width: fit-content;
|
||
color: var(--el-color-danger);
|
||
font-weight: bold;
|
||
margin-left: 3px;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
.picture {
|
||
display: grid;
|
||
grid-template-columns: 500px 1fr;
|
||
gap: 20px;
|
||
@media (max-width: 1620px) {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
@media (max-width: 1024px) {
|
||
gap: 15px;
|
||
}
|
||
.picture-item {
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
border: 1px solid var(--el-border-color);
|
||
.source-button {
|
||
padding-right: 15px;
|
||
display: flex;
|
||
align-items: start;
|
||
:deep(.el-radio-button__inner) {
|
||
padding: 6px 10px;
|
||
}
|
||
}
|
||
.sender-pie {
|
||
height: 350px;
|
||
@media (max-width: 767px) {
|
||
height: 200px;
|
||
}
|
||
}
|
||
.increase-line {
|
||
height: 350px;
|
||
@media (max-width: 767px) {
|
||
height: 280px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.picture-cs {
|
||
display: grid;
|
||
grid-template-columns: 1fr 500px;
|
||
gap: 20px;
|
||
@media (max-width: 1620px) {
|
||
grid-template-columns: 1fr;
|
||
gap: 15px;
|
||
}
|
||
.picture-cs-item {
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
border: 1px solid var(--el-border-color);
|
||
.send-count {
|
||
height: 350px;
|
||
@media (max-width: 767px) {
|
||
height: 320px;
|
||
}
|
||
}
|
||
.email-column {
|
||
height: 350px;
|
||
@media (max-width: 767px) {
|
||
height: 250px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
</style>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|