Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
罗鑫霖
/
vion-tools
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 57a5e9d7
authored
Nov 09, 2023
by
李乾广
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
增加店铺客流来源轨迹分析页面
1 parent
39163ce7
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
447 additions
and
1 deletions
src/router/index.js
src/views/Main/Main.vue
src/views/SourceTrajectoryAnalysis/ClusterResult/ClusterResult.less
src/views/SourceTrajectoryAnalysis/ClusterResult/ClusterResult.vue
src/views/SourceTrajectoryAnalysis/ClusterResult/ClusterResultApi.js
src/views/SourceTrajectoryAnalysis/SourceTrajectoryAnalysisApi.js
src/views/SourceTrajectoryAnalysis/index.vue
src/router/index.js
View file @
57a5e9d
...
...
@@ -34,6 +34,10 @@ const menuRoute = [
component
:
()
=>
import
(
"@/views/SnapshotCluster1/SnapshotCluster.vue"
),
},
{
path
:
'SourceTrajectoryAnalysis'
,
component
:
()
=>
import
(
"@/views/SourceTrajectoryAnalysis/index.vue"
),
},
{
path
:
'EquipmentTimeErrorVerification'
,
component
:
()
=>
import
(
"@/views/EquipmentTimeErrorVerification/EquipmentTimeErrorVerification.vue"
),
},
...
...
src/views/Main/Main.vue
View file @
57a5e9d
...
...
@@ -17,7 +17,7 @@
</el-header>
<el-main
style=
"padding: 0"
>
<el-container>
<el-aside
style=
"background: #001529"
width=
"
19
0px"
>
<el-aside
style=
"background: #001529"
width=
"
20
0px"
>
<a-menu
mode=
"inline"
theme=
"dark"
v-model:selectedKeys=
"selectedKeys"
@
click=
"onClick"
>
<a-menu-item
:key=
"'/Main/DataRerun'"
>
<div
class=
"flex-vertical-center"
>
...
...
@@ -121,6 +121,12 @@
<span
style=
"padding: 0 5px"
>
抓拍聚类删除
</span>
</div>
</a-menu-item>
<a-menu-item
:key=
"'/Main/SourceTrajectoryAnalysis'"
>
<div
class=
"flex-vertical-center"
>
<img
:src=
"require('./Icons/6.svg')"
style=
"height: auto;width:20px"
/>
<span
style=
"padding: 0 5px"
>
店铺客流来源轨迹分析
</span>
</div>
</a-menu-item>
</a-menu>
</el-aside>
<el-main>
...
...
src/views/SourceTrajectoryAnalysis/ClusterResult/ClusterResult.less
0 → 100644
View file @
57a5e9d
.single-image {
height: 300px;
width: 100%;
}
.direction{
font-weight: 900;
background-color: red;
color: white;
}
.direction1{
background-color: green;
}
.direction0{
background-color: orange;
}
src/views/SourceTrajectoryAnalysis/ClusterResult/ClusterResult.vue
0 → 100644
View file @
57a5e9d
This diff is collapsed.
Click to expand it.
src/views/SourceTrajectoryAnalysis/ClusterResult/ClusterResultApi.js
0 → 100644
View file @
57a5e9d
import
axiosInstance
from
"@/Request/PublicAxiosInstance"
import
{
filterEmptyValueInObject
}
from
"@/PublicUtil/PublicUtil"
class
ClusterResultApi
{
getClusterResultList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/faceRecognitions/faceRecordGroup`
,
params
:
filterEmptyValueInObject
(
data
)
}
)
}
getAccountList
()
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/accounts`
,
}
)
}
getPlazaList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/malls`
,
params
:
filterEmptyValueInObject
(
{
accountIds
:
data
.
account_id
},
)
}
)
}
getZoneList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/zones/zoneList`
,
params
:
filterEmptyValueInObject
(
{
account_id
:
data
.
account_id
,
plaza_id
:
data
.
plaza_id
,
},
)
}
)
}
getGateList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/gates/gateByInfo`
,
params
:
filterEmptyValueInObject
(
{
account_id
:
data
.
account_id
,
plaza_id
:
data
.
plaza_id
,
zone_id
:
data
.
zone_id
,
type
:
data
.
type
,
},
)
}
)
}
getBodyPoint
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/feature/bodyPoint`
,
params
:
filterEmptyValueInObject
(
data
)
}
)
}
}
const
clusterResultApi
=
new
ClusterResultApi
()
export
default
clusterResultApi
src/views/SourceTrajectoryAnalysis/SourceTrajectoryAnalysisApi.js
0 → 100644
View file @
57a5e9d
import
axiosInstance
from
"@/Request/PublicAxiosInstance"
import
{
filterEmptyValueInObject
}
from
"@/PublicUtil/PublicUtil"
class
SourceTrajectoryAnalysisApi
{
getList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/track/list`
,
params
:
filterEmptyValueInObject
(
data
)
}
)
}
}
const
sourceTrajectoryAnalysisApi
=
new
SourceTrajectoryAnalysisApi
()
export
default
sourceTrajectoryAnalysisApi
src/views/SourceTrajectoryAnalysis/index.vue
0 → 100644
View file @
57a5e9d
<
template
>
<a-form
:model=
"queryForm"
layout=
"inline"
>
<a-form-item
label=
"集团:"
style=
"padding: 5px 0;margin-bottom: 24px;"
>
<a-select
v-model:value=
"queryForm.account_id"
style=
"width: 280px"
@
change=
"onAccountChange"
:options=
"accountList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"广场:"
style=
"padding: 5px 0;margin-bottom: 24px;"
>
<a-select
v-model:value=
"queryForm.plaza_id"
style=
"width: 280px"
@
change=
"onPlazaChange"
:options=
"plazaList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"区域信息:"
style=
"padding: 5px 0;margin-bottom: 24px;"
>
<a-select
v-model:value=
"queryForm.zone_id"
style=
"width: 240px"
@
change=
"onZoneChange"
:options=
"zoneList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"日期:"
style=
"padding: 5px 0;margin-bottom: 24px;"
>
<a-date-picker
v-model:value=
"queryForm.countDate"
style=
"width: 280px"
/>
</a-form-item>
<a-form-item
style=
"padding: 5px 0;margin-bottom: 24px;"
>
<a-button
type=
"primary"
@
click=
"search"
>
查询
</a-button>
</a-form-item>
</a-form>
<a-table
:dataSource=
"dataList"
v-loading=
"isLoading"
:columns=
"[
{
title: 'person_unid',
dataIndex: 'personUnid',
align:'center',
slots: {
customRender: 'accountname',
},
},
{
title: '第一次出现的地点',
dataIndex: 'firstGateName',
align:'center',
},
{
title: '第一次出现的时间',
dataIndex: 'fistCountTime',
align:'center',
},
{
title: '进入时间',
dataIndex: 'inTime',
align:'center',
},
{
title: '离开时间',
dataIndex: 'outTime',
align:'center',
},
{
title: '停留时间(毫秒)',
dataIndex: 'residenceTime',
align:'center',
},
{
title: '最后一次出现的地点',
dataIndex: 'lastGateName',
align:'center',
},
{
title: '最后一次出现的时间',
dataIndex: 'lastCountTime',
align:'center',
},
{
title: '到过的店铺数量',
dataIndex: 'inZoneNum',
align:'center',
},
{
title: '是否多次进出',
dataIndex: 'manyTimes',
align:'center',
},
{
title: '操作',
dataIndex: 'operation',
align: 'center',
width:100,
slots: {
customRender: 'operation',
},
}
]" :pagination="false">
<template
#
operation=
"
{ record }">
<div>
<a-button
@
click=
"showDetail(record)"
type=
"primary"
>
查看详情
</a-button>
</div>
</
template
>
</a-table>
<a-pagination
v-model:current=
"pageNum"
v-model:pageSize=
"pageSize"
:total=
"total"
:show-total=
"total => `共 ${total} 条`"
:pageSizeOptions=
"['10', '20']"
@
change=
"onPageNumChange"
@
showSizeChange=
"onPageSizeChange"
show-size-changer
show-quick-jumper
style=
"text-align:center;margin-top: 10px;"
/>
<ClusterResult
ref=
"ClusterResultRef"
/>
</template>
<
script
>
import
moment
from
'moment'
import
{
isArray
}
from
'@/PublicUtil/Judgment'
import
{
defineComponent
,
ref
,
toRaw
,
reactive
}
from
'vue'
import
{
filterEmptyValueInObject
,
formatDate
}
from
'@/PublicUtil/PublicUtil'
import
clusterResultApi
from
'@/views/SnapshotCluster/ClusterResult/ClusterResultApi'
import
SourceTrajectoryAnalysisApi
from
'@/views/SourceTrajectoryAnalysis/SourceTrajectoryAnalysisApi'
import
ClusterResult
from
'@/views/SourceTrajectoryAnalysis/ClusterResult/ClusterResult.vue'
export
default
defineComponent
({
components
:
{
ClusterResult
,
},
setup
()
{
const
ClusterResultRef
=
ref
();
const
pageNum
=
ref
(
1
)
const
pageSize
=
ref
(
10
)
const
total
=
ref
()
const
dataList
=
ref
([])
const
isLoading
=
ref
(
false
)
const
accountList
=
ref
([])
const
plazaList
=
ref
([])
const
zoneList
=
ref
([])
const
queryForm
=
reactive
({
account_id
:
''
,
plaza_id
:
''
,
zone_id
:
''
,
countDate
:
moment
(
moment
().
format
(
'YYYY-MM-DD'
),
'YYYY-MM-DD'
)
})
const
searchCondition
=
ref
({})
// if (window.localStorage.getItem('searchCondition')) {
// searchCondition.value = JSON.parse(window.localStorage.getItem('searchCondition'));
// queryForm.account_id = searchCondition.value.zone_id;
// queryForm.plaza_id = searchCondition.value.plaza_id;
// }
const
getAccountList
=
function
()
{
queryForm
.
account_id
=
''
accountList
.
value
=
[]
clusterResultApi
.
getAccountList
().
then
(
(
r
)
=>
{
if
(
isArray
(
r
))
{
for
(
const
item
of
r
)
{
accountList
.
value
.
push
({
value
:
item
.
id
,
label
:
item
.
name
,
})
}
if
(
accountList
.
value
.
length
)
{
if
(
searchCondition
.
value
.
account_id
&&
searchCondition
.
value
.
account_id
.
length
>
0
)
{
queryForm
.
account_id
=
searchCondition
.
value
.
account_id
}
else
{
queryForm
.
account_id
=
accountList
.
value
[
0
].
value
}
getPlazaList
()
}
}
}
)
}
const
onAccountChange
=
function
()
{
getPlazaList
(
1
)
}
const
getPlazaList
=
function
(
val
)
{
queryForm
.
plaza_id
=
''
plazaList
.
value
=
[]
if
(
!
queryForm
.
account_id
.
toString
())
{
return
}
clusterResultApi
.
getPlazaList
({
account_id
:
queryForm
.
account_id
.
toString
()
}).
then
(
(
r
)
=>
{
if
(
isArray
(
r
))
{
for
(
const
item
of
r
)
{
plazaList
.
value
.
push
({
value
:
item
.
id
,
label
:
item
.
name
,
})
}
if
(
plazaList
.
value
.
length
>
0
)
{
if
(
!
val
&&
searchCondition
.
value
.
plaza_id
&&
searchCondition
.
value
.
plaza_id
.
length
>
0
)
{
queryForm
.
plaza_id
=
searchCondition
.
value
.
plaza_id
}
else
{
queryForm
.
plaza_id
=
plazaList
.
value
[
0
].
value
}
getZoneList
(
1
)
}
}
}
)
}
const
onPlazaChange
=
function
()
{
getZoneList
(
1
)
}
const
getZoneList
=
function
(
val
)
{
queryForm
.
zone_id
=
''
zoneList
.
value
=
[]
clusterResultApi
.
getZoneList
({
account_id
:
queryForm
.
account_id
,
plaza_id
:
queryForm
.
plaza_id
,
}).
then
(
(
r
)
=>
{
if
(
isArray
(
r
))
{
for
(
const
item
of
r
)
{
zoneList
.
value
.
push
({
value
:
item
.
id
,
label
:
item
.
name
,
})
}
if
(
zoneList
.
value
.
length
)
{
if
(
val
&&
searchCondition
.
value
.
zone_id
&&
searchCondition
.
value
.
zone_id
.
length
>
0
)
{
queryForm
.
zone_id
=
searchCondition
.
value
.
zone_id
}
else
{
queryForm
.
zone_id
=
zoneList
.
value
[
0
].
value
}
}
confirmSearch
()
}
}
)
}
const
onZoneChange
=
function
()
{
// confirmSearch()
}
const
onPageNumChange
=
function
(
num
)
{
pageNum
.
value
=
num
confirmSearch
()
}
const
onPageSizeChange
=
function
(
current
,
size
)
{
pageNum
.
value
=
1
pageSize
.
value
=
size
confirmSearch
()
}
const
confirmSearch
=
function
()
{
isLoading
.
value
=
true
const
rawData
=
toRaw
(
queryForm
)
const
data
=
filterEmptyValueInObject
({
page
:
pageNum
.
value
-
1
,
pageSize
:
pageSize
.
value
,
countDate
:
formatDate
(
rawData
.
countDate
),
zoneId
:
rawData
.
zone_id
,
mallId
:
rawData
.
plaza_id
,
})
dataList
.
value
=
[],
total
.
value
=
0
SourceTrajectoryAnalysisApi
.
getList
(
data
).
then
(
(
r
)
=>
{
isLoading
.
value
=
false
if
(
r
.
msg_code
==
200
)
{
dataList
.
value
=
r
.
data
.
persons
total
.
value
=
r
.
data
.
pageNum
}
}
)
}
const
search
=
function
()
{
pageNum
.
value
=
1
pageSize
.
value
=
10
confirmSearch
()
}
const
__main
=
function
()
{
getAccountList
()
}
const
showDetail
=
function
(
row
)
{
const
rawData
=
toRaw
(
queryForm
)
const
data
=
filterEmptyValueInObject
({
page
:
0
,
pageSize
:
10
,
account_id
:
rawData
.
account_id
,
plaza_id
:
rawData
.
plaza_id
,
type
:
0
,
picType
:
2
,
startTime
:
formatDate
(
rawData
.
countDate
)
+
' 00:00:00'
,
endTime
:
formatDate
(
rawData
.
countDate
)
+
' 23:59:59'
,
personUnid
:
row
.
personUnid
,
direction
:
'-1,1'
,
})
// console.log(data)
ClusterResultRef
.
value
.
initDialog
(
data
);
}
__main
()
return
{
ClusterResultRef
,
accountList
,
onAccountChange
,
plazaList
,
zoneList
,
onPlazaChange
,
onZoneChange
,
queryForm
,
pageNum
,
pageSize
,
total
,
isLoading
,
dataList
,
onPageNumChange
,
onPageSizeChange
,
confirmSearch
,
search
,
showDetail
}
},
})
</
script
>
\ No newline at end of file
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment