提交 9e8d1c4f authored 作者: lidongxu's avatar lidongxu

refactor(cmm): 蝉妈妈页面又优化了一下

同上
上级 7915b8e2
export const useDatePickerOptions = () => {
const nowMouth = [new Date().setDate((new Date().getDate() - 30)), new Date().setDate((new Date().getDate() - 1))]
const pickerOptions = ref([// 日期选项配置
{
text: '最近一周',
......@@ -19,6 +20,7 @@ export const useDatePickerOptions = () => {
}
])
return {
nowMouth,
pickerOptions
}
}
\ No newline at end of file
......@@ -21,10 +21,6 @@ const props = defineProps({
type: String,
default: '600px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
......@@ -93,6 +89,7 @@ const setOptions = () => {
}
}
]
// 根据图例是否显示,设置 y 轴名字的值
yAxis.filter(yObj => {
return props.chartData.legend.some(o => {
const target = o.data.find(o => {
......@@ -102,6 +99,7 @@ const setOptions = () => {
else yObj.name = target.name.split('-')[1]
})
})
// 设置图表选项
chart.value.setOption({
xAxis: {
type: 'category',
......@@ -165,18 +163,6 @@ const setOptions = () => {
});
return tooltip;
}
// padding: [5, 10],
// formatter: (params) => {
// let tooltip = '';
// params.forEach((item) => {
// if (item.seriesName.split('-')[1] === '销售额') {
// tooltip += item.marker + item.seriesName + ': ' + (this.myThousand ? convertToUnit(item.value, true) : toFixed2(item.value) + '元') + '<br>';
// } else if (item.seriesName.split('-')[1] === '观看人次') {
// tooltip += item.marker + item.seriesName + ': ' + toFixed2(item.value) + (this.myThousand ? '' : '') + '<br>';
// }
// });
// return tooltip;
// }
},
yAxis,
series: props.chartData.series
......@@ -191,19 +177,15 @@ watchEffect(() => {
setOptions()
})
const initChart = () => {
chart.value = echarts.init(echartsRef.value)
}
const resize = () => {
chart.value.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
chart.value = echarts.init(echartsRef.value)
})
})
useWindowResize(() => {
chart.value.resize()
})
onBeforeUnmount(() => {
if (!chart.value) {
return
......
<template>
<div class="tabs-container">
<el-form :model="queryParams"
inline
size="default">
inline>
<el-form-item label="直播间">
<el-select v-model="queryParams.brandList"
@change="queryChangeFn"
multiple
clearable
collapse-tags
collapse-tags-tooltip>
collapse-tags-tooltip
@change="queryChangeFn">
<el-option v-for="str in brandList"
:label="str"
:value="str">
......@@ -43,7 +42,8 @@
</el-date-picker>
</el-form-item>
</el-form>
<div class="chart_wrap" v-loading="loading">
<div class="chart_wrap"
v-loading="loading">
<template v-if="queryParams.brandList.length > 0 && queryParams.typeList.length > 0">
<group-legend :legendData="chartData.legend"
@click-item="legendChangeFn"></group-legend>
......@@ -64,19 +64,16 @@ import { getCmmListAPI } from '@/api'
import { generatorDayList, parseTime, getAdditionalColor, resetObjValue } from '@/utils'
import { useDatePickerOptions } from '@/hooks'
// 静态数据
const dateList = [new Date().setDate((new Date().getDate() - 30)), new Date().setDate((new Date().getDate() - 1))] // 最近 30 日日期数组
const dataTypeList = ['销售额', '观看人次'] // 数据类型
// 页面使用数据
const brandList = ref([])// 直播间列表
const typeList = ref(dataTypeList) // 数据类型列表
const { pickerOptions } = useDatePickerOptions()
const loading = ref(true)
const brandList = ref([]) // 直播间列表
const typeList = ref(['销售额', '观看人次']) // 数据类型列表
const { pickerOptions, nowMouth } = useDatePickerOptions() // 日期快捷方式
const queryParams = reactive({ // 查询表单
brandList: [],
date: dateList,
typeList: [dataTypeList[0]]
date: nowMouth,
typeList: [typeList.value[0]]
})
const allChartData = reactive({ // 图表所有数据
......@@ -84,26 +81,28 @@ const allChartData = reactive({ // 图表所有数据
legend: [],
series: []
})
const chartData = reactive({ // 图表内要用的数据
const chartData = reactive({ // 图表使用数据
xAxis: [],
legend: [],
series: []
})
// 获取数据
const getList = async () => {
loading.value = true
// 重置数据源
resetObjValue(allChartData)
// 获取 x 轴时间
allChartData.xAxis = generatorDayList(queryParams.date[0], queryParams.date[1])
// 请求数据
const { data } = await getCmmListAPI({
startDate: parseTime(queryParams.date[0], '{y}-{m}-{d}'),
endDate: parseTime(queryParams.date[1], '{y}-{m}-{d}')
})
// 获取 x 轴时间
allChartData.xAxis = generatorDayList(queryParams.date[0], queryParams.date[1])
// 获取 legend 和 series 数据
data.map((list, index) => {
// list:每个直播间
// 按索引拿到颜色
let color = getAdditionalColor(index)
// 每个系列对象
const saleObj = {
......@@ -145,6 +144,10 @@ const getList = async () => {
gkrcObj.data.push(0)
}
})
// 添加系列数据
allChartData.series.push(saleObj)
allChartData.series.push(gkrcObj)
// 添加图例数据
allChartData.legend.push({
data: [{
......@@ -162,9 +165,6 @@ const getList = async () => {
}],
orient: 'verticalAlign'
})
// 添加系列数据
allChartData.series.push(saleObj)
allChartData.series.push(gkrcObj)
})
loading.value = false
return data
......@@ -239,6 +239,7 @@ init()
// 筛选条件改变了
const queryChangeFn = async (arg) => {
// 日期改变需要后台重新获取,其他改因为数据都给前台了,自己筛选
if (arg === 'date' && queryParams.date) {
await getList()
}
......@@ -260,7 +261,7 @@ const reset = async () => {
<style scoped
lang="scss">
.tabs-container {
flex: 1;
display: flex;
......
......@@ -70,8 +70,8 @@
</template>
<script setup>
import GradientArea from './GradientArea.vue';
import TableList from './TableList.vue';
import GradientArea from '../components/GradientArea.vue';
import TableList from '../components/TableList.vue';
import { getComPrdListAPI, getSycmListAPI } from '@/api'
import { generatorDayList, parseTime, getAdditionalColor, resetObjValue } from '@/utils'
import { useDatePickerOptions } from '@/hooks'
......
<template>
<div ref="echartsRef"
:class="className"
:style="{ height: height, width: width }" />
</template>
<script setup>
import * as echarts from 'echarts'
import { formatNumberWithUnit } from '@/utils'
import { useWindowResize } from '@/hooks'
const props = defineProps({
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '600px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
})
const echartsRef = ref(null)
const chart = shallowRef(null)
let myThousand = false // 是否显示万单位
let isArea = ref(true) // 是否面积图
const emits = defineEmits(['changeType'])
const setOptions = () => {
// 面积图是否切换
const seriesResult = props.chartData.series.map(o => {
if (!isArea.value) {
const obj = { ...o }
delete obj.areaStyle
delete obj.lineStyle
return obj
} else {
return o
}
})
chart.value.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
},
formatter: function (params) {
let tooltip = '';
params.forEach((item) => {
// 获取系列颜色
var color = item.color;
// 拼接提示内容
if (item.seriesName.split('-')[1].includes('速')) {
tooltip += '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + color + ';"></span>' + item.seriesName + ': ' + formatNumberWithUnit({
value: item.value,
carry: false,
round: false,
pos: false,
des: '%'
}) + '<br>';
} else {
tooltip += '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:' + color + ';"></span>' + item.seriesName + ':' + formatNumberWithUnit({
value: item.value,
des: '人'
}) + '<br>';
}
});
return tooltip;
}
},
// legend: {
// data: props.chartData.legend
// },
toolbox: {
feature: {
saveAsImage: {},
magicType: {
type: ['stack', 'tiled'] // 切换图表类型
},
myTool1: {
show: true,
title: '切换表格',
icon: 'path://M5,5 L5,15 L15,15 L15,5 Z M20,5 L20,15 L30,15 L30,5 Z M5,20 L5,30 L15,30 L15,20 Z M20,20 L20,30 L30,30 L30,20 Z',
onclick: () => {
emits('changeType', 'table')
}
},
myTool2: {
show: true,
title: '面积/折线图',
icon: 'path://M5,5 L5,30 L15,30 L25,20 L35,30 L45,30 L45,5 Z',
onclick: () => {
isArea.value = !isArea.value
}
}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
// type: 'category',
// boundaryGap: false,
data: props.chartData.xAxis
}
],
yAxis: [
{
type: 'value'
}
],
series: seriesResult
}, true)
}
watchEffect(() => {
if (!chart.value) return
myThousand = props.chartData.series?.some(o => {
return o.data.some(num => num >= 10000)
})
setOptions()
})
const initChart = () => {
chart.value = echarts.init(echartsRef.value)
}
const resize = () => {
chart.value.resize()
}
useWindowResize(resize)
onMounted(() => {
nextTick(() => {
initChart()
})
})
onBeforeUnmount(() => {
if (!chart.value) {
return
}
chart.value.dispose()
chart.value = null
})
</script>
\ No newline at end of file
<template>
<div class="toolbar">
<right-toolbar :search="false"
@queryTable="queryTable">
<el-tooltip class="item"
effect="dark"
content="日期合并/分散"
placement="top">
<el-button circle
icon="Calendar"
@click="dateMergeFn()" />
</el-tooltip>
<el-tooltip class="item"
effect="dark"
content="切换图表"
placement="top">
<el-button circle
icon="Histogram"
@click="changeType()" />
</el-tooltip>
</right-toolbar>
</div>
<el-table :data="data"
style="width: 100%">
<el-table-column prop="platformStore"
label="店铺" />
<el-table-column prop="date"
label="日期"
v-if="!dateMerge" />
<el-table-column v-for="str in column"
:prop="columnKey[str]"
:label="str"
:formatter="formatterFn" />
</el-table>
</template>
<script lang="ts"
setup>
const columnKey = {
'支付买家数': 'zfmj',
'交易增速': 'jyzs',
'独立访客范围': 'uv',
'流量增速': 'llzs'
}
const props = defineProps({
column: {
type: Object,
default: () => {
return {}
},
},
data: {
type: Array,
default: () => {
return []
},
},
dateMerge: { // 是否把日期数据合并
type: Boolean,
default: false,
}
})
const formatterFn = (row, column, cellValue) => {
let result = cellValue
if (column.property === 'jyzs' || column.property === 'llzs') {
result += '%'
}
if (props.dateMerge) {
result += ' / 平均每日'
}
return result
}
const emits = defineEmits(['changeType', 'queryTable', 'dateMerge'])
const queryTable = () => {
emits('queryTable')
}
const changeType = () => {
emits('changeType', 'charts')
}
const dateMergeFn = () => {
emits('dateMerge')
}
</script>
<style scoped
style="sass">
.toolbar {
float: right;
}
</style>
\ No newline at end of file
......@@ -68,8 +68,8 @@
</template>
<script setup>
import GradientArea from './GradientArea.vue';
import TableList from './TableList.vue';
import GradientArea from '../components/GradientArea.vue';
import TableList from '../components/TableList.vue';
import { getStoreListAPI, getSycmStoreListAPI } from '@/api'
import { generatorDayList, parseTime, getAdditionalColor, resetObjValue } from '@/utils'
import { useDatePickerOptions } from '@/hooks'
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论