根据网站集约化建设的要求百度搜索排行
涉及到日期组件封装,echarts柱状图、折线图、饼图(环形)的绘制,
1.柱状+折线图的option配置
//数据接入统计图表
const initAccessChat = () => {accessChartDom = echarts.init(accessChartEl.value)const accessOption = {grid: {left: '1%',right: '1%',bottom: '1%',top: '20%',containLabel: true,},legend: {itemHeight: 12,itemWidth: 12,itemGap: 30, // 图例元素间隔icon: 'rect', //方形top: '5%',data: ['路口', '智慧车辆'],},tooltip: {trigger: 'axis',backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景confine: true,extraCssText://额外附加到浮层的css样式,此处为为浮层添加阴影及padding'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',},xAxis: [{type: 'category',data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],axisPointer: {type: 'shadow',},},],yAxis: {type: 'value',},series: [{name: '路口',type: 'bar',barWidth: 16,itemStyle: {// 添加 itemStylecolor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [// 渐变方向:从上到下{ offset: 0, color: '#0EECE4' }, // 顶部颜色{ offset: 1, color: '#058FE7' }, // 底部颜色]),},data: [110, 50, 220, 200, 135, 135, 135],},{name: '智慧车辆',type: 'line',symbol: 'none',itemStyle: {color: '#FFD15C', // 明确指定系列颜色},lineStyle: {color: '#FFD15C',width: 3,},data: [110, 50, 220, 200, 135, 135, 135],},],}accessChartDom.setOption(accessOption)
}
2.需要绘制出圆弧渐变的线条,主要通过lineStyle去修改渐变由浅入深以及线条下方的阴影控制
const initDelChat = () => {delChartDom = echarts.init(delChartEl.value)const delOption = {grid: {left: '1%',right: '1%',bottom: '1%',top: '20%',containLabel: true,},tooltip: {trigger: 'axis',backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景confine: true,extraCssText://额外附加到浮层的css样式,此处为为浮层添加阴影及padding'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',},xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],},yAxis: {type: 'value',},legend: {itemHeight: 12,itemWidth: 12,itemGap: 30, // 图例元素间隔icon: 'rect', //方形top: '5%',data: ['日志', '视频', '图片', '轨迹数据'],},series: [{name: '日志',type: 'line',smooth: true,symbol: 'none',data: [120, 132, 101, 134, 90, 230, 210],itemStyle: {color: '#FEB729', // 明确指定系列颜色},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [// 渐变方向:从左到右{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#FEB729' },{ offset: 1, color: '#FEB729' },]),shadowColor: '#FEB729', // 阴影颜色shadowBlur: 8, // 阴影模糊程度shadowOffsetY: 2.5, //阴影向下偏移},},{name: '视频',type: 'line',smooth: true,symbol: 'none',data: [220, 182, 191, 234, 290, 330, 310],itemStyle: {color: '#4B85FF',},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#4B85FF' },{ offset: 1, color: '#4B85FF' },]),shadowColor: '#4B85FF',shadowBlur: 8,shadowOffsetY: 2.5,},},{name: '图片',type: 'line',smooth: true,symbol: 'none',data: [150, 232, 201, 154, 190, 330, 410],itemStyle: {color: '#F2465E',},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#F2465E' },{ offset: 1, color: '#F2465E' },]),shadowColor: '#F2465E',shadowBlur: 8,shadowOffsetY: 2.5,},},{name: '轨迹数据',type: 'line',smooth: true,symbol: 'none',data: [320, 332, 301, 334, 390, 330, 320],itemStyle: {color: '#57CC9B',},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#57CC9B' },{ offset: 1, color: '#57CC9B' },]),shadowColor: '#57CC9B',shadowBlur: 8,shadowOffsetY: 2.5,},},],// ],}delChartDom.setOption(delOption)
}
3.饼图,主要是右半边的legend自定义字段,以及自定义字体样式
//仓库存储统计图表
const initStorageChat = () => {storageChartDom = echarts.init(storageChartEl.value)const storageOption = {title: {text: '4500',subtext: '数据总量',left: '34%',top: '40%',textAlign: 'center',textStyle: {fontSize: 30,color: '#333',},subtextStyle: {fontSize: 14,color: '#333',},itemGap: 5, //标题间距},legend: {x: 'right',orient: 'vertical',align: 'left',left: '55%',top: '20%',itemHeight: 16,itemWidth: 16,itemGap: 25, // 图例元素间隔icon: 'rect', //方形data: ['日志', '视频', '图片', '轨迹数据'],formatter: name => {const data = storageOption.series[0].dataconst item = data.find(item => item.name === name)if (item) {const total = data.reduce((sum, item) => sum + item.value, 0)const percentage = ((item.value / total) * 100).toFixed(2)let arr = ['{name|' + item.name + '}', '{value|' + item.value + '}', '{percentage|' + percentage + '%}']return arr.join(' ')} else {return name}},textStyle: {rich: {name: {padding: [0, 0, 0, 6],width: 80,},value: {fontSize: 20,width: 70,color: '#333',align: 'center',},percentage: {fontSize: 20,align: 'center',},},},},series: [{type: 'pie',// right: '50%',center: ['35%', '50%'],radius: ['58%', '80%'], // 设置饼图内外半径avoidLabelOverlap: false,label: {show: false, // 不显示标签},labelLine: {show: false,},data: [{value: 1048,name: '日志',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [// 从左到右渐变{ offset: 0, color: '#5A96FF' },{ offset: 1, color: '#26D5FD' },]),},},{value: 735,name: '视频',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#FBDA37' },{ offset: 1, color: '#F95145' },]),},},{value: 580,name: '图片',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#2CD57E' },{ offset: 1, color: '#27F1C2' },]),},},{value: 484,name: '轨迹数据',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#FA8A56' },{ offset: 1, color: '#F94564' },]),},},],// 饼图的阴影效果itemStyle: {shadowBlur: 10,shadowColor: 'rgba(0, 0, 0, 0.2)',borderRadius: 0, // 设置圆角半径为 10pxborderWidth: 0, // 去除扇形之间的边框},// 饼图的hover效果emphasis: {itemStyle: {borderWidth: 2, // 设置边框宽度borderColor: '#FFFFFF', // 设置边框颜色},},},],}storageChartDom.setOption(storageOption)
}
4.这个就没什么难度了,直接上代码
//数据应用统计图表
const initApplyChat = () => {applyChartDom = echarts.init(applyChartEl.value)const applyOption = {grid: {left: '1%',right: '1%',bottom: '1%',top: '20%',containLabel: true,},legend: {itemHeight: 12,itemWidth: 12,itemGap: 30, // 图例元素间隔icon: 'rect', //方形top: '5%',data: ['路口', '车辆'],},tooltip: {trigger: 'axis',backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景confine: true,extraCssText://额外附加到浮层的css样式,此处为为浮层添加阴影及padding'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',},xAxis: [{type: 'category',data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],axisPointer: {type: 'shadow',},},],yAxis: [{type: 'value',},],series: [{name: '路口',type: 'bar',barWidth: 16,itemStyle: {// 添加 itemStylecolor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [// 渐变方向:从上到下{ offset: 0, color: '#FBDA37' }, // 顶部颜色{ offset: 1, color: '#F94564' }, // 底部颜色]),},data: [220, 182, 191, 234, 290, 330, 310],},{name: '车辆',type: 'bar',barWidth: 16,itemStyle: {// 添加 itemStylecolor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [// 渐变方向:从上到下{ offset: 0, color: '#0EECE4' }, // 顶部颜色{ offset: 1, color: '#058FE7' }, // 底部颜色]),},data: [320, 332, 301, 334, 390, 330, 320],},],}applyChartDom.setOption(applyOption)
}
完整代码,包含布局样式
<template><div class="commmon-container data-overview"><!-- 上方数据统计显示 --><div class="search_container total-card">
----省略上方其他代码</div><div class="table_container chart-container"><div class="chart-item"><TimePickertitle="近一周数据接入统计"@time-range-change="handleTimeRangeChange1"></TimePicker><divclass="echarts-style"ref="accessChartEl"></div></div><div class="chart-item"><TimePickertitle="近一月数据处理统计"@time-range-change="handleTimeRangeChange2"></TimePicker><divclass="echarts-style"ref="delChartEl"></div></div><div class="chart-item"><TimePicker @time-range-change="handleTimeRangeChange3"><template #title><a-selectref="select"v-model:value="stashName"style="width: 164px"><a-select-option value="jack">Jack</a-select-option><a-select-option value="lucy">Lucy</a-select-option><a-select-option value="Yiminghe">yiminghe</a-select-option></a-select></template></TimePicker><divclass="echarts-style"ref="storageChartEl"></div></div><div class="chart-item"><TimePickertitle="近一周数据应用统计"@time-range-change="handleTimeRangeChange4"></TimePicker><divclass="echarts-style"ref="applyChartEl"></div></div></div></div>
</template><script setup>
import { onMounted, reactive, ref, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { SettingFilled } from '@ant-design/icons-vue'
import accessBack from '@/assets/dataManage/access_back.png'
import delBack from '@/assets/dataManage/del_back.png'
import storageBack from '@/assets/dataManage/storage_back.png'
import applyBack from '@/assets/dataManage/apply_back.png'
import TimePicker from './components/timePicker.vue'
import * as echarts from 'echarts'const router = useRouter()const stashName = ref('') //仓库名称//时间选择
const handleTimeRangeChange1 = timeRange => {console.log('选择的时间段1:', timeRange)
}
const handleTimeRangeChange2 = timeRange => {console.log('选择的时间段2:', timeRange)
}
const handleTimeRangeChange3 = timeRange => {console.log('选择的时间段3:', timeRange)
}
const handleTimeRangeChange4 = timeRange => {console.log('选择的时间段4:', timeRange)
}//图表
const delChartEl = ref(null) //数据处理
const accessChartEl = ref(null) //数据接入
const storageChartEl = ref(null) //仓库
const applyChartEl = ref(null) //数据应用
let delChartDom = null
let accessChartDom = null
let storageChartDom = null
let applyChartDom = null//数据接入统计图表
const initAccessChat = () => {accessChartDom = echarts.init(accessChartEl.value)const accessOption = {grid: {left: '1%',right: '1%',bottom: '1%',top: '20%',containLabel: true,},legend: {itemHeight: 12,itemWidth: 12,itemGap: 30, // 图例元素间隔icon: 'rect', //方形top: '5%',data: ['路口', '智慧车辆'],},tooltip: {trigger: 'axis',backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景confine: true,extraCssText://额外附加到浮层的css样式,此处为为浮层添加阴影及padding'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',},xAxis: [{type: 'category',data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],axisPointer: {type: 'shadow',},},],yAxis: {type: 'value',},series: [{name: '路口',type: 'bar',barWidth: 16,itemStyle: {// 添加 itemStylecolor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [// 渐变方向:从上到下{ offset: 0, color: '#0EECE4' }, // 顶部颜色{ offset: 1, color: '#058FE7' }, // 底部颜色]),},data: [110, 50, 220, 200, 135, 135, 135],},{name: '智慧车辆',type: 'line',symbol: 'none',itemStyle: {color: '#FFD15C', // 明确指定系列颜色},lineStyle: {color: '#FFD15C',width: 3,},data: [110, 50, 220, 200, 135, 135, 135],},],}accessChartDom.setOption(accessOption)
}
// 数据处理统计图表
const initDelChat = () => {delChartDom = echarts.init(delChartEl.value)const delOption = {grid: {left: '1%',right: '1%',bottom: '1%',top: '20%',containLabel: true,},tooltip: {trigger: 'axis',backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景confine: true,extraCssText://额外附加到浮层的css样式,此处为为浮层添加阴影及padding'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',},xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],},yAxis: {type: 'value',},legend: {itemHeight: 12,itemWidth: 12,itemGap: 30, // 图例元素间隔icon: 'rect', //方形top: '5%',data: ['日志', '视频', '图片', '轨迹数据'],},series: [{name: '日志',type: 'line',smooth: true,symbol: 'none',data: [120, 132, 101, 134, 90, 230, 210],itemStyle: {color: '#FEB729', // 明确指定系列颜色},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [// 渐变方向:从左到右{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#FEB729' },{ offset: 1, color: '#FEB729' },]),shadowColor: '#FEB729', // 阴影颜色shadowBlur: 8, // 阴影模糊程度shadowOffsetY: 2.5, //阴影向下偏移},},{name: '视频',type: 'line',smooth: true,symbol: 'none',data: [220, 182, 191, 234, 290, 330, 310],itemStyle: {color: '#4B85FF',},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#4B85FF' },{ offset: 1, color: '#4B85FF' },]),shadowColor: '#4B85FF',shadowBlur: 8,shadowOffsetY: 2.5,},},{name: '图片',type: 'line',smooth: true,symbol: 'none',data: [150, 232, 201, 154, 190, 330, 410],itemStyle: {color: '#F2465E',},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#F2465E' },{ offset: 1, color: '#F2465E' },]),shadowColor: '#F2465E',shadowBlur: 8,shadowOffsetY: 2.5,},},{name: '轨迹数据',type: 'line',smooth: true,symbol: 'none',data: [320, 332, 301, 334, 390, 330, 320],itemStyle: {color: '#57CC9B',},lineStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: 'rgba(255,255,255,0.5)' },{ offset: 0.2, color: '#57CC9B' },{ offset: 1, color: '#57CC9B' },]),shadowColor: '#57CC9B',shadowBlur: 8,shadowOffsetY: 2.5,},},],// ],}delChartDom.setOption(delOption)
}//仓库存储统计图表
const initStorageChat = () => {storageChartDom = echarts.init(storageChartEl.value)const storageOption = {title: {text: '4500',subtext: '数据总量',left: '34%',top: '40%',textAlign: 'center',textStyle: {fontSize: 30,color: '#333',},subtextStyle: {fontSize: 14,color: '#333',},itemGap: 5, //标题间距},legend: {x: 'right',orient: 'vertical',align: 'left',left: '55%',top: '20%',itemHeight: 16,itemWidth: 16,itemGap: 25, // 图例元素间隔icon: 'rect', //方形data: ['日志', '视频', '图片', '轨迹数据'],formatter: name => {const data = storageOption.series[0].dataconst item = data.find(item => item.name === name)if (item) {const total = data.reduce((sum, item) => sum + item.value, 0)const percentage = ((item.value / total) * 100).toFixed(2)let arr = ['{name|' + item.name + '}', '{value|' + item.value + '}', '{percentage|' + percentage + '%}']return arr.join(' ')} else {return name}},textStyle: {rich: {name: {padding: [0, 0, 0, 6],width: 80,},value: {fontSize: 20,width: 70,color: '#333',align: 'center',},percentage: {fontSize: 20,align: 'center',},},},},series: [{type: 'pie',// right: '50%',center: ['35%', '50%'],radius: ['58%', '80%'], // 设置饼图内外半径avoidLabelOverlap: false,label: {show: false, // 不显示标签},labelLine: {show: false,},data: [{value: 1048,name: '日志',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [// 从左到右渐变{ offset: 0, color: '#5A96FF' },{ offset: 1, color: '#26D5FD' },]),},},{value: 735,name: '视频',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#FBDA37' },{ offset: 1, color: '#F95145' },]),},},{value: 580,name: '图片',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#2CD57E' },{ offset: 1, color: '#27F1C2' },]),},},{value: 484,name: '轨迹数据',itemStyle: {color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{ offset: 0, color: '#FA8A56' },{ offset: 1, color: '#F94564' },]),},},],// 饼图的阴影效果itemStyle: {shadowBlur: 10,shadowColor: 'rgba(0, 0, 0, 0.2)',borderRadius: 0, // 设置圆角半径为 10pxborderWidth: 0, // 去除扇形之间的边框},// 饼图的hover效果emphasis: {// scale: 0.3,itemStyle: {borderWidth: 2, // 设置边框宽度borderColor: '#FFFFFF', // 设置边框颜色},// itemStyle: {// margin:'0 10px'// },},},],}storageChartDom.setOption(storageOption)
}//数据应用统计图表
const initApplyChat = () => {applyChartDom = echarts.init(applyChartEl.value)const applyOption = {grid: {left: '1%',right: '1%',bottom: '1%',top: '20%',containLabel: true,},legend: {itemHeight: 12,itemWidth: 12,itemGap: 30, // 图例元素间隔icon: 'rect', //方形top: '5%',data: ['路口', '车辆'],},tooltip: {trigger: 'axis',backgroundColor: 'rgba(255,255,255,0.65)', //设置自定义背景confine: true,extraCssText://额外附加到浮层的css样式,此处为为浮层添加阴影及padding'box-shadow: 0px 2px 12px 0px rgba(0,0,0,0.2)',},xAxis: [{type: 'category',data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],axisPointer: {type: 'shadow',},},],yAxis: [{type: 'value',},],series: [{name: '路口',type: 'bar',barWidth: 16,itemStyle: {// 添加 itemStylecolor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [// 渐变方向:从上到下{ offset: 0, color: '#FBDA37' }, // 顶部颜色{ offset: 1, color: '#F94564' }, // 底部颜色]),},data: [220, 182, 191, 234, 290, 330, 310],},{name: '车辆',type: 'bar',barWidth: 16,itemStyle: {// 添加 itemStylecolor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [// 渐变方向:从上到下{ offset: 0, color: '#0EECE4' }, // 顶部颜色{ offset: 1, color: '#058FE7' }, // 底部颜色]),},data: [320, 332, 301, 334, 390, 330, 320],},],}applyChartDom.setOption(applyOption)
}//数据统计展示
const totalData = ref([{ label: '数据接入', value: 201, backImg: accessBack },{ label: '数据处理', value: 202, backImg: delBack },{ label: '仓库存储', value: 203, hasBtn: true, backImg: storageBack },{ label: '应用统计', value: 204, backImg: applyBack },
])//仓库管理
const goStashManage = () => {router.push({path: '/dataManage/stashManage',})
}const handleResize = () => {// 调整图表尺寸delChartDom.resize()accessChartDom.resize()storageChartDom.resize()applyChartDom.resize()
}onMounted(() => {initDelChat()initAccessChat()initStorageChat()initApplyChat()window.addEventListener('resize', handleResize) // 监听 resize 事件
})onUnmounted(() => {window.removeEventListener('resize', handleResize) // 移除 resize 事件监听// 组件卸载时销毁图表实例delChartDom.dispose()accessChartDom.dispose()storageChartDom.dispose()applyChartDom.dispose()
})
</script><style lang="less" scoped>
@import '@/style/public.less';.custom-btn-manage {margin-left: 16px;border: none;padding: 6px 12px;
}.data-overview {display: flex;flex-direction: column;background-color: #f5f5f5;
}.total-card {display: flex;justify-content: space-between;.card-item {width: calc(25% - 20px);height: 126px;display: flex;flex-direction: column;align-items: flex-start;border-radius: 8px;padding: 24px;color: #ffffff;justify-content: space-between;background-repeat: no-repeat;background-size: cover;background-position: right;.label {font-size: 18px;font-weight: 400;}.number {font-size: 32px;font-weight: 500;}}
}.chart-container {flex: 1;display: flex;justify-content: space-between;flex-wrap: wrap;.chart-item {width: calc(50% - 10px);height: calc(50% - 20px);display: flex;padding: 16px;background-color: #fff;border-radius: 8px;flex-direction: column;.echarts-style {flex: 1;}}
}
</style>
另外附上TimePicker组件封装的代码,其实我封装得不太好,但是懒得优化了
<template><div class="total-top"><divv-if="title !== ''"class="total-title">{{ title }}</div><slot name="title"></slot><div class="time-options"><divclass="time-item"v-for="item in timeOptions":key="item.label":class="{ active: currentTime === item.label }"@click="getTimeRange(item)">{{ item.label }}</div><a-range-pickerv-model:value="timeValue"valueFormat="YYYY-MM-DD"style="margin-left: 12px"@change="getTimeRange"/></div></div>
</template><script setup>
import { ref, onMounted } from 'vue'
import dayjs from 'dayjs'const props = defineProps({//标题title: {type: String,default: '',},
})const currentTime = ref('今日') //默认时间const timeOptions = ref([{label: '今日',time: [dayjs().startOf('day').format('YYYY-MM-DD'), dayjs().endOf('day').format('YYYY-MM-DD')],},{label: '本周',time: [dayjs().startOf('week').format('YYYY-MM-DD'), dayjs().endOf('week').format('YYYY-MM-DD')],},{label: '本月',time: [dayjs().startOf('month').format('YYYY-MM-DD'), dayjs().endOf('month').format('YYYY-MM-DD')],},
])
const timeValue = ref()const emit = defineEmits(['time-range-change'])// 点击默认时间选项和时间选择器都调用此方法
const getTimeRange = item => {if (item && item.label) {currentTime.value = item.labeltimeValue.value = item.time} else {currentTime.value = ''}emit('time-range-change', timeValue.value)
}onMounted(() => {getTimeRange(timeOptions.value[0]) // 默认显示今日
})
</script><style lang="less" scoped>
.total-top {display: flex;align-items: center;width: 100%;justify-content: space-between;.total-title {font-weight: bold;font-size: 18px;color: #333;&::before {content: '';display: inline-block;width: 8px;height: 16px;background-color: #0084f6;margin-right: 12px;border-radius: 9px 9px 9px 9px;}}.time-options {display: flex;.time-item {padding: 6px 12px;background-color: #f5f5f5;border-radius: 24px;margin: 0 6px;cursor: pointer;}.active {background-color: #0084f6;color: #fff;}}
}
</style>