Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-ui
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-ui
Commits
9e8d1c4f
提交
9e8d1c4f
authored
1月 06, 2025
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor(cmm): 蝉妈妈页面又优化了一下
同上
上级
7915b8e2
显示空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
35 行增加
和
313 行删除
+35
-313
date.js
src/hooks/date.js
+3
-0
LineAndBar.vue
src/views/bi/competitor/cmm/LineAndBar.vue
+7
-25
index.vue
src/views/bi/competitor/cmm/index.vue
+21
-20
GradientArea.vue
src/views/bi/competitor/components/GradientArea.vue
+0
-0
TableList.vue
src/views/bi/competitor/components/TableList.vue
+0
-0
index.vue
src/views/bi/competitor/sycm_prd/index.vue
+2
-2
GradientArea.vue
src/views/bi/competitor/sycm_store/GradientArea.vue
+0
-166
TableList.vue
src/views/bi/competitor/sycm_store/TableList.vue
+0
-98
index.vue
src/views/bi/competitor/sycm_store/index.vue
+2
-2
没有找到文件。
src/hooks/date.js
浏览文件 @
9e8d1c4f
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
src/views/bi/competitor/cmm/LineAndBar.vue
浏览文件 @
9e8d1c4f
...
...
@@ -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
...
...
src/views/bi/competitor/cmm/index.vue
浏览文件 @
9e8d1c4f
<
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
()
}
...
...
src/views/bi/competitor/
sycm_prd
/GradientArea.vue
→
src/views/bi/competitor/
components
/GradientArea.vue
浏览文件 @
9e8d1c4f
File moved
src/views/bi/competitor/
sycm_prd
/TableList.vue
→
src/views/bi/competitor/
components
/TableList.vue
浏览文件 @
9e8d1c4f
File moved
src/views/bi/competitor/sycm_prd/index.vue
浏览文件 @
9e8d1c4f
...
...
@@ -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'
...
...
src/views/bi/competitor/sycm_store/GradientArea.vue
deleted
100644 → 0
浏览文件 @
7915b8e2
<
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
src/views/bi/competitor/sycm_store/TableList.vue
deleted
100644 → 0
浏览文件 @
7915b8e2
<
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
src/views/bi/competitor/sycm_store/index.vue
浏览文件 @
9e8d1c4f
...
...
@@ -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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论