Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
提交反馈
为 GitLab 提交贡献
登录
切换导航
P
pica-risk-admin
项目
项目
详情
动态
版本
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
收起侧边栏
Close sidebar
动态
分支图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
com.pica.cloud.education.frontend
pica-risk-admin
提交
19a466a1
提交
19a466a1
编写于
12月 07, 2020
作者:
huangwensu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
创建风控系统
上级
3d2a4329
变更
8
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
506 行增加
和
1133 行删除
+506
-1133
index.html
index.html
+1
-1
Header.vue
src/components/common/Header.vue
+1
-1
index.js
src/router/index.js
+8
-27
doctor-black.vue
src/views/black-list/doctor-black.vue
+249
-0
empty-phone.vue
src/views/black-list/empty-phone.vue
+247
-0
add-funnel.vue
src/views/user-path/add-funnel.vue
+0
-330
funnel-data.vue
src/views/user-path/funnel-data.vue
+0
-566
funnel.vue
src/views/user-path/funnel.vue
+0
-208
未找到文件。
index.html
浏览文件 @
19a466a1
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
<html>
<html>
<head>
<head>
<meta
charset=
"utf-8"
>
<meta
charset=
"utf-8"
>
<title>
数据服务
</title>
<title>
风控系统
</title>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
>
<meta
name =
"viewport"
content =
"width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
>
<meta
name =
"viewport"
content =
"width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
>
<meta
content=
""
name=
"description"
/>
<meta
content=
""
name=
"description"
/>
...
...
src/components/common/Header.vue
浏览文件 @
19a466a1
<
template
>
<
template
>
<div
class=
"header"
>
<div
class=
"header"
>
<div
class=
"logo"
>
数据服务
</div>
<div
class=
"logo"
>
风控系统
</div>
<div
class=
"user-info"
>
<div
class=
"user-info"
>
<el-dropdown
trigger=
"click"
@
command=
"handleCommand"
>
<el-dropdown
trigger=
"click"
@
command=
"handleCommand"
>
<span
class=
"el-dropdown-link"
>
<span
class=
"el-dropdown-link"
>
...
...
src/router/index.js
浏览文件 @
19a466a1
...
@@ -18,37 +18,18 @@ export default new Router({
...
@@ -18,37 +18,18 @@ export default new Router({
children
:
[
children
:
[
{
{
path
:
'/'
,
path
:
'/'
,
redirect
:
'/d
ata-view
'
,
redirect
:
'/d
octor-black
'
,
},{
// 数据导入
},{
path
:
'/data-in'
,
path
:
'/doctor-black'
,
component
:
resolve
=>
require
([
'../views/sensitive-control/data-in.vue'
],
resolve
),
component
:
resolve
=>
require
([
'../views/black-list/doctor-black.vue'
],
resolve
),
},
{
// 数据统计
},{
path
:
'/data-statistic'
,
path
:
'/empty-phone'
,
component
:
resolve
=>
require
([
'../views/sensitive-control/data-statistic.vue'
],
resolve
),
component
:
resolve
=>
require
([
'../views/black-list/empty-phone.vue'
],
resolve
),
},{
// 数据查看
path
:
'/data-view'
,
component
:
resolve
=>
require
([
'../views/sensitive-control/data-view.vue'
],
resolve
)
},
{
// 用户路径分析
path
:
'/user-path'
,
component
:
resolve
=>
require
([
'../views/user-path/funnel.vue'
],
resolve
)
},
{
// 用户路径分析--新增转化漏斗
path
:
'/add-funnel'
,
component
:
resolve
=>
require
([
'../views/user-path/add-funnel.vue'
],
resolve
)
},
{
// 用户路径分析--查看数据
path
:
'/path-data'
,
component
:
resolve
=>
require
([
'../views/user-path/funnel-data.vue'
],
resolve
)
},
},
]
]
},
},
{
// 短信中的 数据查看页面
path
:
'/data-view-message'
,
component
:
resolve
=>
require
([
'../views/sensitive-control/data-view-message.vue'
],
resolve
)
},
]
]
...
...
src/views/black-list/doctor-black.vue
0 → 100644
浏览文件 @
19a466a1
<
template
>
<div
class=
"black-container"
>
<el-row
:gutter=
"30"
class=
"row search"
type=
"flex"
style=
"margin-bottom:0;"
>
<el-form
ref=
"form"
:model=
"searchParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-col
:span=
"18"
>
<el-form-item
label=
"名称"
>
<el-input
v-model=
"searchParam.searchName"
maxlength=
"20"
placeholder=
"请输入黑名单中的名称"
style=
"width:288px;"
></el-input>
</el-form-item>
</el-col>
<el-col
:span=
"6"
style=
"padding:0;text-align:right;padding-right:15px;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"search(1)"
>
查询
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"importBatch"
>
批量导入
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"addBlackList"
>
新增黑名单
</el-button>
</el-col>
</el-form>
</el-row>
<el-table
class=
"search-table"
:data=
"tableData"
style=
"width: 100%"
>
<el-table-column
prop=
"searchName"
label=
"名称"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"time"
label=
"添加时间"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"remark"
label=
"添加理由"
min-width=
"150"
align=
"center"
></el-table-column>
<el-table-column
label=
"操作"
fixed=
"right"
align=
"center"
min-width=
"200"
>
<template
slot-scope=
"scope"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"removeFromBlack(scope.row)"
>
从黑名单移除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<div
class=
"pagination"
>
<el-pagination
background
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page=
"searchParam.pageNo"
:page-sizes=
"[15, 30, 50, 100, 200, 500, 700, 1000, 1500, 2000]"
:page-size=
"searchParam.pageSize"
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"totalRows"
>
</el-pagination>
</div>
<!-- 将手机号加入黑名单 -->
<el-dialog
title=
"提示"
:visible
.
sync=
"addDialogVisible"
width=
"30%"
center
>
<el-form
ref=
"importForm"
:model=
"addParam"
label-suffix=
":"
label-width=
"80px"
>
<el-form-item
label=
"手机号"
>
<el-input
v-model=
"addParam.mobilePhone"
style=
"width: 300px;"
></el-input>
</el-form-item>
<el-form-item
label=
"添加理由"
>
<el-input
v-model=
"addParam.remark"
style=
"width: 300px;"
></el-input>
</el-form-item>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"addDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmAdd"
>
确 定
</el-button>
</span>
</el-dialog>
<!-- 从黑名单移除二次确认 -->
<el-dialog
title=
"提示"
:visible
.
sync=
"removeDialogVisible"
width=
"30%"
center
>
<span>
您确定将{{removeTel}}移除黑名单?
</span>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"removeDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmRemove"
>
确 定
</el-button>
</span>
</el-dialog>
<!-- 批量导入 -->
<el-dialog
title=
"提示"
:visible
.
sync=
"importDialogVisible"
width=
"30%"
center
>
<el-form
ref=
"importForm"
:model=
"searchParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-form-item
label=
"上传文件"
>
<el-upload
class=
"upload-demo"
accept=
".xlsx"
action=
"#"
v-model=
"importFileName"
:before-upload=
"uploadImportFile"
>
<el-input
class=
"upload-input"
v-model=
"importFileName"
autocomplete=
"off"
></el-input>
</el-upload>
</el-form-item>
<div
class=
"el-upload__tip"
@
click=
"download"
>
下载导入模板
</div>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"importDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmImport"
>
确 定
</el-button>
</span>
</el-dialog>
</div>
</template>
<
script
>
import
{
doUpload
,
getFilePath
}
from
"../../common/qiniuUtil"
;
import
{
openLoading
,
closeLoading
}
from
"../../common/utils"
;
export
default
{
data
()
{
return
{
addDialogVisible
:
false
,
removeDialogVisible
:
false
,
importDialogVisible
:
false
,
searchParam
:
{
searchName
:
''
,
pageSize
:
15
,
pageNo
:
1
},
totalRows
:
0
,
tableData
:
[],
addParam
:
{
mobilePhone
:
''
,
remark
:
''
},
removeId
:
''
,
removeTel
:
''
,
acceptValue
:
'*/*'
,
importFileName
:
''
}
},
mounted
()
{
this
.
search
();
},
methods
:
{
// 封装一下请求通用的方法
getData
(
type
,
url
,
req
,
callback
)
{
openLoading
(
this
);
this
.
$axios
[
type
](
localStorage
.
getItem
(
"lectureUrl"
)
+
url
,
req
)
.
then
(
res
=>
{
closeLoading
(
this
);
let
data
=
res
.
data
;
if
(
data
.
code
==
"000000"
)
{
if
(
callback
)
callback
(
data
);
}
else
{
this
.
$message
.
error
(
data
.
message
);
}
})
.
catch
(
error
=>
{
closeLoading
(
this
);
this
.
$message
.
error
(
"网络出现点问题"
);
});
},
search
(
param
)
{
if
(
param
)
this
.
searchParam
.
pageNo
=
1
;
this
.
getData
(
"get"
,
`/riskcontrol/blacklist/list?searchName=
${
this
.
searchParam
.
searchName
}
&pageNo=
${
this
.
searchParam
.
pageNo
}
&pageSize=
${
this
.
searchParam
.
pageSize
}
`
,
{},
data
=>
{
this
.
tableData
=
data
.
data
.
list
;
this
.
totalRows
=
data
.
data
.
totalRows
;
}
);
},
// 批量导入
importBatch
()
{
this
.
importDialogVisible
=
true
;
},
confirmImport
()
{
},
// 上传文件
uploadImportFile
(
file
)
{
console
.
log
(
file
)
let
self
=
this
;
this
.
importFileName
=
file
.
name
;
let
arr
=
file
.
type
.
split
(
'/'
);
let
ext
=
"."
+
arr
[
1
];
let
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
let
fileJson
=
{
fileName
:
file
.
name
,
file
:
e
.
target
.
result
.
substr
(
e
.
target
.
result
.
indexOf
(
"base64,"
)
+
7
),
ext
:
ext
};
self
.
base64
=
fileJson
;
console
.
log
(
'fileJson'
,
self
.
base64
);
};
reader
.
readAsDataURL
(
file
);
this
.
getData
(
"post"
,
`/riskcontrol/blacklist/import`
,
{
base64Str
:
self
.
base64
.
file
},
data
=>
{
if
(
data
.
code
==
'000000'
)
{
}
}
);
},
// 下载导入模板
download
()
{
console
.
log
(
'下载模板'
);
setTimeout
(()
=>
{
window
.
open
(
''
);
// 后台给的导入Excel地址
},
500
);
},
// 新增黑名单
addBlackList
()
{
this
.
addDialogVisible
=
true
;
},
confirmAdd
()
{
let
req
=
this
.
addParam
;
this
.
getData
(
"post"
,
`/riskcontrol/blacklist/create`
,
req
,
data
=>
{
if
(
data
.
code
==
'000000'
)
{
this
.
addDialogVisible
=
false
;
this
.
search
();
}
}
);
},
// 从黑名单移除
removeFromBlack
(
row
)
{
this
.
removeId
=
row
.
id
;
this
.
removeTel
=
row
.
mobilePhone
;
this
.
removeDialogVisible
=
true
;
},
confirmRemove
()
{
this
.
getData
(
"delete"
,
`/riskcontrol/blacklist/remove
${
this
.
removeId
}
`
,
{},
data
=>
{
if
(
data
.
code
==
'000000'
)
{
this
.
removeDialogVisible
=
false
;
this
.
search
();
}
}
);
},
handleSizeChange
(
value
)
{
this
.
searchParam
.
pageSize
=
value
;
this
.
search
();
},
handleCurrentChange
(
value
)
{
this
.
searchParam
.
pageNo
=
value
;
this
.
search
();
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.black-container {
.upload-input {
width: 300px;
}
}
</
style
>
\ No newline at end of file
src/views/black-list/empty-phone.vue
0 → 100644
浏览文件 @
19a466a1
<
template
>
<div
class=
"black-container"
>
<el-row
:gutter=
"30"
class=
"row search"
type=
"flex"
style=
"margin-bottom:0;"
>
<el-form
ref=
"form"
:model=
"searchParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-col
:span=
"18"
>
<el-form-item
label=
"名称"
>
<el-input
v-model=
"searchParam.searchName"
maxlength=
"20"
placeholder=
"请输入黑名单中的名称"
style=
"width:288px;"
></el-input>
</el-form-item>
</el-col>
<el-col
:span=
"6"
style=
"padding:0;text-align:right;padding-right:15px;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"search(1)"
>
查询
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"importBatch"
>
批量导入
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"addBlackList"
>
新增黑名单
</el-button>
</el-col>
</el-form>
</el-row>
<el-table
class=
"search-table"
:data=
"tableData"
style=
"width: 100%"
>
<el-table-column
prop=
"searchName"
label=
"名称"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"time"
label=
"添加时间"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"remark"
label=
"添加理由"
min-width=
"150"
align=
"center"
></el-table-column>
<el-table-column
label=
"操作"
fixed=
"right"
align=
"center"
min-width=
"200"
>
<template
slot-scope=
"scope"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"removeFromBlack(scope.row)"
>
从黑名单移除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<div
class=
"pagination"
>
<el-pagination
background
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page=
"searchParam.pageNo"
:page-sizes=
"[15, 30, 50, 100, 200, 500, 700, 1000, 1500, 2000]"
:page-size=
"searchParam.pageSize"
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"totalRows"
>
</el-pagination>
</div>
<!-- 将手机号加入黑名单 -->
<el-dialog
title=
"提示"
:visible
.
sync=
"addDialogVisible"
width=
"30%"
center
>
<el-form
ref=
"importForm"
:model=
"addParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-form-item
label=
"手机号"
>
<el-input
v-model=
"addParam.mobilePhone"
></el-input>
</el-form-item>
<el-form-item
label=
"添加理由"
>
<el-input
v-model=
"addParam.remark"
></el-input>
</el-form-item>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"addDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmAdd"
>
确 定
</el-button>
</span>
</el-dialog>
<!-- 从黑名单移除二次确认 -->
<el-dialog
title=
"提示"
:visible
.
sync=
"removeDialogVisible"
width=
"30%"
center
>
<span>
您确定将{{removeTel}}移除黑名单?
</span>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"removeDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmRemove"
>
确 定
</el-button>
</span>
</el-dialog>
<!-- 批量导入 -->
<el-dialog
title=
"提示"
:visible
.
sync=
"importDialogVisible"
width=
"30%"
center
>
<el-form
ref=
"importForm"
:model=
"searchParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-form-item
label=
"上传文件"
>
<el-upload
class=
"upload-demo"
accept=
".xlsx"
action=
"#"
v-model=
"importFileName"
:before-upload=
"uploadImportFile"
>
<el-input
class=
"update-input"
v-model=
"importFileName"
autocomplete=
"off"
></el-input>
</el-upload>
</el-form-item>
<div
class=
"el-upload__tip"
@
click=
"download"
>
下载导入模板
</div>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"importDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmImport"
>
确 定
</el-button>
</span>
</el-dialog>
</div>
</template>
<
script
>
import
{
doUpload
,
getFilePath
}
from
"../../common/qiniuUtil"
;
import
{
openLoading
,
closeLoading
}
from
"../../common/utils"
;
export
default
{
data
()
{
return
{
addDialogVisible
:
false
,
removeDialogVisible
:
false
,
importDialogVisible
:
false
,
searchParam
:
{
searchName
:
''
,
pageSize
:
15
,
pageNo
:
1
},
totalRows
:
0
,
tableData
:
[],
addParam
:
{
mobilePhone
:
''
,
remark
:
''
},
removeId
:
''
,
removeTel
:
''
,
acceptValue
:
'*/*'
,
importFileName
:
''
}
},
mounted
()
{
this
.
search
();
},
methods
:
{
// 封装一下请求通用的方法
getData
(
type
,
url
,
req
,
callback
)
{
openLoading
(
this
);
this
.
$axios
[
type
](
localStorage
.
getItem
(
"lectureUrl"
)
+
url
,
req
)
.
then
(
res
=>
{
closeLoading
(
this
);
let
data
=
res
.
data
;
if
(
data
.
code
==
"000000"
)
{
if
(
callback
)
callback
(
data
);
}
else
{
this
.
$message
.
error
(
data
.
message
);
}
})
.
catch
(
error
=>
{
closeLoading
(
this
);
this
.
$message
.
error
(
"网络出现点问题"
);
});
},
search
(
param
)
{
if
(
param
)
this
.
searchParam
.
pageNo
=
1
;
this
.
getData
(
"get"
,
`/riskcontrol/blacklist/list?searchName=
${
this
.
searchParam
.
searchName
}
&pageNo=
${
this
.
searchParam
.
pageNo
}
&pageSize=
${
this
.
searchParam
.
pageSize
}
`
,
{},
data
=>
{
this
.
tableData
=
data
.
data
.
list
;
this
.
totalRows
=
data
.
data
.
totalRows
;
}
);
},
// 批量导入
importBatch
()
{
this
.
importDialogVisible
=
true
;
},
confirmImport
()
{
},
// 上传文件
uploadImportFile
(
file
)
{
console
.
log
(
file
)
let
self
=
this
;
this
.
importFileName
=
file
.
name
;
let
arr
=
file
.
type
.
split
(
'/'
);
let
ext
=
"."
+
arr
[
1
];
let
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
let
fileJson
=
{
fileName
:
file
.
name
,
file
:
e
.
target
.
result
.
substr
(
e
.
target
.
result
.
indexOf
(
"base64,"
)
+
7
),
ext
:
ext
};
self
.
base64
=
fileJson
;
console
.
log
(
'fileJson'
,
self
.
base64
);
};
reader
.
readAsDataURL
(
file
);
this
.
getData
(
"post"
,
`/riskcontrol/blacklist/import`
,
{
base64Str
:
self
.
base64
.
file
},
data
=>
{
if
(
data
.
code
==
'000000'
)
{
}
}
);
},
// 下载导入模板
download
()
{
console
.
log
(
'下载模板'
);
setTimeout
(()
=>
{
window
.
open
(
''
);
// 后台给的导入Excel地址
},
500
);
},
// 新增黑名单
addBlackList
()
{
this
.
addDialogVisible
=
true
;
},
confirmAdd
()
{
let
req
=
this
.
addParam
;
this
.
getData
(
"post"
,
`/riskcontrol/blacklist/create`
,
req
,
data
=>
{
if
(
data
.
code
==
'000000'
)
{
this
.
addDialogVisible
=
false
;
this
.
search
();
}
}
);
},
// 从黑名单移除
removeFromBlack
(
row
)
{
this
.
removeId
=
row
.
id
;
this
.
removeTel
=
row
.
mobilePhone
;
this
.
removeDialogVisible
=
true
;
},
confirmRemove
()
{
this
.
getData
(
"delete"
,
`/riskcontrol/blacklist/remove
${
this
.
removeId
}
`
,
{},
data
=>
{
if
(
data
.
code
==
'000000'
)
{
this
.
removeDialogVisible
=
false
;
this
.
search
();
}
}
);
},
handleSizeChange
(
value
)
{
this
.
searchParam
.
pageSize
=
value
;
this
.
search
();
},
handleCurrentChange
(
value
)
{
this
.
searchParam
.
pageNo
=
value
;
this
.
search
();
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.black-container {
}
</
style
>
\ No newline at end of file
src/views/user-path/add-funnel.vue
已删除
100644 → 0
浏览文件 @
3d2a4329
<
template
>
<div
class=
"add-funnel-container"
>
<el-breadcrumb
separator=
"/"
class=
"add-title"
>
<el-breadcrumb-item
:to=
"
{ path: '/user-path' }">漏斗分析
</el-breadcrumb-item>
<el-breadcrumb-item>
新增转化漏斗
</el-breadcrumb-item>
</el-breadcrumb>
<div
class=
"add-content"
>
<div
class=
"con"
>
<el-row
:gutter=
"30"
class=
"row save"
type=
"flex"
style=
"margin-bottom:0;"
>
<el-form
ref=
"form"
:model=
"searchParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-col
:span=
"21"
>
<el-form-item
label=
"漏斗名称"
>
<el-input
:class=
"
{'red-b': disabledSave}"
v-model="searchParam.name"
maxlength="30"
placeholder="请输入漏斗名称"
style="width:430px;"
@blur="validValue">
</el-input>
<span
v-show=
"disabledSave"
style=
"color: red; font-size: 12px;"
>
{{
nameTip
}}
</span>
</el-form-item>
</el-col>
<el-col
:span=
"3"
style=
"padding:0;text-align:right;padding-right:15px;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"saveAddAndEdit"
>
保存
</el-button>
</el-col>
</el-form>
</el-row>
<div
class=
"add-step"
>
<p>
请以用户逐步触发的事件为依据,构造漏斗、系统会自动计算整个过程的转化率。如果事件之间不连续,转化率为0!
</p>
</div>
<div
class=
"step-content"
v-for=
"(item,index) in searchParam.actionModelList"
:key=
"index"
>
<span
class=
"st"
>
步骤
{{
index
+
1
}}
</span>
<el-form
ref=
"form"
class=
"step-form"
:model=
"item"
label-suffix=
":"
style=
"width:100%;"
>
<el-col
:span=
"11"
>
<el-form-item
label=
"步骤名称"
>
<el-input
:class=
"
{'red-b': item.nameCheck
&&
item.actionName}"
v-model="item.actionName"
@input="nameChange(item, index)"
maxlength="30"
placeholder="请输入步骤名称"
style="width:70%">
</el-input>
<p
v-show=
"item.nameCheck && !item.actionName"
style=
"color: red; font-size: 12px;"
>
名称重复,请重新输入
</p>
</el-form-item>
</el-col>
<el-col
:span=
"11"
>
<el-form-item
label=
"触发事件"
>
<el-input
v-show=
"!showEvent"
:class=
"
{'red-b': item.unchecked}"
@focus="getEventData"
v-model="item.eventName"
style="width:75%;"
:title="item.eventName"
placeholder="请选择用户触发事件">
</el-input>
<el-select
v-show=
"showEvent"
v-model=
"item.eventId"
filterable
placeholder=
"请选择用户触发事件"
:class=
"
{'red-b': item.unchecked}"
@blur="selectValid(item, index)"
@change="eventChange(item, index)"
style="width:75%;"
>
<el-option
v-for=
"(eItem,eIndex) in eventSelect"
:key=
"eIndex"
:label=
"eItem.eventName"
:value=
"eItem.eventId"
>
</el-option>
</el-select>
<p
v-show=
"item.unchecked"
style=
"color: red; font-size: 12px;"
>
请选择一个触发事件
</p>
<p
v-show=
"item.repChecked"
style=
"color: red; font-size: 12px;"
>
触发事件重复,请重新选择
</p>
</el-form-item>
</el-col>
</el-form>
<i
v-if=
"index == 0"
class=
"el-icon-remove-outline disable-step"
></i>
<i
v-if=
"index > 0"
class=
"el-icon-remove-outline delete-step"
@
click=
"deleteSteps(index)"
></i>
<i
class=
"el-icon-circle-plus-outline add-step"
@
click=
"addSteps"
></i>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
{
openLoading
,
closeLoading
}
from
"../../common/utils"
;
export
default
{
data
()
{
return
{
showEvent
:
false
,
// 编辑回显时不显示触发事件下拉数据
disabledSave
:
false
,
funnelId
:
''
,
searchParam
:
{
name
:
''
,
actionModelList
:
[
{
actionName
:
''
,
eventId
:
''
}]
},
eventSelect
:
[],
tipText
:
'名称重复,请重新输入'
,
nameTip
:
'请输入漏斗名称'
,
repIndex
:
0
,
flag
:
false
}
},
created
()
{
this
.
funnelId
=
this
.
$route
.
query
.
id
;
},
mounted
()
{
if
(
this
.
funnelId
)
{
// 编辑
this
.
getFunnelDetail
();
}
else
{
// 新增
this
.
getEventList
();
}
},
methods
:
{
// 封装一下请求通用的方法
getData
(
type
,
url
,
req
,
callback
)
{
openLoading
(
this
);
this
.
$axios
[
type
](
localStorage
.
getItem
(
"lectureUrl"
)
+
url
,
req
)
.
then
(
res
=>
{
closeLoading
(
this
);
let
data
=
res
.
data
;
if
(
data
.
code
==
"000000"
)
{
if
(
callback
)
callback
(
data
);
}
else
if
(
data
.
code
==
'227002'
||
data
.
code
==
'227003'
){
this
.
disabledSave
=
true
;
this
.
nameTip
=
'名称重复,请重新输入'
;
}
})
},
// 获取触发事件列表
getEventList
(
item
)
{
this
.
getData
(
"get"
,
`/session/funnel/eventList`
,
{},
res
=>
{
this
.
eventSelect
=
res
.
data
;
}
);
},
getEventData
()
{
this
.
showEvent
=
true
;
this
.
getEventList
();
},
// 编辑获取漏斗详情
getFunnelDetail
()
{
this
.
getData
(
"get"
,
`/session/funnel/detail/
${
this
.
funnelId
}
`
,
{},
res
=>
{
if
(
res
.
code
==
'000000'
)
{
this
.
searchParam
=
res
.
data
;
}
}
);
},
// 漏斗名称是否有值判断
validValue
()
{
if
(
this
.
searchParam
.
name
)
{
this
.
disabledSave
=
false
;
}
},
// 步骤名称不重复
nameChange
(
item
,
index
)
{
this
.
$set
(
this
.
searchParam
.
actionModelList
[
index
],
'nameCheck'
,
false
);
if
(
!
item
.
actionName
)
return
;
for
(
let
i
=
0
;
i
<
this
.
searchParam
.
actionModelList
.
length
;
i
++
)
{
if
(
i
==
index
)
continue
;
if
(
item
.
actionName
==
this
.
searchParam
.
actionModelList
[
i
].
actionName
)
{
setTimeout
(()
=>
{
this
.
searchParam
.
actionModelList
[
index
].
actionName
=
''
;
this
.
$set
(
this
.
searchParam
.
actionModelList
[
index
],
'nameCheck'
,
true
);
},
500
)
}
}
},
// 触发事件选择时重复判断
eventChange
(
item
,
index
)
{
this
.
$set
(
this
.
searchParam
.
actionModelList
[
index
],
'repChecked'
,
false
);
for
(
let
i
=
0
;
i
<
this
.
searchParam
.
actionModelList
.
length
;
i
++
)
{
if
(
index
!=
i
)
{
if
(
item
.
eventId
==
this
.
searchParam
.
actionModelList
[
i
].
eventId
)
{
this
.
$set
(
this
.
searchParam
.
actionModelList
[
index
],
'repChecked'
,
true
);
this
.
searchParam
.
actionModelList
[
index
].
eventId
=
''
;
}
}
}
},
// 触发事件是否为空样式
selectValid
(
item
,
index
)
{
this
.
$set
(
this
.
searchParam
.
actionModelList
[
index
],
'unchecked'
,
false
);
// if(!item.eventId) return;
// for(let i = 0; i
<
this
.
searchParam
.
actionModelList
.
length
;
i
++
)
{
// this.$set(this.searchParam.actionModelList[i], 'repChecked', false);
// if(index != i) {
// if(item.eventId == this.searchParam.actionModelList[i].eventId) {
// this.searchParam.actionModelList[index].eventId = '';
// this.$set(this.searchParam.actionModelList[index], 'repChecked', true);
// }
// }
// }
},
// 保存
saveAddAndEdit
()
{
if
(
!
this
.
searchParam
.
name
)
{
this
.
disabledSave
=
true
;
this
.
nameTip
=
'请输入漏斗名称'
;
return
;
}
for
(
let
i
=
0
;
i
<
this
.
searchParam
.
actionModelList
.
length
;
i
++
)
{
if
(
!
this
.
searchParam
.
actionModelList
[
i
].
eventId
)
{
this
.
$set
(
this
.
searchParam
.
actionModelList
[
i
],
'unchecked'
,
true
);
// 事件名称为空
this
.
$set
(
this
.
searchParam
.
actionModelList
[
i
],
'repChecked'
,
false
);
//事件重复
return
;
}
if
((
this
.
searchParam
.
actionModelList
[
i
].
nameCheck
&&
this
.
searchParam
.
actionModelList
[
i
].
actionName
)
||
this
.
searchParam
.
actionModelList
[
i
].
unchecked
||
this
.
searchParam
.
actionModelList
[
i
].
repChecked
)
{
// 有步骤名称重复
return
;
}
this
.
eventSelect
.
forEach
(
item
=>
{
if
(
this
.
searchParam
.
actionModelList
[
i
].
eventId
==
item
.
eventId
)
{
this
.
$set
(
this
.
searchParam
.
actionModelList
[
i
],
'eventName'
,
item
.
eventName
);
}
});
}
let
req
=
this
.
searchParam
;
for
(
let
i
=
0
;
i
<
req
.
actionModelList
.
length
;
i
++
)
{
if
(
!
req
.
actionModelList
[
i
].
actionName
)
{
req
.
actionModelList
[
i
].
actionName
=
req
.
actionModelList
[
i
].
eventName
;
req
.
actionModelList
[
i
].
nameCheck
=
false
;
}
}
this
.
getData
(
"post"
,
`/session/funnel/save`
,
req
,
res
=>
{
if
(
res
.
code
==
'000000'
)
{
this
.
$message
.
success
(
'转化漏斗保存成功'
);
this
.
$router
.
push
({
path
:
'path-data'
,
query
:
{
id
:
res
.
data
.
id
,
name
:
res
.
data
.
name
}
});
}
}
);
},
// 删除步骤
deleteSteps
(
i
)
{
this
.
$message
.
success
(
'删除成功'
);
this
.
searchParam
.
actionModelList
.
splice
(
i
,
1
);
},
// 增加步骤
addSteps
()
{
this
.
searchParam
.
actionModelList
.
push
({
actionName
:
''
,
eventId
:
''
});
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.add-funnel-container {
margin: -20px -40px;
.red-b {
border: 1px solid red;
}
.add-title {
height: 60px;
line-height: 60px;
padding-left: 40px;
}
.add-content {
background: #F2F2F4;
padding: 20px 0 20px 20px;
min-height: 83vh;
.con {
padding-bottom: 30px;
background: #fff;
min-height: 80vh;
.save {
padding: 20px 20px 0;
margin: 0 !important;
border-bottom: 1px solid #EDEDEE;
}
.add-step {
padding: 30px 40px 0;
font-size: 14px;
color: #4D4C4F;
}
.step-content {
overflow: hidden;
margin: 30px 40px 0px;
border: 1px solid #EDEDEE;
span.st {
float: left;
font-size: 14px;
color: #58ADE8;
padding: 5px;
margin: 20px 20px 0 20px;
border: 1px solid #58ADE8;
border-radius: 3px;
}
.step-form {
width: 80% !important;
padding: 15px 0 0 30px;
}
i {
padding: 10px 20px;
font-size: 20px;
}
.disable-step {
color: #D2D2D3;
}
.delete-step {
color: #58ADE8;
}
.add-step {
color: #58ADE8;
}
}
}
}
}
</
style
>
\ No newline at end of file
src/views/user-path/funnel-data.vue
已删除
100644 → 0
浏览文件 @
3d2a4329
<
template
>
<div
class=
"data-container"
>
<el-breadcrumb
separator=
"/"
class=
"data-title"
>
<el-breadcrumb-item
:to=
"
{ path: '/user-path' }">漏斗分析
</el-breadcrumb-item>
<el-breadcrumb-item>
{{
name
}}
详情
</el-breadcrumb-item>
</el-breadcrumb>
<div
class=
"data-content"
>
<div
class=
"con"
>
<el-row
:gutter=
"30"
class=
"row search"
type=
"flex"
style=
"margin-bottom:0;"
>
<el-form
ref=
"form"
:model=
"searchParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-col
:span=
"12"
>
<el-form-item
label=
"时间"
required
>
<el-date-picker
type=
"date"
placeholder=
"开始时间"
v-model=
"searchParam.startDate"
style=
"width: 200px;"
:picker-options=
"endDateOpt"
value-format=
"yyyy-MM-dd"
>
</el-date-picker>
<span>
-
</span>
<el-date-picker
type=
"date"
placeholder=
"结束时间"
v-model=
"searchParam.endDate"
style=
"width: 200px;"
:picker-options=
"endDateOpt1"
value-format=
"yyyy-MM-dd"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col
:span=
"8"
>
<el-form-item
label=
"版本"
>
<el-select
v-model=
"searchParam.version"
placeholder=
"请选择版本"
style=
"width:200px"
>
<el-option
v-for=
"(eItem,eIndex) in versionSelect"
:key=
"eIndex"
:label=
"eItem"
:value=
"eItem"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col
:span=
"4"
style=
"padding:0;text-align:right;padding-right:15px;"
>
<el-button
type=
"default"
size=
"small"
@
click=
"reset"
>
重置
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"getAnalysisData(searchParam)"
>
筛选
</el-button>
</el-col>
</el-form>
</el-row>
<div
class=
"data-num"
>
<div
class=
"num-text first-num"
>
<span>
总人数
</span>
<p>
{{
funnelData
.
userCountTotal
}}
<span>
人
</span></p>
</div>
<div
class=
"num-text"
>
<span>
总转化率
</span>
<p>
{{
funnelData
.
inversionRateTotal
}}
</p>
</div>
<div
class=
"num-text"
>
<span>
达成目标人数
</span>
<p>
{{
funnelData
.
userCountLast
}}
<span>
人
</span></p>
</div>
<div
class=
"num-text num"
>
<span>
转化率最低步骤
</span>
<p>
{{
funnelData
.
funnelNameLast
}}
</p>
</div>
</div>
<div
class=
"data-analysis"
>
<div
class=
"map-title"
>
转化漏斗详情
</div>
<div
ref=
"chart"
class=
"echart"
></div>
<el-table
class=
"data-table"
:data=
"funnelData.funnelReportModels"
style=
"width: 100%"
>
<el-table-column
prop=
"funnel"
label=
"步骤"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"funnelName"
label=
"步骤名称"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"userCount"
label=
"用户数"
min-width=
"150"
align=
"center"
></el-table-column>
<el-table-column
prop=
"inversionRate"
label=
"较上一步转化率"
min-width=
"150"
align=
"center"
></el-table-column>
<el-table-column
prop=
"inversionRateTotal"
label=
"总转化率"
min-width=
"150"
align=
"center"
></el-table-column>
</el-table>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
let
url
=
'image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAARCAMAAACLgl7OAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAaVBMVEUAAADBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcEAAAD45xibAAAAInRSTlMAmT6WJYwSfBMGZAFHmEgtkBeCCW0KAlI1k5QeiA10A1tc7ah1owAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAB7SURBVCjPtZDZDoAgDAQXvA+8bwX1/3/SGKIBEd+cx07TdgtIiAF0/mygDvnAoYDr2b3nnjP8wOaDUG6J4ncfR9cdScpMzbJECZEXT1/kesyy0n1VPv6AulF908Kg6+9DWN/hjWGUfhpgYV5Ov8ywwgUhguODddtXvXIAjuUEs/70/t4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMTItMTZUMTU6MzM6MDkrMDg6MDCzL2BEAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTEyLTE2VDE1OjMzOjA5KzA4OjAwwnLY+AAAAABJRU5ErkJggg=='
;
import
{
openLoading
,
closeLoading
}
from
"../../common/utils"
;
export
default
{
data
()
{
return
{
funnelId
:
''
,
name
:
''
,
searchParam
:
{
endDate
:
''
,
startDate
:
''
,
version
:
''
},
versionSelect
:
[],
// 版本下拉数据
funnelData
:
{},
endDateOpt
:
{
disabledData
:
(
time
)
=>
{
if
(
this
.
searchParam
.
endDate
!=
""
&&
this
.
searchParam
.
endDate
!=
null
)
{
return
(
time
.
getTime
()
>
new
Date
(
this
.
searchParam
.
endDate
).
getTime
()
);
}
}
},
endDateOpt1
:
{
disabledDate
:
time
=>
{
return
(
time
.
getTime
()
<
(
new
Date
(
this
.
searchParam
.
startDate
).
getTime
()
-
3600
*
1000
*
24
*
1
)
||
time
.
getTime
()
>
(
new
Date
(
this
.
searchParam
.
startDate
).
getTime
()
+
3600
*
1000
*
24
*
29
)
);
}
},
beginTime
:
''
,
endTime
:
''
}
},
created
()
{
this
.
funnelId
=
this
.
$route
.
query
.
id
;
this
.
name
=
this
.
$route
.
query
.
name
;
},
mounted
()
{
//this.searchParam.endDate = new Date().format("yyyy-MM-dd");
let
date1
=
new
Date
();
let
date2
=
new
Date
(
date1
);
let
date3
=
new
Date
(
date1
);
date2
.
setDate
(
date1
.
getDate
()
-
7
);
date3
.
setDate
(
date1
.
getDate
()
-
1
);
let
dt
=
date2
.
getDate
()
>
10
?
date2
.
getDate
()
:
'0'
+
date2
.
getDate
();
let
dt1
=
date3
.
getDate
()
>
10
?
date3
.
getDate
()
:
'0'
+
date3
.
getDate
();
this
.
searchParam
.
startDate
=
date2
.
getFullYear
()
+
"-"
+
(
date2
.
getMonth
()
+
1
)
+
"-"
+
dt
;
this
.
searchParam
.
endDate
=
date3
.
getFullYear
()
+
"-"
+
(
date3
.
getMonth
()
+
1
)
+
"-"
+
dt1
;
this
.
beginTime
=
date2
.
getFullYear
()
+
"-"
+
(
date2
.
getMonth
()
+
1
)
+
"-"
+
dt
;
this
.
endTime
=
date3
.
getFullYear
()
+
"-"
+
(
date3
.
getMonth
()
+
1
)
+
"-"
+
dt1
;
this
.
getVersionData
();
},
methods
:
{
// 封装一下请求通用的方法
getData
(
type
,
url
,
req
,
callback
)
{
openLoading
(
this
);
this
.
$axios
[
type
](
localStorage
.
getItem
(
"lectureUrl"
)
+
url
,
req
)
.
then
(
res
=>
{
closeLoading
(
this
);
let
data
=
res
.
data
;
if
(
data
.
code
==
"000000"
)
{
if
(
callback
)
callback
(
data
);
}
else
{
this
.
$message
.
error
(
data
.
message
);
}
})
},
// 获取版本号数据
getVersionData
()
{
this
.
getData
(
"get"
,
`/session/funnel/version/list`
,
{},
res
=>
{
if
(
res
.
code
==
'000000'
)
{
this
.
versionSelect
=
res
.
data
;
this
.
searchParam
.
version
=
this
.
versionSelect
[
0
];
this
.
getAnalysisData
(
this
.
searchParam
);
}
}
);
},
// 获取漏斗分析数据
getAnalysisData
(
req
)
{
if
(
!
req
.
startDate
||
!
req
.
endDate
)
{
this
.
$message
.
info
(
'请选择时间'
);
return
;
}
this
.
getData
(
"get"
,
`/session/funnel/report?endDate=
${
req
.
endDate
}
&funnelId=
${
this
.
funnelId
}
&startDate=
${
req
.
startDate
}
&version=
${
req
.
version
}
`
,
{},
res
=>
{
if
(
res
.
code
==
'000000'
)
{
this
.
funnelData
=
res
.
data
;
this
.
initCharts
();
//this.initEchart();
}
}
);
},
// 初始化图标--漏斗图
initCharts
()
{
let
lineargroup
=
this
.
funnelData
.
funnelReportModels
;
let
len
=
lineargroup
.
length
;
let
colorObj
=
{
type
:
'linear'
,
x
:
0
,
y
:
0
,
x2
:
0
,
y2
:
1
,
colorStops
:
[{
offset
:
0
,
color
:
'#1cd389'
// 0% 处的颜色
},
{
offset
:
1
,
color
:
'#668eff'
// 100% 处的颜色
}],
global
:
false
// 缺省为 false
};
let
myChart
=
{},
data1
=
[],
dataArr
=
[],
valueArr
=
[],
lineArr
=
[],
linksArr
=
[],
arrowTop
=
0
,
arrowH
=
0
,
lineTop
=
0
,
lineLeft
=
0
,
lineHeight
=
0
,
blackH
;
if
(
len
==
2
)
{
blackH
=
300
;
arrowTop
=
105
;
arrowH
=
130
;
lineTop
=
50
;
lineLeft
=
'4%'
;
lineHeight
=
306
;
}
else
if
(
len
==
3
)
{
blackH
=
300
;
arrowTop
=
115
;
arrowH
=
130
;
lineTop
=
30
;
lineLeft
=
'30%'
;
lineHeight
=
306
;
}
else
if
(
len
==
4
)
{
blackH
=
300
;
arrowTop
=
88
;
arrowH
=
210
;
lineTop
=
30
;
lineLeft
=
'45%'
;
lineHeight
=
306
;
}
else
if
(
len
==
5
)
{
blackH
=
300
;
arrowTop
=
70
;
arrowH
=
260
;
lineTop
=
20
;
lineLeft
=
'42%'
;
lineHeight
=
346
;
}
else
if
(
len
==
6
)
{
blackH
=
300
;
arrowTop
=
60
;
arrowH
=
300
;
lineTop
=
20
;
lineLeft
=
'40%'
;
lineHeight
=
366
;
}
else
if
(
len
==
7
)
{
blackH
=
360
;
arrowTop
=
60
;
arrowH
=
390
;
lineTop
=
20
;
lineLeft
=
'35%'
;
lineHeight
=
456
;
}
else
{
blackH
=
340
;
arrowTop
=
50
;
arrowH
=
400
;
lineTop
=
10
;
lineLeft
=
'35%'
;
lineHeight
=
466
;
}
for
(
let
i
=
0
;
i
<
lineargroup
.
length
;
i
++
)
{
let
obj1
=
{
value
:
200
-
i
*
40
,
num
:
lineargroup
[
i
].
userCount
,
name
:
lineargroup
[
i
].
funnelName
};
data1
.
push
(
obj1
);
if
(
i
!=
(
lineargroup
.
length
-
1
))
{
dataArr
.
push
(
'转化率'
);
valueArr
.
push
({
value
:
'100'
});
// 步骤箭头
linksArr
.
push
({
// 转化率线
source
:
lineargroup
[
i
].
funnelName
,
target
:
lineargroup
[
i
+
1
].
funnelName
,
value
:
lineargroup
[
i
+
1
].
inversionRate
,
lineStyle
:
{
normal
:
{
curveness
:
parseInt
(
len
-
i
)
+
4
,
color
:
colorObj
}
}
})
}
lineArr
.
push
({
name
:
lineargroup
[
i
].
funnelName
,
x
:
400
,
y
:
0
+
i
*
15
});
}
let
option
=
{
backgroundColor
:
'#ffffff'
,
grid
:
{
top
:
arrowTop
,
// 箭头距离顶部高度 3-115 4-
left
:
"-44%"
,
right
:
20
,
height
:
arrowH
,
// 箭头之间的距离 3-145 4-
bottom
:
'0'
},
xAxis
:
{
show
:
false
},
yAxis
:
[{
show
:
false
,
boundaryGap
:
false
,
type
:
"category"
,
data
:
dataArr
}],
series
:
[{
// 内容块
top
:
0
,
type
:
'funnel'
,
height
:
blackH
+
len
*
20
,
// 块高度
gap
:
40
,
// 块间距
minSize
:
300
,
// 块两边斜度
left
:
'5%'
,
// 块左边距离
width
:
'45%'
,
// 块宽度
label
:
{
show
:
true
,
position
:
'inside'
,
fontSize
:
'14'
,
formatter
:
function
(
d
)
{
var
newParamsName
=
""
;
var
paramsNameNumber
=
d
.
name
.
length
;
var
provideNumber
=
30
;
//一行显示几个字
var
rowNumber
=
Math
.
ceil
(
paramsNameNumber
/
provideNumber
);
if
(
paramsNameNumber
>
provideNumber
)
{
for
(
var
p
=
0
;
p
<
rowNumber
;
p
++
)
{
var
tempStr
=
""
;
var
start
=
p
*
provideNumber
;
var
end
=
start
+
provideNumber
;
if
(
p
==
rowNumber
-
1
)
{
tempStr
=
d
.
name
.
substring
(
start
,
paramsNameNumber
);
}
else
{
tempStr
=
d
.
name
.
substring
(
start
,
end
)
+
"
\n
"
;
}
newParamsName
+=
tempStr
;
}
}
else
{
newParamsName
=
d
.
name
;
}
return
newParamsName
+
'{aa|}
\
n'
+
d
.
data
.
num
},
rich
:
{
aa
:
{
padding
:
[
8
,
0
,
6
,
0
]
}
}
},
data
:
data1
},
{
type
:
'pictorialBar'
,
// 步骤箭头
name
:
''
,
symbolSize
:
[
'32'
,
'17'
],
symbolPosition
:
'center'
,
symbol
:
url
,
animation
:
true
,
symbolClip
:
true
,
z
:
10
,
data
:
valueArr
},
{
// 转化率线
z
:
1
,
top
:
lineTop
,
left
:
lineLeft
,
height
:
lineHeight
,
type
:
'graph'
,
layout
:
'none'
,
symbolSize
:
0
,
roam
:
false
,
edgeSymbol
:
[
'circle'
,
'arrow'
],
lineStyle
:
{
normal
:
{
width
:
4
,
}
},
edgeLabel
:
{
// 转化率数字
normal
:
{
show
:
true
,
rotate
:
90
,
position
:
'middle'
,
borderRadius
:
4
,
color
:
'#333'
,
verticalAlign
:
'middle'
,
fontSize
:
14
,
legendHoverLink
:
true
,
padding
:
[
30
,
20
,
5
,
10
],
formatter
:
function
(
d
)
{
if
(
d
.
value
)
{
var
ins
=
'{img1|} '
+
'{words|'
+
d
.
value
+
'}'
;
return
ins
;
}
},
rich
:
{
img1
:
{
width
:
18
,
height
:
16
},
words
:
{
color
:
'#333'
,
position
:
'right'
,
fontSize
:
14
,
lineHeight
:
20
,
padding
:
[
0
,
0
,
5
,
0
],
}
}
}
},
data
:
lineArr
,
links
:
linksArr
}
]
};
myChart
=
this
.
$echarts
.
init
(
this
.
$refs
.
chart
);
myChart
.
setOption
(
option
);
},
// 初始化图--柱状图
initEchart
()
{
let
dataX
=
[],
dataY
=
[];
let
lineargroup
=
this
.
funnelData
.
funnelReportModels
;
for
(
let
i
=
0
;
i
<
lineargroup
.
length
;
i
++
)
{
dataX
.
push
(
lineargroup
[
i
].
funnelName
);
dataY
.
push
(
lineargroup
[
i
].
inversionRate
);
}
let
option
=
{
tooltip
:
{
trigger
:
'axis'
,
axisPointer
:
{
type
:
'cross'
,
crossStyle
:
{
color
:
'#999'
}
}
},
xAxis
:
[
{
type
:
'category'
,
data
:
dataX
,
axisPointer
:
{
type
:
'shadow'
}
}
],
yAxis
:
[
{
type
:
'value'
,
name
:
''
,
min
:
0
,
max
:
100
,
interval
:
25
,
axisLabel
:
{
formatter
:
'{value} %'
}
}
],
series
:
[
{
type
:
'bar'
,
barWidth
:
30
,
data
:
[
80
,
60
,
20
],
// dataY
itemStyle
:
{
normal
:
{
label
:
{
show
:
true
,
//开启显示
position
:
'top'
,
//在上方显示
textStyle
:
{
//数值样式
color
:
'black'
,
fontSize
:
16
}
},
color
:
function
(
params
)
{
return
'#58ADE8'
}
}
}
},
{
name
:
'折线'
,
type
:
'line'
,
itemStyle
:
{
/*设置折线颜色*/
normal
:
{
color
:
'#58ADE8'
}
},
data
:
[
80
,
60
,
20
]
// dataY
}
]
};
let
myChart
=
this
.
$echarts
.
init
(
this
.
$refs
.
chart
);
myChart
.
setOption
(
option
);
},
reset
()
{
this
.
searchParam
=
{
endDate
:
this
.
endTime
,
startDate
:
this
.
beginTime
,
version
:
this
.
versionSelect
[
0
]
};
this
.
getAnalysisData
(
this
.
searchParam
);
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.data-container {
margin: -20px -40px;
.data-title {
height: 60px;
line-height: 60px;
padding-left: 40px;
}
.data-content {
background: #F2F2F4;
padding: 20px 0 20px 20px;
.con {
background: #fff;
padding-bottom: 50px;
.search {
padding: 20px 20px 0;
margin: 0 !important;
border-bottom: 1px solid #EDEDEE;
}
.data-num {
display: flex;
padding: 20px 20px 0 30px;
.num-text {
width: 15%;
border-right: 1px solid #EDEDEE;
text-align: center;
span {
font-size: 12px;
color: #b2b2b3;
}
p {
padding-top: 8px;
}
}
.first-num {
width: 10%;
text-align: left;
}
.num {
width: 20%;
border: none;
}
}
.data-analysis {
// overflow: hidden;
margin: 20px 20px 0 30px;
padding: 0px 20px 30px;
border: 1px solid #EDEDEE;
box-shadow: 5px 0px 30px #EDEDEE;
.map-title {
height: 60px;
line-height: 60px;
border-bottom: 1px solid #EDEDEE;
}
.echart {
padding-top: 20px;
width: 100%;
min-height: 550px;
}
.data-table {
margin-top: 20px;
}
}
}
}
}
</
style
>
\ No newline at end of file
src/views/user-path/funnel.vue
已删除
100644 → 0
浏览文件 @
3d2a4329
<
template
>
<div
class=
"funnel-container"
>
<div
class=
"funnel-title"
>
漏斗分析
</div>
<div
class=
"funnel-content"
>
<div
class=
"con"
>
<el-row
:gutter=
"30"
class=
"row search"
type=
"flex"
style=
"margin-bottom:0;"
>
<el-form
ref=
"form"
:model=
"searchParam"
label-suffix=
":"
style=
"width:100%;"
>
<el-col
:span=
"21"
>
<el-form-item
label=
"漏斗名称"
>
<el-input
v-model=
"searchParam.searchName"
maxlength=
"20"
placeholder=
"请输入漏斗名称"
style=
"width:288px;"
></el-input>
</el-form-item>
</el-col>
<el-col
:span=
"3"
style=
"padding:0;text-align:right;padding-right:15px;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"search(1)"
>
搜索
</el-button>
</el-col>
</el-form>
</el-row>
<div
class=
"search-table-con"
>
<el-row
:gutter=
"10"
class=
"row create-button"
style=
"margin-right:0;"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"addData"
>
+新增转化漏斗
</el-button>
</el-row>
<!-- 表格 -->
<el-table
class=
"search-table"
:data=
"tableData"
style=
"width: 100%"
:empty-text=
"tableText"
>
<el-table-column
prop=
"name"
label=
"漏斗名称"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"stepStartName"
label=
"起始步骤"
min-width=
"140"
align=
"center"
></el-table-column>
<el-table-column
prop=
"stepEndName"
label=
"转化目标"
min-width=
"150"
align=
"center"
></el-table-column>
<el-table-column
label=
"操作"
fixed=
"right"
align=
"center"
min-width=
"200"
>
<template
slot-scope=
"scope"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"visitData(scope.row)"
>
查看数据
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"editColumn(scope.row)"
>
编辑
</el-button>
<el-button
type=
"danger"
size=
"small"
@
click=
"deleteConfirm(scope.row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<div
class=
"pagination"
>
<el-pagination
background
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page=
"searchParam.pageNo"
:page-sizes=
"[15, 30, 50, 100, 200, 500, 700, 1000, 1500, 2000]"
:page-size=
"searchParam.pageSize"
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"totalRows"
>
</el-pagination>
</div>
<!-- 删除确认框 -->
<el-dialog
class=
"delete-dialog"
:visible
.
sync=
"dialogVisible"
width=
"30%"
>
<span><i
class=
"el-icon-circle-close"
style=
"color: red"
></i>
确认要删除这条转化漏斗吗?
</span>
<span
class=
"tip"
>
删除该转化漏斗数据将不会保留
</span>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirm"
>
确 定
</el-button>
</span>
</el-dialog>
</div>
</div>
</div>
</div>
</template>
<
script
>
import
{
openLoading
,
closeLoading
}
from
"../../common/utils"
;
export
default
{
data
()
{
return
{
tableText
:
'暂未创建漏斗'
,
searchParam
:
{
searchName
:
''
,
pageNo
:
1
,
pageSize
:
15
},
totalRows
:
0
,
tableData
:
[],
dialogVisible
:
false
,
deleteId
:
''
}
},
mounted
()
{
this
.
search
();
},
methods
:
{
// 封装一下请求通用的方法
getData
(
type
,
url
,
req
,
callback
)
{
openLoading
(
this
);
this
.
$axios
[
type
](
localStorage
.
getItem
(
"lectureUrl"
)
+
url
,
req
)
.
then
(
res
=>
{
closeLoading
(
this
);
let
data
=
res
.
data
;
if
(
data
.
code
==
"000000"
)
{
if
(
callback
)
callback
(
data
);
}
else
{
this
.
$message
.
error
(
data
.
message
);
}
})
},
search
(
param
)
{
if
(
param
)
this
.
searchParam
.
pageNo
=
1
;
let
req
=
this
.
searchParam
;
this
.
getData
(
"get"
,
`/session/funnel/list?searchName=
${
this
.
searchParam
.
searchName
}
&pageNo=
${
this
.
searchParam
.
pageNo
}
&pageSize=
${
this
.
searchParam
.
pageSize
}
`
,
{},
res
=>
{
this
.
tableData
=
res
.
data
.
data
;
this
.
totalRows
=
res
.
data
.
totalRows
;
if
(
this
.
tableData
.
length
==
0
)
{
this
.
tableText
=
param
?
"暂无数据"
:
'暂未创建漏斗'
;
}
}
);
},
// 新增漏斗
addData
()
{
this
.
$router
.
push
({
path
:
'add-funnel'
});
},
// 查看数据
visitData
(
row
)
{
this
.
$router
.
push
({
path
:
'path-data'
,
query
:
{
id
:
row
.
id
,
name
:
row
.
name
}
});
},
// 编辑
editColumn
(
row
)
{
this
.
$router
.
push
({
path
:
'add-funnel'
,
query
:
{
id
:
row
.
id
}});
},
// 删除确认框
deleteConfirm
(
row
)
{
this
.
dialogVisible
=
true
;
this
.
deleteId
=
row
.
id
;
},
confirm
()
{
this
.
getData
(
"delete"
,
`/session/funnel/remove/
${
this
.
deleteId
}
`
,
{},
res
=>
{
if
(
res
.
code
==
'000000'
)
{
this
.
dialogVisible
=
false
;
this
.
$message
.
success
(
'删除成功'
);
this
.
search
();
}
}
);
},
handleSizeChange
(
value
)
{
this
.
searchParam
.
pageSize
=
value
;
this
.
search
();
},
handleCurrentChange
(
value
)
{
this
.
searchParam
.
pageNo
=
value
;
this
.
search
();
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.funnel-container {
margin: -20px -40px;
.funnel-title {
height: 60px;
line-height: 60px;
padding-left: 40px;
}
.funnel-content {
background: #F2F2F4;
padding: 20px 0 20px 20px;
min-height: 83vh;
.con {
padding-bottom: 30px;
background: #fff;
min-height: 80vh;
.search {
padding: 20px 20px 0;
margin: 0 !important;
border-bottom: 1px solid #EDEDEE;
}
.search-table-con {
padding: 0 40px;
.create-button {
margin-top: 20px;
}
}
.delete-dialog {
span{
display: block;
font-size: 16px;
font-weight: 700;
margin-left: 40px;
i {
display: inline-block;
font-size: 20px;
color: red;
margin-right: 10px;
}
}
span.tip {
font-size: 14px;
font-weight: 400;
color: #aaa;
margin: 15px 0 0 70px;
}
}
}
}
}
</
style
>
\ No newline at end of file
写
预览
Markdown
格式
0%
请重试
or
附加一个文件
附加文件
取消
您添加了
0
人
到此讨论。请谨慎行事。
先完成此消息的编辑!
取消
想要评论请
注册
或
登录