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 3ca4c554
authored
Jan 19, 2024
by
李乾广
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
试乘接待开发,批次开发
1 parent
d94b1f16
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
2270 additions
and
27 deletions
src/router/index.js
src/views/Main/Main.vue
src/views/SnapshotCluster/ClusterResult/ClusterResult.vue
src/views/SnapshotCluster/SnapshotCluster.vue
src/views/SnapshotCluster/SnapshotRecord/SnapshotRecord.vue
src/views/SnapshotCluster/batchesResult/batchesResult.less
src/views/SnapshotCluster/batchesResult/batchesResult.vue
src/views/SnapshotCluster/batchesResult/batchesResultApi.js
src/views/TestDriveHospitality/ClusterResult/ClusterResult.less
src/views/TestDriveHospitality/ClusterResult/ClusterResult.vue
src/views/TestDriveHospitality/ClusterResult/ClusterResultApi.js
src/views/TestDriveHospitality/SnapshotCluster.vue
src/views/TestDriveHospitality/SnapshotRecord/SnapshotRecord.less
src/views/TestDriveHospitality/SnapshotRecord/SnapshotRecord.vue
src/views/TestDriveHospitality/SnapshotRecord/SnapshotRecordApi.js
src/views/TestDriveHospitality/imgDialog.vue
src/views/TestDriveHospitality/singleImgComparisonDialog.vue
src/router/index.js
View file @
3ca4c55
...
...
@@ -34,6 +34,10 @@ const menuRoute = [
component
:
()
=>
import
(
"@/views/SnapshotCluster1/SnapshotCluster.vue"
),
},
{
path
:
'TestDriveHospitality'
,
component
:
()
=>
import
(
"@/views/TestDriveHospitality/SnapshotCluster.vue"
),
},
{
path
:
'SourceTrajectoryAnalysis'
,
component
:
()
=>
import
(
"@/views/SourceTrajectoryAnalysis/index.vue"
),
},
...
...
src/views/Main/Main.vue
View file @
3ca4c55
...
...
@@ -55,6 +55,12 @@
<span
style=
"padding: 0 5px"
>
抓拍聚类
</span>
</div>
</a-menu-item>
<a-menu-item
:key=
"'/Main/TestDriveHospitality'"
>
<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-item
:key=
"'/Main/EquipmentTimeErrorVerification'"
>
<div
class=
"flex-vertical-center"
>
<img
:src=
"require('./Icons/7.svg')"
style=
"height: auto;width:20px"
/>
...
...
src/views/SnapshotCluster/ClusterResult/ClusterResult.vue
View file @
3ca4c55
...
...
@@ -66,6 +66,7 @@
<a-select-option
:value=
"1"
>
进
</a-select-option>
<a-select-option
:value=
"-1"
>
出
</a-select-option>
<a-select-option
:value=
"0"
>
横穿
</a-select-option>
<a-select-option
:value=
"2"
>
过店
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
label=
"抓拍类型:"
style=
"padding: 5px 0"
>
...
...
@@ -287,7 +288,7 @@ export default {
plazaList
.
value
=
[]
clusterResultApi
.
getPlazaList
(
{
account_id
:
queryForm
.
account_id
.
toString
()
account_id
:
queryForm
.
account_id
?
queryForm
.
account_id
.
toString
():
''
}
).
then
(
(
r
)
=>
{
...
...
@@ -321,8 +322,8 @@ export default {
zoneList
.
value
=
[]
clusterResultApi
.
getZoneList
(
{
account_id
:
queryForm
.
account_id
.
toString
()
,
plaza_id
:
queryForm
.
plaza_id
.
toString
()
,
account_id
:
queryForm
.
account_id
?
queryForm
.
account_id
.
toString
():
''
,
plaza_id
:
queryForm
.
plaza_id
?
queryForm
.
plaza_id
.
toString
():
''
,
}
).
then
(
(
r
)
=>
{
...
...
@@ -355,9 +356,9 @@ export default {
gateList
.
value
=
[]
clusterResultApi
.
getGateList
(
{
account_id
:
queryForm
.
account_id
.
toString
()
,
plaza_id
:
queryForm
.
plaza_id
.
toString
()
,
zone_id
:
queryForm
.
zone_id
.
toString
()
,
account_id
:
queryForm
.
account_id
?
queryForm
.
account_id
.
toString
():
''
,
plaza_id
:
queryForm
.
plaza_id
?
queryForm
.
plaza_id
.
toString
():
''
,
zone_id
:
queryForm
.
zone_id
?
queryForm
.
zone_id
.
toString
():
''
,
type
:
queryForm
.
type
,
}
).
then
(
...
...
@@ -424,21 +425,21 @@ export default {
const
rawData
=
toRaw
(
queryForm
)
const
data
=
filterEmptyValueInObject
(
{
account_id
:
rawData
.
account_id
.
toString
()
,
account_id
:
rawData
.
account_id
?
rawData
.
account_id
.
toString
():
''
,
type
:
rawData
.
type
,
plaza_id
:
rawData
.
plaza_id
.
toString
()
,
zone_id
:
rawData
.
zone_id
.
toString
()
,
gate_id
:
rawData
.
gate_id
.
toString
()
,
direction
:
rawData
.
direction
.
toString
()
,
plaza_id
:
rawData
.
plaza_id
?
rawData
.
plaza_id
.
toString
():
''
,
zone_id
:
rawData
.
zone_id
?
rawData
.
zone_id
.
toString
():
''
,
gate_id
:
rawData
.
gate_id
?
rawData
.
gate_id
.
toString
():
''
,
direction
:
rawData
.
direction
?
rawData
.
direction
.
toString
():
''
,
picType
:
rawData
.
picType
,
personType
:
rawData
.
personType
.
toString
()
,
personType
:
rawData
.
personType
?
rawData
.
personType
.
toString
():
''
,
startTime
:
formatDate
(
rawData
.
date
)
+
' '
+
rawData
.
startTime
,
endTime
:
formatDate
(
rawData
.
date
)
+
' '
+
rawData
.
endTime
,
minPic
:
rawData
.
minPic
,
maxPic
:
rawData
.
maxPic
,
page
:
pageNum
.
value
-
1
,
pageSize
:
pageSize
.
value
,
childAdult
:
rawData
.
childAdult
.
toString
()
,
childAdult
:
rawData
.
childAdult
?
rawData
.
childAdult
.
toString
():
''
,
}
)
const
storageData
=
filterEmptyValueInObject
(
...
...
src/views/SnapshotCluster/SnapshotCluster.vue
View file @
3ca4c55
...
...
@@ -6,6 +6,9 @@
<a-menu-item
:key=
"'聚类结果'"
>
聚类结果
</a-menu-item>
<a-menu-item
:key=
"'批次'"
>
批次
</a-menu-item>
</a-menu>
<div
v-if=
"currentMenu[0] === '抓拍记录'"
>
<SnapshotRecord></SnapshotRecord>
...
...
@@ -13,17 +16,22 @@
<div
v-if=
"currentMenu[0] === '聚类结果'"
>
<ClusterResult></ClusterResult>
</div>
<div
v-if=
"currentMenu[0] === '批次'"
>
<batchesResult></batchesResult>
</div>
</
template
>
<
script
>
import
{
ref
}
from
'vue'
import
SnapshotRecord
from
'./SnapshotRecord/SnapshotRecord.vue'
import
ClusterResult
from
'./ClusterResult/ClusterResult.vue'
import
batchesResult
from
'./batchesResult/batchesResult.vue'
export
default
{
components
:
{
SnapshotRecord
,
ClusterResult
,
batchesResult
,
},
setup
()
{
// scalar
...
...
src/views/SnapshotCluster/SnapshotRecord/SnapshotRecord.vue
View file @
3ca4c55
...
...
@@ -64,6 +64,7 @@
<a-select-option
:value=
"1"
>
进
</a-select-option>
<a-select-option
:value=
"-1"
>
出
</a-select-option>
<a-select-option
:value=
"0"
>
横穿
</a-select-option>
<a-select-option
:value=
"2"
>
过店
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
label=
"抓拍类型:"
style=
"padding: 5px 0"
>
...
...
@@ -214,7 +215,7 @@ export default {
const
searchCondition
=
ref
({})
if
(
window
.
localStorage
.
getItem
(
'searchCondition'
)){
searchCondition
.
value
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'searchCondition'
));
queryForm
.
type
=
searchCondition
.
value
.
type
;
//
queryForm.type = searchCondition.value.type;
queryForm
.
zone_id
=
searchCondition
.
value
.
zone_id
;
queryForm
.
gate_id
=
searchCondition
.
value
.
gate_id
;
queryForm
.
direction
=
searchCondition
.
value
.
direction
;
...
...
@@ -255,7 +256,7 @@ export default {
plazaList
.
value
=
[]
snapshotRecordApi
.
getPlazaList
(
{
account_id
:
queryForm
.
account_id
.
toString
()
account_id
:
queryForm
.
account_id
?
queryForm
.
account_id
.
toString
():
''
}
).
then
(
(
r
)
=>
{
...
...
@@ -288,8 +289,8 @@ export default {
zoneList
.
value
=
[]
snapshotRecordApi
.
getZoneList
(
{
account_id
:
queryForm
.
account_id
.
toString
()
,
plaza_id
:
queryForm
.
plaza_id
.
toString
()
,
account_id
:
queryForm
.
account_id
?
queryForm
.
account_id
.
toString
():
''
,
plaza_id
:
queryForm
.
plaza_id
?
queryForm
.
plaza_id
.
toString
():
''
,
}
).
then
(
(
r
)
=>
{
...
...
@@ -322,9 +323,9 @@ export default {
gateList
.
value
=
[]
snapshotRecordApi
.
getGateList
(
{
account_id
:
queryForm
.
account_id
.
toString
()
,
plaza_id
:
queryForm
.
plaza_id
.
toString
()
,
zone_id
:
queryForm
.
zone_id
.
toString
()
,
account_id
:
queryForm
.
account_id
?
queryForm
.
account_id
.
toString
():
''
,
plaza_id
:
queryForm
.
plaza_id
?
queryForm
.
plaza_id
.
toString
():
''
,
zone_id
:
queryForm
.
zone_id
?
queryForm
.
zone_id
.
toString
():
''
,
type
:
queryForm
.
type
,
}
).
then
(
...
...
@@ -388,19 +389,19 @@ export default {
const
rawData
=
toRaw
(
queryForm
)
const
data
=
filterEmptyValueInObject
(
{
account_id
:
rawData
.
account_id
.
toString
()
,
account_id
:
rawData
.
account_id
?
rawData
.
account_id
.
toString
():
''
,
type
:
rawData
.
type
,
plaza_id
:
rawData
.
plaza_id
.
toString
()
,
zone_id
:
rawData
.
zone_id
.
toString
()
,
gate_id
:
rawData
.
gate_id
.
toString
()
,
direction
:
rawData
.
direction
.
toString
()
,
plaza_id
:
rawData
.
plaza_id
?
rawData
.
plaza_id
.
toString
():
''
,
zone_id
:
rawData
.
zone_id
?
rawData
.
zone_id
.
toString
():
''
,
gate_id
:
rawData
.
gate_id
?
rawData
.
gate_id
.
toString
():
''
,
direction
:
rawData
.
direction
?
rawData
.
direction
.
toString
():
''
,
picType
:
rawData
.
picType
,
personType
:
rawData
.
personType
.
toString
()
,
personType
:
rawData
.
personType
?
rawData
.
personType
.
toString
():
''
,
startTime
:
formatDate
(
rawData
.
date
)
+
' '
+
rawData
.
startTime
,
endTime
:
formatDate
(
rawData
.
date
)
+
' '
+
rawData
.
endTime
,
page
:
pageNum
.
value
-
1
,
pageSize
:
pageSize
.
value
,
childAdult
:
rawData
.
childAdult
.
toString
()
,
childAdult
:
rawData
.
childAdult
?
rawData
.
childAdult
.
toString
():
''
,
}
)
const
storageData
=
filterEmptyValueInObject
(
...
...
src/views/SnapshotCluster/batchesResult/batchesResult.less
0 → 100644
View file @
3ca4c55
.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/SnapshotCluster/batchesResult/batchesResult.vue
0 → 100644
View file @
3ca4c55
<
template
>
<div
class=
"containter"
>
<a-form
:model=
"queryForm"
layout=
"inline"
:label-col=
"
{ style: { width: '70px' } }">
<a-form-item
label=
"集团:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.account_id"
style=
"width: 240px"
mode=
"multiple"
:maxTagCount=
"1"
@
change=
"onAccountChange"
:options=
"accountList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"广场:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.plaza_id"
style=
"width: 240px"
mode=
"multiple"
:maxTagCount=
"1"
:options=
"plazaList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"选择日期:"
style=
"padding: 5px 0"
>
<a-date-picker
v-model:value=
"queryForm.date"
:format=
"'YYYY-MM-DD'"
style=
"width: 240px"
/>
</a-form-item>
<a-form-item
label=
"选择时间:"
style=
"padding: 5px 0"
>
<a-time-picker
format=
"HH:mm:ss"
valueFormat=
"HH:mm:ss"
v-model:value=
"queryForm.startTime"
style=
"width: 140px"
/>
<span
style=
"padding: 0 4px"
>
至
</span>
<a-time-picker
format=
"HH:mm:ss"
valueFormat=
"HH:mm:ss"
v-model:value=
"queryForm.endTime"
style=
"width: 140px"
/>
</a-form-item>
<a-form-item
label=
"批次人数:"
style=
"padding: 5px 0"
>
<a-input-number
v-model:value=
"queryForm.minNum"
:min=
"0"
:max=
"100000000"
style=
"width: 140px"
/>
<span
style=
"padding: 0 4px"
>
至
</span>
<a-input-number
v-model:value=
"queryForm.maxNum"
:min=
"queryForm.maxNum||0"
:max=
"100000000"
style=
"width: 140px"
/>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-button
type=
"primary"
@
click=
"clickSearch"
:loading=
"isLoading"
>
查询
</a-button>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-button
type=
"primary"
@
click=
"concatBatches"
>
合并
</a-button>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-button
type=
"primary"
@
click=
"deleteBatches"
>
删除
</a-button>
</a-form-item>
</a-form>
<div
v-loading=
"isLoading"
>
<div
class=
"resultContent"
:style=
"
{'height':contentHeight+'px'}">
<template
v-for=
"person in dataList"
>
<div
class=
"classBox"
:class=
"person.expand?'expand':''"
>
<div
:class=
"person.checked?'checked':''"
>
<div
class=
"boxInfo"
>
<span
class=
"iconExpand"
v-show=
"!person.expand"
>
▶
</span>
<span
class=
"iconExpand"
v-show=
"person.expand"
>
▼
</span>
<span
class=
"expandWord"
@
click=
'expandChange(person)'
>
{{
person
.
expand
?
'收起'
:
'展开'
}}
</span>
<el-checkbox
class=
"checkBox"
v-model=
"person.checked"
@
change=
'checkChange(person)'
></el-checkbox>
批次id:
{{
' '
+
person
.
groupUnid
}}
<span
style=
"margin-left: 20px;"
>
图片数量:
{{
person
.
personRecordList
.
length
}}
</span>
</div>
<el-row
v-for=
"row in getPagedList(person.personRecordList, 8)"
>
<el-col
:span=
"3"
v-for=
"item in row"
>
<div
style=
"margin: 0 2px;border: 3px solid transparent;"
@
click=
"handleClick(item)"
:class=
"currentItemId==item.id?'actived':''"
>
<el-image
:src=
"item.faceRecognitionVo.picture_url"
:fit=
"'fill'"
class=
"single-image"
>
</el-image>
<div
style=
"padding-left: 5px;padding-right: 5px;"
>
<div
style=
"width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"
>
unid:
{{
item
.
faceRecognitionVo
.
unid
||
'--'
}}
</div>
<div
style=
"width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"
>
personid:
{{
item
.
faceRecognitionVo
.
person_unid
||
'--'
}}
</div>
<div>
时间:
{{
item
.
faceRecognitionVo
.
counttime
}}
</div>
<div>
类型:
{{
item
.
faceRecognitionVo
.
person_type
==
1
?
'店员'
:(
item
.
faceRecognitionVo
.
person_type
==
0
?
'顾客'
:
'未知'
)
}}
(
{{
item
.
faceRecognitionVo
.
childAdult
==
1
?
'成人'
:(
item
.
faceRecognitionVo
.
childAdult
==
0
?
'儿童'
:
'未知'
)
}}
)
</div>
<div>
性别:
{{
formatGender
(
item
.
faceRecognitionVo
.
gender
)
}}
(
{{
item
.
age
}}
)
</div>
<div>
地点:
{{
item
.
faceRecognitionVo
.
gate_name
}}
</div>
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</
template
>
</div>
<a-pagination
v-model:current=
"pageNum"
v-model:pageSize=
"pageSize"
:total=
"total"
:show-total=
"total => `共 ${total} 条`"
:pageSizeOptions=
"['10', '20', '40', '80']"
@
change=
"onPageNumChange"
@
showSizeChange=
"onPageSizeChange"
show-size-changer
show-quick-jumper
style=
"text-align:center"
/>
</div>
</div>
</template>
<
script
>
import
{
reactive
,
ref
,
toRaw
}
from
'vue'
import
batchesResultApi
from
'@/views/SnapshotCluster/batchesResult/batchesResultApi'
import
{
isArray
}
from
'@/PublicUtil/Judgment'
import
moment
from
'moment'
import
{
filterEmptyValueInObject
,
formatDate
,
getPagedList
}
from
'@/PublicUtil/PublicUtil'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
export
default
{
components
:
{
},
setup
()
{
// scalar
const
pageNum
=
ref
(
1
)
const
pageSize
=
ref
(
10
)
const
total
=
ref
()
const
isLoading
=
ref
(
false
)
const
dataList
=
ref
([])
const
accountList
=
ref
([])
const
plazaList
=
ref
([])
const
currobj
=
ref
({})
const
currentItemId
=
ref
()
const
queryForm
=
reactive
({
account_id
:
[],
plaza_id
:
[],
date
:
moment
(
moment
().
format
(
'YYYY-MM-DD'
),
'YYYY-MM-DD'
),
startTime
:
'00:00:00'
,
endTime
:
'23:59:59'
,
minNum
:
0
,
maxNum
:
100000
,
})
const
searchCondition
=
ref
({})
if
(
window
.
localStorage
.
getItem
(
'searchCondition'
))
{
searchCondition
.
value
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'searchCondition'
));
// queryForm.startTime = searchCondition.value.startTime;
// queryForm.endTime = searchCondition.value.endTime;
queryForm
.
minNum
=
searchCondition
.
value
.
minNum
||
0
;
queryForm
.
maxNum
=
searchCondition
.
value
.
maxNum
||
100000
;
}
const
onPageNumChange
=
function
(
num
)
{
pageNum
.
value
=
num
confirmSearch
()
}
const
onPageSizeChange
=
function
(
current
,
size
)
{
pageNum
.
value
=
1
pageSize
.
value
=
size
confirmSearch
()
}
const
onAccountChange
=
function
()
{
getPlazaList
(
1
)
}
const
getPlazaList
=
function
(
val
)
{
queryForm
.
plaza_id
=
[]
plazaList
.
value
=
[]
batchesResultApi
.
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
.
push
(
plazaList
.
value
[
0
].
value
)
}
confirmSearch
()
}
}
}
)
}
const
getAccountList
=
function
()
{
queryForm
.
account_id
=
[]
accountList
.
value
=
[]
batchesResultApi
.
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
.
push
(
accountList
.
value
[
0
].
value
)
}
getPlazaList
()
}
}
}
)
}
const
clickSearch
=
function
()
{
pageNum
.
value
=
1
confirmSearch
()
}
const
confirmSearch
=
function
()
{
isLoading
.
value
=
true
const
rawData
=
toRaw
(
queryForm
)
const
data
=
filterEmptyValueInObject
({
mallId
:
rawData
.
plaza_id
?
rawData
.
plaza_id
.
toString
():
''
,
countDate
:
formatDate
(
rawData
.
date
),
startTime
:
formatDate
(
rawData
.
date
)
+
' '
+
rawData
.
startTime
,
endTime
:
formatDate
(
rawData
.
date
)
+
' '
+
rawData
.
endTime
,
minNum
:
rawData
.
minNum
,
maxNum
:
rawData
.
maxNum
,
pageNum
:
pageNum
.
value
,
pageSize
:
pageSize
.
value
,
})
const
storageData
=
filterEmptyValueInObject
({
account_id
:
rawData
.
account_id
,
plaza_id
:
rawData
.
plaza_id
,
date
:
rawData
.
date
,
minNum
:
rawData
.
minNum
,
maxNum
:
rawData
.
maxNum
,
startTime
:
rawData
.
startTime
,
endTime
:
rawData
.
endTime
,
})
window
.
localStorage
.
setItem
(
'searchCondition'
,
JSON
.
stringify
(
storageData
))
batchesResultApi
.
getBatchesResultList
(
data
).
then
(
(
r
)
=>
{
isLoading
.
value
=
false
sortDataList
(
r
.
data
.
pageData
)
r
.
data
.
pageData
.
forEach
((
itemPerson
)
=>
{
itemPerson
.
checked
=
false
itemPerson
.
expand
=
false
itemPerson
.
personRecordList
.
forEach
((
item
)
=>
{
if
(
item
.
faceRecognitionVo
&&
item
.
faceRecognitionVo
.
picture_url
)
{
item
.
faceRecognitionVo
.
picture_url
=
window
.
_baseImgUrl
+
item
.
faceRecognitionVo
.
picture_url
}
if
(
item
.
faceRecognitionVo
&&
item
.
faceRecognitionVo
.
features_url
)
{
item
.
faceRecognitionVo
.
features_url
=
window
.
_baseImgUrl
+
item
.
faceRecognitionVo
.
features_url
}
})
})
dataList
.
value
=
r
.
data
.
pageData
console
.
log
(
dataList
.
value
)
total
.
value
=
r
.
data
.
total
document
.
getElementsByClassName
(
'resultContent'
)[
0
].
scrollTop
=
0
}
)
}
const
formatGender
=
function
(
number
)
{
switch
(
number
)
{
case
1
:
{
return
'男'
}
case
-
1
:
{
return
'未知'
}
case
0
:
{
return
'女'
}
default
:
{
break
}
}
}
const
sortDataList
=
function
(
list
)
{
list
.
sort
(
(
a
,
b
)
=>
{
return
(
b
.
personRecordList
.
length
-
a
.
personRecordList
.
length
)
}
)
}
const
checkChange
=
function
(
data
)
{
console
.
log
(
data
)
}
const
expandChange
=
function
(
data
)
{
dataList
.
value
.
forEach
(
item
=>
{
if
(
data
.
groupUnid
==
item
.
groupUnid
)
{
item
.
expand
=
!
item
.
expand
}
})
}
// 批次合并
const
concatBatches
=
function
()
{
const
rawData
=
toRaw
(
queryForm
)
let
selectArr
=
[]
dataList
.
value
.
forEach
(
item
=>
{
if
(
item
.
checked
&&
item
.
checked
==
true
)
{
selectArr
.
push
(
item
)
}
})
if
(
selectArr
.
length
!=
2
)
{
ElMessage
({
message
:
`请选择两个批次分组进行合并`
,
type
:
'warning'
})
return
}
console
.
log
(
selectArr
)
let
parmas
=
{
countDate
:
formatDate
(
rawData
.
date
),
sourceGroupUnid
:
selectArr
[
0
].
groupUnid
,
targetGroupUnid
:
selectArr
[
1
].
groupUnid
,
mallId
:
rawData
.
plaza_id
?
rawData
.
plaza_id
.
toString
():
''
,
}
ElMessageBox
.
confirm
(
'是否合并选中的两个批次分组?'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
}).
then
(()
=>
{
batchesResultApi
.
concatTwoBatches
(
parmas
).
then
(
(
res
)
=>
{
if
(
res
.
code
==
200
)
{
ElMessage
({
message
:
`合并成功`
,
type
:
'success'
})
confirmSearch
()
}
else
{
ElMessage
({
message
:
`删除失败`
,
type
:
'warning'
})
}
}
)
}).
catch
(()
=>
{})
}
//删除批次记录
const
deleteBatches
=
function
(){
if
(
!
currentItemId
.
value
){
ElMessage
(
{
message
:
`请选择图片`
,
type
:
'warning'
}
)
return
}
if
(
!
currobj
.
value
.
picture_url
){
ElMessage
(
{
message
:
`请选择有效的图片`
,
type
:
'warning'
}
)
return
}
ElMessageBox
.
confirm
(
'是否确认删除该批次记录?'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
}).
then
(()
=>
{
batchesResultApi
.
deleteOneBatches
({
id
:
currentItemId
.
value
}).
then
(
(
res
)
=>
{
console
.
log
(
res
)
if
(
res
.
code
==
200
)
{
ElMessage
({
message
:
`删除成功`
,
type
:
'success'
})
confirmSearch
()
currentItemId
.
value
=
''
currobj
.
value
=
{};
}
else
{
ElMessage
({
message
:
`删除失败`
,
type
:
'warning'
})
}
}
)
}).
catch
(()
=>
{})
}
const
handleClick
=
function
(
data
){
currentItemId
.
value
=
data
.
id
currobj
.
value
=
data
;
}
const
contentHeight
=
ref
(
0
)
const
__main
=
function
()
{
getAccountList
()
contentHeight
.
value
=
window
.
innerHeight
-
310
}
__main
()
return
{
isLoading
,
pageNum
,
pageSize
,
total
,
accountList
,
plazaList
,
dataList
,
contentHeight
,
currentItemId
,
currobj
,
handleClick
,
queryForm
,
onPageNumChange
,
onPageSizeChange
,
onAccountChange
,
confirmSearch
,
getPagedList
,
checkChange
,
expandChange
,
formatGender
,
clickSearch
,
concatBatches
,
deleteBatches
,
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
@import
"./batchesResult"
;
.actived
{
border
:
3px
solid
#1890ff
!important
;
}
.checkBox
{
margin-left
:
10px
;
}
.boxInfo
{
line-height
:
28px
;
margin-bottom
:
10px
;
}
.classBox
{
margin
:
10px
0
;
border
:
solid
1px
black
;
height
:
485px
;
overflow-y
:
hidden
;
}
.expand
{
height
:
auto
;
overflow
:
auto
;
}
.expandWord
{
color
:
#1890ff
;
margin-right
:
5px
;
cursor
:
pointer
;
float
:
right
;
}
.iconExpand
{
cursor
:
pointer
;
float
:
right
;
color
:
#1890ff
;
margin-right
:
20px
;
}
.checked
{
background-color
:
#bbb
;
}
.resultContent
{
overflow
:
auto
;
min-height
:
500px
;
}
.downBtn
{
color
:
#409EFF
;
font-size
:
15px
;
cursor
:
pointer
;
display
:
inline-block
;
width
:
auto
;
}
.downBtn1
{
float
:
right
;
}
</
style
>
\ No newline at end of file
src/views/SnapshotCluster/batchesResult/batchesResultApi.js
0 → 100644
View file @
3ca4c55
import
axiosInstance
from
"@/Request/PublicAxiosInstance"
import
{
filterEmptyValueInObject
}
from
"@/PublicUtil/PublicUtil"
class
ClusterResultApi
{
getBatchesResultList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/car4s/group/page`
,
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
},
)
}
)
}
// 合并批次分组
concatTwoBatches
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'PUT'
,
url
:
`/car4s/group/merge`
,
data
:
filterEmptyValueInObject
(
data
)
}
)
}
// 删除批次记录
deleteOneBatches
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'PUT'
,
url
:
`/car4s/group/remove`
,
data
:
filterEmptyValueInObject
(
data
)
}
)
}
}
const
clusterResultApi
=
new
ClusterResultApi
()
export
default
clusterResultApi
src/views/TestDriveHospitality/ClusterResult/ClusterResult.less
0 → 100644
View file @
3ca4c55
.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/TestDriveHospitality/ClusterResult/ClusterResult.vue
0 → 100644
View file @
3ca4c55
<
template
>
<div
class=
"containter"
>
<a-form
:model=
"queryForm"
layout=
"inline"
:label-col=
"
{ style: { width: '70px' } }">
<a-form-item
label=
"集团:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.account_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
@
change=
"onAccountChange"
:options=
"accountList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"广场:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.plaza_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
@
change=
"onPlazaChange"
:options=
"plazaList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"区域信息:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.zone_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
@
change=
"onZoneChange"
:options=
"zoneList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"监控点:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.gate_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
:options=
"gateList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"选择日期:"
style=
"padding: 5px 0"
>
<a-date-picker
v-model:value=
"queryForm.date"
:format=
"'YYYY-MM-DD'"
style=
"width: 280px"
/>
</a-form-item>
<a-form-item
label=
"选择时间:"
style=
"padding: 5px 0"
>
<a-time-picker
v-model:value=
"queryForm.startTime"
style=
"width: 140px"
/>
<span
style=
"padding: 0 4px"
>
至
</span>
<a-time-picker
v-model:value=
"queryForm.endTime"
style=
"width: 140px"
/>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-button
type=
"primary"
@
click=
"clickSearch"
:loading=
"isLoading"
>
查询
</a-button>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-upload
:file-list=
"fileList"
:before-upload=
"beforeUpload"
>
<a-button
type=
"primary"
>
<upload-outlined></upload-outlined>
导入
</a-button>
</a-upload>
</a-form-item>
<!--
<a-form-item
style=
"padding: 5px 0"
>
<a-button
type=
"primary"
@
click=
"deleteBatches"
>
删除
</a-button>
</a-form-item>
-->
</a-form>
<div
v-loading=
"isLoading"
>
<div
class=
"resultContent"
:style=
"
{'height':contentHeight+'px'}">
<template
v-for=
"person in dataList"
>
<div
class=
"classBox"
>
<div>
<div
class=
"boxInfo"
>
<span>
记录id:
{{
person
.
personUnid
}}
</span>
<span
style=
"margin-left: 20px;"
>
开始接待时间:
{{
person
.
startTime
}}
</span>
<span
style=
"margin-left: 20px;"
>
结束接待时间:
{{
person
.
endTime
}}
</span>
<span
style=
"margin-left: 20px;"
>
接待时长:
{{
person
.
duration
}}
</span>
</div>
<el-row
v-for=
"row in getPagedList(person.customerList, 8)"
>
<el-col
:span=
"3"
v-for=
"item in row"
>
<div
style=
"margin: 0 5px"
@
click=
"handleClick(item)"
:class=
"currentItemId==item.id?'actived':''"
>
<el-image
:src=
"item.picture_url"
:fit=
"'fill'"
class=
"single-image"
></el-image>
<div>
unid:
{{
item
.
unid
}}
</div>
<div>
时间:
{{
item
.
counttime
}}
</div>
<div>
性别:
{{
formatGender
(
item
.
gender
)
}}
(
{{
item
.
age
}}
)
</div>
<div>
地点:
{{
item
.
gate_name
}}
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</
template
>
</div>
<a-pagination
v-model:current=
"pageNum"
v-model:pageSize=
"pageSize"
:total=
"total"
:show-total=
"total => `共 ${total} 条`"
:pageSizeOptions=
"['10', '20', '40', '80']"
@
change=
"onPageNumChange"
@
showSizeChange=
"onPageSizeChange"
show-size-changer
show-quick-jumper
style=
"text-align:center"
/>
</div>
</div>
</template>
<
script
>
import
{
reactive
,
ref
,
toRaw
}
from
'vue'
import
clusterResultApi
from
'@/views/TestDriveHospitality/ClusterResult/ClusterResultApi'
import
{
isArray
}
from
'@/PublicUtil/Judgment'
import
moment
from
'moment'
import
{
filterEmptyValueInObject
,
formatDate
,
formatTime
,
getPagedList
}
from
'@/PublicUtil/PublicUtil'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
export
default
{
components
:
{
},
setup
()
{
const
pageNum
=
ref
(
1
)
const
pageSize
=
ref
(
10
)
const
total
=
ref
()
const
isLoading
=
ref
(
false
)
const
currobj
=
ref
({})
const
currentItemId
=
ref
()
const
dataList
=
ref
([])
const
accountList
=
ref
([])
const
plazaList
=
ref
([])
const
zoneList
=
ref
([])
const
gateList
=
ref
([])
const
queryForm
=
reactive
({
account_id
:
[],
plaza_id
:
[],
zone_id
:
[],
gate_id
:
[],
date
:
moment
(
moment
().
format
(
'YYYY-MM-DD'
),
'YYYY-MM-DD'
),
startTime
:
moment
(
'00:00:00'
,
'HH:mm:ss'
),
endTime
:
moment
(
'23:59:59'
,
'HH:mm:ss'
),
})
const
searchCondition
=
ref
({})
if
(
window
.
localStorage
.
getItem
(
'searchCondition'
))
{
searchCondition
.
value
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'searchCondition'
));
queryForm
.
date
=
searchCondition
.
value
.
date
;
// queryForm.startTime = searchCondition.value.startTime;
// queryForm.endTime = searchCondition.value.endTime;
}
const
onPageNumChange
=
function
(
num
)
{
pageNum
.
value
=
num
confirmSearch
()
}
const
onPageSizeChange
=
function
(
current
,
size
)
{
pageNum
.
value
=
1
pageSize
.
value
=
size
confirmSearch
()
}
const
onAccountChange
=
function
()
{
getPlazaList
(
1
)
}
const
onPlazaChange
=
function
()
{
getZoneList
()
getGateList
()
}
const
onZoneChange
=
function
()
{
getGateList
()
}
const
getPlazaList
=
function
(
val
)
{
queryForm
.
plaza_id
=
[]
plazaList
.
value
=
[]
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
.
push
(
plazaList
.
value
[
0
].
value
)
}
getZoneList
(
1
)
getGateList
(
1
)
confirmSearch
()
}
}
}
)
}
const
getZoneList
=
function
(
val
)
{
zoneList
.
value
=
[]
clusterResultApi
.
getZoneList
({
account_id
:
queryForm
.
account_id
.
toString
(),
plaza_id
:
queryForm
.
plaza_id
.
toString
(),
}).
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
=
[]
}
}
else
{
queryForm
.
zone_id
=
[]
}
}
}
)
}
const
getGateList
=
function
(
val
)
{
gateList
.
value
=
[]
clusterResultApi
.
getGateList
({
account_id
:
queryForm
.
account_id
.
toString
(),
plaza_id
:
queryForm
.
plaza_id
.
toString
(),
zone_id
:
queryForm
.
zone_id
.
toString
(),
type
:
0
,
}).
then
(
(
r
)
=>
{
if
(
isArray
(
r
.
data
))
{
for
(
const
item
of
r
.
data
)
{
gateList
.
value
.
push
({
value
:
item
.
id
,
label
:
item
.
name
,
})
}
if
(
gateList
.
value
.
length
)
{
if
(
val
&&
searchCondition
.
value
.
gate_id
&&
searchCondition
.
value
.
gate_id
.
length
>
0
)
{
queryForm
.
gate_id
=
searchCondition
.
value
.
gate_id
}
else
{
queryForm
.
gate_id
=
[]
}
}
else
{
queryForm
.
gate_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
.
push
(
accountList
.
value
[
0
].
value
)
}
getPlazaList
()
}
}
}
)
}
const
clickSearch
=
function
()
{
pageNum
.
value
=
1
confirmSearch
()
}
const
confirmSearch
=
function
()
{
isLoading
.
value
=
true
const
rawData
=
toRaw
(
queryForm
)
const
data
=
filterEmptyValueInObject
({
// account_id: rawData.account_id?rawData.account_id.toString():'',
mallId
:
rawData
.
plaza_id
?
rawData
.
plaza_id
.
toString
():
''
,
zoneIds
:
rawData
.
zone_id
?
rawData
.
zone_id
.
toString
():
''
,
gateIds
:
rawData
.
gate_id
?
rawData
.
gate_id
.
toString
():
''
,
countDate
:
formatDate
(
rawData
.
date
),
startTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
startTime
),
endTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
endTime
),
pageNum
:
pageNum
.
value
,
pageSize
:
pageSize
.
value
,
})
const
storageData
=
filterEmptyValueInObject
({
account_id
:
rawData
.
account_id
,
plaza_id
:
rawData
.
plaza_id
,
zone_id
:
rawData
.
zone_id
,
gate_id
:
rawData
.
gate_id
,
date
:
rawData
.
date
,
startTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
startTime
),
endTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
endTime
),
})
window
.
localStorage
.
setItem
(
'searchCondition'
,
JSON
.
stringify
(
storageData
))
clusterResultApi
.
getClusterResultList
(
data
).
then
(
(
r
)
=>
{
isLoading
.
value
=
false
sortDataList
(
r
.
data
.
pageData
)
r
.
data
.
pageData
.
forEach
((
itemPerson
)
=>
{
itemPerson
.
customerList
.
forEach
((
item
)
=>
{
if
(
item
.
features_url
)
{
item
.
features_url
=
window
.
_baseImgUrl
+
item
.
features_url
}
if
(
item
.
picture_url
)
{
item
.
picture_url
=
window
.
_baseImgUrl
+
item
.
picture_url
}
})
itemPerson
.
staffList
.
forEach
((
item1
)
=>
{
if
(
item1
.
features_url
)
{
item1
.
features_url
=
window
.
_baseImgUrl
+
item1
.
features_url
}
if
(
item1
.
picture_url
)
{
item1
.
picture_url
=
window
.
_baseImgUrl
+
item1
.
picture_url
}
})
})
dataList
.
value
=
r
.
data
.
pageData
total
.
value
=
r
.
data
.
total
document
.
getElementsByClassName
(
'resultContent'
)[
0
].
scrollTop
=
0
}
)
}
const
formatGender
=
function
(
number
)
{
switch
(
number
)
{
case
1
:
{
return
'男'
}
case
-
1
:
{
return
'未知'
}
case
0
:
{
return
'女'
}
default
:
{
break
}
}
}
const
sortDataList
=
function
(
list
)
{
list
.
sort
(
(
a
,
b
)
=>
{
return
(
b
.
customerList
.
length
-
a
.
customerList
.
length
)
}
)
}
const
handleClick
=
function
(
data
)
{
currentItemId
.
value
=
data
.
id
currobj
.
value
=
data
;
}
// 导入接待记录
const
importHospitality
=
function
(
data
)
{
}
// 删除试乘记录
const
deleteBatches
=
function
()
{
if
(
!
currentItemId
.
value
)
{
ElMessage
({
message
:
`请选择图片`
,
type
:
'warning'
})
return
}
if
(
!
currobj
.
value
.
picture_url
)
{
ElMessage
({
message
:
`请选择有效的图片`
,
type
:
'warning'
})
return
}
ElMessageBox
.
confirm
(
'是否确认删除该接待记录?'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
}).
then
(()
=>
{
clusterResultApi
.
deleteOneDrive
({
id
:
currentItemId
.
value
}).
then
(
(
res
)
=>
{
console
.
log
(
res
)
if
(
res
.
code
==
200
)
{
ElMessage
({
message
:
`删除成功`
,
type
:
'success'
})
confirmSearch
()
currentItemId
.
value
=
''
currobj
.
value
=
{};
}
else
{
ElMessage
({
message
:
`删除失败`
,
type
:
'warning'
})
}
}
)
}).
catch
(()
=>
{})
}
const
contentHeight
=
ref
(
0
)
const
__main
=
function
()
{
getAccountList
()
contentHeight
.
value
=
window
.
innerHeight
-
310
}
const
fileList
=
([]);
const
beforeUpload
=
function
(
file
)
{
const
formData
=
new
FormData
();
formData
.
append
(
'file'
,
file
);
clusterResultApi
.
uploadReception
(
formData
).
then
((
res
)
=>
{
if
(
res
.
code
==
200
)
{
ElMessage
({
message
:
`上传成功`
,
type
:
'success'
})
clickSearch
()
}
else
{
ElMessage
({
message
:
`上传失败`
,
type
:
'warning'
})
}
})
return
false
;
};
__main
()
return
{
beforeUpload
,
fileList
,
isLoading
,
pageNum
,
pageSize
,
total
,
currentItemId
,
currobj
,
accountList
,
plazaList
,
zoneList
,
gateList
,
dataList
,
contentHeight
,
queryForm
,
onPageNumChange
,
onPageSizeChange
,
onAccountChange
,
onPlazaChange
,
onZoneChange
,
confirmSearch
,
getPagedList
,
handleClick
,
importHospitality
,
formatGender
,
clickSearch
,
deleteBatches
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
@import
"./ClusterResult"
;
.actived
{
border
:
3px
solid
#1890ff
;
}
.checkBox
{
margin-left
:
10px
;
}
.boxInfo
{
line-height
:
28px
;
margin-bottom
:
10px
;
}
.classBox
{
margin
:
10px
0
;
border
:
solid
1px
black
;
height
:
485px
;
overflow-y
:
hidden
;
}
.expand
{
height
:
auto
;
overflow
:
auto
;
}
.expandWord
{
color
:
#1890ff
;
margin-right
:
5px
;
cursor
:
pointer
;
float
:
right
;
}
.iconExpand
{
cursor
:
pointer
;
float
:
right
;
color
:
#1890ff
;
margin-right
:
20px
;
}
.checked
{
background-color
:
#bbb
;
}
.resultContent
{
overflow
:
auto
;
min-height
:
500px
;
}
.downBtn
{
color
:
#409EFF
;
font-size
:
15px
;
cursor
:
pointer
;
display
:
inline-block
;
width
:
auto
;
}
.downBtn1
{
float
:
right
;
}
</
style
>
\ No newline at end of file
src/views/TestDriveHospitality/ClusterResult/ClusterResultApi.js
0 → 100644
View file @
3ca4c55
import
axiosInstance
from
"@/Request/PublicAxiosInstance"
import
{
filterEmptyValueInObject
}
from
"@/PublicUtil/PublicUtil"
class
ClusterResultApi
{
getClusterResultList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/car4s/reception/page`
,
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
)
}
)
}
// 上传接待记录
uploadReception
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'POST'
,
url
:
`/car4s/reception/upload`
,
headers
:
{
'Content-Type'
:
'multipart/form-data'
},
data
:
data
}
)
}
}
const
clusterResultApi
=
new
ClusterResultApi
()
export
default
clusterResultApi
src/views/TestDriveHospitality/SnapshotCluster.vue
0 → 100644
View file @
3ca4c55
<
template
>
<a-menu
v-model:selectedKeys=
"currentMenu"
mode=
"horizontal"
>
<a-menu-item
:key=
"'试乘记录'"
>
试乘记录
</a-menu-item>
<a-menu-item
:key=
"'接待记录'"
>
接待记录
</a-menu-item>
</a-menu>
<div
v-if=
"currentMenu[0] === '试乘记录'"
>
<SnapshotRecord></SnapshotRecord>
</div>
<div
v-if=
"currentMenu[0] === '接待记录'"
>
<ClusterResult></ClusterResult>
</div>
</
template
>
<
script
>
import
{
ref
}
from
'vue'
import
SnapshotRecord
from
'./SnapshotRecord/SnapshotRecord.vue'
import
ClusterResult
from
'./ClusterResult/ClusterResult.vue'
export
default
{
components
:
{
SnapshotRecord
,
ClusterResult
,
},
setup
()
{
// scalar
const
currentMenu
=
ref
([
'试乘记录'
])
// sequence
// mapping
// function
return
{
// scalar
currentMenu
,
// sequence
// mapping
// function
}
}
}
</
script
>
<
style
scoped
>
</
style
>
src/views/TestDriveHospitality/SnapshotRecord/SnapshotRecord.less
0 → 100644
View file @
3ca4c55
.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/TestDriveHospitality/SnapshotRecord/SnapshotRecord.vue
0 → 100644
View file @
3ca4c55
<
template
>
<a-form
:model=
"queryForm"
layout=
"inline"
:label-col=
"
{ style: { width: '70px' } }">
<a-form-item
label=
"集团:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.account_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
@
change=
"onAccountChange"
:options=
"accountList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"广场:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.plaza_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
@
change=
"onPlazaChange"
:options=
"plazaList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"区域信息:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.zone_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
@
change=
"onZoneChange"
:options=
"zoneList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"监控点:"
style=
"padding: 5px 0"
>
<a-select
v-model:value=
"queryForm.gate_id"
style=
"width: 280px"
mode=
"multiple"
:maxTagCount=
"1"
:options=
"gateList"
optionFilterProp=
"label"
show-search
>
</a-select>
</a-form-item>
<a-form-item
label=
"选择日期:"
style=
"padding: 5px 0"
>
<a-date-picker
v-model:value=
"queryForm.date"
:format=
"'YYYY-MM-DD'"
style=
"width: 280px"
/>
</a-form-item>
<a-form-item
label=
"选择时间:"
style=
"padding: 5px 0"
>
<a-time-picker
v-model:value=
"queryForm.startTime"
style=
"width: 140px"
/>
<span
style=
"padding: 0 4px"
>
至
</span>
<a-time-picker
v-model:value=
"queryForm.endTime"
style=
"width: 140px"
/>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-button
type=
"primary"
@
click=
"clickSearch"
:loading=
"isLoading"
>
查询
</a-button>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-upload
:file-list=
"fileList"
:before-upload=
"beforeUpload"
>
<a-button
type=
"primary"
>
<upload-outlined></upload-outlined>
导入
</a-button>
</a-upload>
</a-form-item>
<a-form-item
style=
"padding: 5px 0"
>
<a-button
type=
"primary"
@
click=
"deleteBatches"
>
删除
</a-button>
</a-form-item>
</a-form>
<div
v-loading=
"isLoading"
>
<div
class=
"resultContent"
:style=
"
{'height':contentHeight+'px'}">
<el-row
v-for=
"row in pagedTableDataList"
>
<el-col
:span=
"3"
v-for=
"item in row"
>
<div
style=
"margin: 0 5px;cursor: pointer;"
@
click=
"handleClick(item)"
:class=
"currentItemId==item.id?'actived':''"
>
<el-image
:src=
"item.picture_url"
:fit=
"'fill'"
class=
"single-image"
>
</el-image>
<div>
unid:
{{
item
.
unid
}}
</div>
<div>
时间:
{{
item
.
counttime
}}
</div>
<div>
性别:
{{
formatGender
(
item
.
gender
)
}}
(
{{
item
.
age
}}
)
</div>
<div>
地点:
{{
item
.
gate_name
}}
</div>
</div>
</el-col>
</el-row>
</div>
<a-pagination
v-model:current=
"pageNum"
v-model:pageSize=
"pageSize"
:total=
"total"
:show-total=
"total => `共 $
{total} 条`" :pageSizeOptions="['24', '48', '96', '192']" @change="onPageNumChange"
@showSizeChange="onPageSizeChange" show-size-changer show-quick-jumper style="text-align:center" />
</div>
<DetailDialog
ref=
"DetailDialogRef"
/>
</
template
>
<
script
>
import
{
computed
,
reactive
,
ref
,
toRaw
}
from
'vue'
import
snapshotRecordApi
from
'@/views/TestDriveHospitality/SnapshotRecord/SnapshotRecordApi'
import
{
isArray
}
from
'@/PublicUtil/Judgment'
import
moment
from
'moment'
import
{
filterEmptyValueInObject
,
formatDate
,
formatTime
,
getPagedList
}
from
'@/PublicUtil/PublicUtil'
// import imgDialog from '../imgDialog.vue'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
Cookies
from
"js-cookie"
import
DetailDialog
from
"../../ComparisonCapturedPictures/DetailDialog.vue"
;
export
default
{
components
:
{
// imgDialog ,
DetailDialog
},
setup
()
{
// scalar
const
pageNum
=
ref
(
1
)
const
pageSize
=
ref
(
24
)
const
total
=
ref
()
const
isLoading
=
ref
(
false
)
// sequence
const
dataList
=
ref
([])
const
accountList
=
ref
([])
const
plazaList
=
ref
([])
const
zoneList
=
ref
([])
const
gateList
=
ref
([])
const
currentItemId
=
ref
()
const
currobj
=
ref
({})
const
DetailDialogRef
=
ref
();
const
pagedTableDataList
=
computed
(
()
=>
{
return
getPagedList
(
dataList
.
value
,
8
)
}
)
const
queryForm
=
reactive
({
account_id
:
[],
plaza_id
:
[],
zone_id
:
[],
gate_id
:
[],
date
:
moment
(
moment
().
format
(
'YYYY-MM-DD'
),
'YYYY-MM-DD'
),
startTime
:
moment
(
'00:00:00'
,
'HH:mm:ss'
),
endTime
:
moment
(
'23:59:59'
,
'HH:mm:ss'
),
})
const
searchCondition
=
ref
({})
if
(
window
.
localStorage
.
getItem
(
'searchCondition'
))
{
searchCondition
.
value
=
JSON
.
parse
(
window
.
localStorage
.
getItem
(
'searchCondition'
));
queryForm
.
date
=
searchCondition
.
value
.
date
;
// queryForm.startTime = searchCondition.value.startTime;
// queryForm.endTime = searchCondition.value.endTime;
}
const
onPageNumChange
=
function
(
num
)
{
pageNum
.
value
=
num
confirmSearch
()
}
const
onPageSizeChange
=
function
(
current
,
size
)
{
pageNum
.
value
=
1
pageSize
.
value
=
size
confirmSearch
()
}
const
onAccountChange
=
function
()
{
getPlazaList
(
1
)
}
const
onPlazaChange
=
function
()
{
getZoneList
()
getGateList
()
}
const
onZoneChange
=
function
()
{
getGateList
()
}
const
getPlazaList
=
function
(
val
)
{
queryForm
.
plaza_id
=
[]
plazaList
.
value
=
[]
snapshotRecordApi
.
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
)
{
if
(
!
val
&&
searchCondition
.
value
.
plaza_id
&&
searchCondition
.
value
.
plaza_id
.
length
>
0
)
{
queryForm
.
plaza_id
=
searchCondition
.
value
.
plaza_id
}
else
{
queryForm
.
plaza_id
.
push
(
plazaList
.
value
[
0
].
value
)
}
getZoneList
(
1
)
getGateList
(
1
)
confirmSearch
()
}
}
}
)
}
const
getZoneList
=
function
(
val
)
{
queryForm
.
zone_id
=
[]
zoneList
.
value
=
[]
snapshotRecordApi
.
getZoneList
({
account_id
:
queryForm
.
account_id
.
toString
(),
plaza_id
:
queryForm
.
plaza_id
.
toString
(),
}).
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
=
[]
}
}
else
{
queryForm
.
zone_id
=
[]
}
}
}
)
}
const
getGateList
=
function
(
val
)
{
gateList
.
value
=
[]
snapshotRecordApi
.
getGateList
({
account_id
:
queryForm
.
account_id
.
toString
(),
plaza_id
:
queryForm
.
plaza_id
.
toString
(),
zone_id
:
queryForm
.
zone_id
.
toString
(),
type
:
0
,
}).
then
(
(
r
)
=>
{
if
(
isArray
(
r
.
data
))
{
for
(
const
item
of
r
.
data
)
{
gateList
.
value
.
push
({
value
:
item
.
id
,
label
:
item
.
name
,
})
}
if
(
gateList
.
value
.
length
)
{
if
(
val
&&
searchCondition
.
value
.
gate_id
&&
searchCondition
.
value
.
gate_id
.
length
>
0
)
{
queryForm
.
gate_id
=
searchCondition
.
value
.
gate_id
}
else
{
queryForm
.
gate_id
=
[]
}
}
else
{
queryForm
.
gate_id
=
[]
}
}
}
)
}
const
getAccountList
=
function
()
{
queryForm
.
account_id
=
[]
accountList
.
value
=
[]
snapshotRecordApi
.
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
.
push
(
accountList
.
value
[
0
].
value
)
}
getPlazaList
()
}
}
}
)
}
const
confirmSearch
=
function
()
{
isLoading
.
value
=
true
const
rawData
=
toRaw
(
queryForm
)
console
.
log
(
rawData
)
const
data
=
filterEmptyValueInObject
({
mallId
:
rawData
.
plaza_id
?
rawData
.
plaza_id
.
toString
():
''
,
zoneIds
:
rawData
.
zone_id
?
rawData
.
zone_id
.
toString
():
''
,
gateIds
:
rawData
.
gate_id
?
rawData
.
gate_id
.
toString
():
''
,
startTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
startTime
),
endTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
endTime
),
pageNum
:
pageNum
.
value
-
1
,
pageSize
:
pageSize
.
value
,
})
const
storageData
=
filterEmptyValueInObject
({
account_id
:
rawData
.
account_id
,
plaza_id
:
rawData
.
plaza_id
,
zone_id
:
rawData
.
zone_id
,
gate_id
:
rawData
.
gate_id
,
date
:
rawData
.
date
,
startTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
startTime
),
endTime
:
formatDate
(
rawData
.
date
)
+
' '
+
formatTime
(
rawData
.
endTime
),
})
window
.
localStorage
.
setItem
(
'searchCondition'
,
JSON
.
stringify
(
storageData
))
snapshotRecordApi
.
getSnapshotRecordList
(
data
).
then
(
(
r
)
=>
{
isLoading
.
value
=
false
r
.
data
.
pageData
.
forEach
((
item
)
=>
{
if
(
item
.
features_url
)
{
item
.
features_url
=
window
.
_baseImgUrl
+
item
.
features_url
}
if
(
item
.
picture_url
)
{
item
.
picture_url
=
window
.
_baseImgUrl
+
item
.
picture_url
}
if
(
item
.
track_url
)
{
item
.
track_url
=
window
.
_baseImgUrl
+
item
.
track_url
}
})
dataList
.
value
=
r
.
data
.
pageData
total
.
value
=
r
.
data
.
total
document
.
getElementsByClassName
(
'resultContent'
)[
0
].
scrollTop
=
0
}
)
}
const
formatGender
=
function
(
number
)
{
switch
(
number
)
{
case
1
:
{
return
'男'
}
case
-
1
:
{
return
'未知'
}
case
0
:
{
return
'女'
}
default
:
{
break
}
}
}
const
handleClick
=
function
(
data
)
{
currentItemId
.
value
=
data
.
id
currobj
.
value
=
data
;
}
const
comparativeFun
=
function
()
{
if
(
currobj
.
value
==
{})
{
ElMessage
({
message
:
`请选择图片进行对比验证`
,
type
:
'warning'
});
return
false
}
if
(
!
currobj
.
value
.
picture_url
)
{
ElMessage
({
message
:
`该图片没有特征,请选择有效的图片`
,
type
:
'warning'
})
return
}
const
rawData
=
toRaw
(
queryForm
)
let
parmas
=
{
plaza_id
:
currobj
.
value
.
mall_id
,
pic_type
:
rawData
.
picType
,
pic_id
:
currobj
.
value
.
id
,
ip
:
window
.
_baseImgUrl
,
countdate
:
formatDate
(
rawData
.
date
)
}
DetailDialogRef
.
value
.
initDialog
(
currobj
.
value
,
parmas
);
}
const
clickSearch
=
function
()
{
pageNum
.
value
=
1
confirmSearch
()
}
// 删除试乘记录
const
deleteBatches
=
function
()
{
if
(
!
currentItemId
.
value
)
{
ElMessage
({
message
:
`请选择图片`
,
type
:
'warning'
})
return
}
if
(
!
currobj
.
value
.
picture_url
)
{
ElMessage
({
message
:
`请选择有效的图片`
,
type
:
'warning'
})
return
}
ElMessageBox
.
confirm
(
'是否确认删除该试乘记录?'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
}).
then
(()
=>
{
snapshotRecordApi
.
deleteOneDrive
({
id
:
currentItemId
.
value
}).
then
(
(
res
)
=>
{
console
.
log
(
res
)
if
(
res
.
code
==
200
)
{
ElMessage
({
message
:
`删除成功`
,
type
:
'success'
})
confirmSearch
()
currentItemId
.
value
=
''
currobj
.
value
=
{};
}
else
{
ElMessage
({
message
:
`删除失败`
,
type
:
'warning'
})
}
}
)
}).
catch
(()
=>
{})
}
const
contentHeight
=
ref
(
0
)
const
__main
=
function
()
{
getAccountList
()
contentHeight
.
value
=
window
.
innerHeight
-
310
}
const
fileList
=
([]);
const
beforeUpload
=
function
(
file
)
{
const
formData
=
new
FormData
();
formData
.
append
(
'file'
,
file
);
snapshotRecordApi
.
uploadDrive
(
formData
).
then
((
res
)
=>
{
if
(
res
.
code
==
200
)
{
ElMessage
({
message
:
`上传成功`
,
type
:
'success'
})
clickSearch
()
}
else
{
ElMessage
({
message
:
`上传失败`
,
type
:
'warning'
})
}
})
return
false
;
};
__main
()
return
{
beforeUpload
,
fileList
,
isLoading
,
pageNum
,
pageSize
,
total
,
currobj
,
accountList
,
plazaList
,
zoneList
,
gateList
,
pagedTableDataList
,
currentItemId
,
contentHeight
,
queryForm
,
onPageNumChange
,
onPageSizeChange
,
onAccountChange
,
onPlazaChange
,
onZoneChange
,
confirmSearch
,
handleClick
,
comparativeFun
,
formatGender
,
clickSearch
,
deleteBatches
,
DetailDialogRef
,
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
@import
"./SnapshotRecord"
;
.actived
{
border
:
3px
solid
#1890ff
;
}
.resultContent
{
overflow
:
auto
;
min-height
:
500px
;
}
.downBtn
{
color
:
#409EFF
;
font-size
:
15px
;
cursor
:
pointer
;
display
:
inline-block
;
width
:
auto
;
}
.downBtn1
{
float
:
right
;
}
</
style
>
\ No newline at end of file
src/views/TestDriveHospitality/SnapshotRecord/SnapshotRecordApi.js
0 → 100644
View file @
3ca4c55
import
axiosInstance
from
"@/Request/PublicAxiosInstance"
import
{
filterEmptyValueInObject
}
from
"@/PublicUtil/PublicUtil"
class
SnapshotRecordApi
{
getSnapshotRecordList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/car4s/engage/page`
,
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
},
)
}
)
}
getResidenceList
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'GET'
,
url
:
`/residence`
,
params
:
data
}
)
}
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
,
},
)
}
)
}
// 删除试乘记录
deleteOneDrive
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'DELETE'
,
url
:
`/car4s/engage/
${
data
.
id
}
`
,
}
)
}
// 上传试乘记录
uploadDrive
(
data
)
{
return
axiosInstance
.
request
(
{
method
:
'POST'
,
url
:
`/car4s/engage/upload`
,
headers
:
{
'Content-Type'
:
'multipart/form-data'
},
data
:
data
}
)
}
}
const
snapshotRecordApi
=
new
SnapshotRecordApi
()
export
default
snapshotRecordApi
src/views/TestDriveHospitality/imgDialog.vue
0 → 100644
View file @
3ca4c55
<
template
>
<a-modal
title=
"图片"
v-if=
'isVisible'
v-model:visible=
"isVisible"
width=
"1200px"
height=
'90%'
class=
"detail-modal"
>
<canvas
id=
"myCanvas"
></canvas>
<img
:src=
"imgUrl"
alt=
""
id=
"img"
>
<template
#
footer
>
<a-button
@
click=
"onCancel"
>
返回
</a-button>
</
template
>
</a-modal>
</template>
<
script
>
import
{
reactive
,
ref
}
from
"vue"
;
export
default
{
setup
()
{
const
isVisible
=
ref
(
false
);
const
isLoading
=
ref
(
false
);
const
detailData
=
ref
({});
const
imgUrl
=
ref
()
const
canvas
=
ref
()
const
ctx
=
ref
()
const
initDialog
=
(
url
,
data
)
=>
{
imgUrl
.
value
=
url
isVisible
.
value
=
true
;
setTimeout
(()
=>
{
var
imgscream
=
document
.
getElementById
(
"img"
);
let
height
=
imgscream
.
offsetHeight
;
let
width
=
imgscream
.
offsetWidth
;
canvas
.
value
=
document
.
getElementById
(
"myCanvas"
);
//初始化
canvas
.
value
.
height
=
height
;
canvas
.
value
.
width
=
width
;
ctx
.
value
=
canvas
.
value
.
getContext
(
"2d"
)
ctx
.
value
.
drawImage
(
imgscream
,
0
,
0
,
width
,
height
);
ctx
.
value
.
beginPath
();
ctx
.
value
.
lineWidth
=
3
ctx
.
value
.
strokeStyle
=
"red"
;
ctx
.
value
.
moveTo
(
data
.
head_x_inSmall
,
data
.
head_y_inSmall
);
//起始位置
ctx
.
value
.
lineTo
(
data
.
foot_x_inSmall
,
data
.
foot_y_inSmall
);
//停止位置
ctx
.
value
.
stroke
();
},
0
)
};
const
onCancel
=
()
=>
{
canvas
.
value
=
''
isVisible
.
value
=
false
;
};
return
{
isVisible
,
onCancel
,
initDialog
,
isLoading
,
imgUrl
,
detailData
};
},
};
</
script
>
<
style
lang=
"less"
scoped
>
#myCanvas
{
display
:
block
;
margin
:
0
auto
;
}
#img
{
position
:
relative
;
top
:
-5000px
;
float
:
left
;
}
</
style
>
src/views/TestDriveHospitality/singleImgComparisonDialog.vue
0 → 100644
View file @
3ca4c55
<
template
>
<a-modal
title=
"单张图片特征对比"
v-if=
'isVisible'
v-model:visible=
"isVisible"
width=
"1600px"
height=
'90%'
class=
"detail-modal"
>
<el-row
:gutter=
"20"
>
<el-col
:span=
"8"
class=
'imgBox1'
v-loading=
'isLoading'
>
<p
class=
"title"
>
<span
class=
"name"
>
现在聚类
</span>
<span
class=
"id"
>
{{
detailData
.
person_unid
}}
</span>
<span
class=
"num"
>
{{
featureList
.
length
}}
张
</span>
</p>
<el-row
:gutter=
"10"
class=
"imgBox1_top"
>
<el-col
:span=
"8"
class=
"itemBox"
v-for=
"item in featureList"
>
<el-image
:src=
"item.picture_url"
:fit=
"'fill'"
class=
"single-image"
@
click=
'clickItem(item)'
>
</el-image>
<span
class=
"el-icon-document downloadFile"
@
click=
"downloadFile(item,$event)"
></span>
<span
class=
"el-icon-picture-outline openImage"
@
click=
"openImage(item,$event)"
></span>
<p
class=
"featureNum"
>
{{
(
item
.
featureNum
).
toFixed
(
2
)
}}
</p>
<div>
时间:
{{
item
.
counttime
}}
</div>
<div>
人员类型:
{{
item
.
person_type
==
1
?
'店员'
:
'顾客'
}}
</div>
<div
class=
"direction"
:class=
"'direction'+item.direction"
>
方向:
{{
formatDirection
(
item
.
direction
)
}}
</div>
<div>
地点:
{{
item
.
gate_name
}}
</div>
</el-col>
<a-empty
v-if=
'featureList.length==0'
style=
'margin: 0 auto;'
></a-empty>
</el-row>
</el-col>
<el-col
:span=
"8"
class=
'imgBox1'
v-loading=
'isLoading1'
>
<p
class=
"title"
>
<span
class=
"name"
>
特征比对
</span>
<span
class=
"num"
>
{{
comparisonList
.
length
}}
张
</span>
</p>
<el-row
:gutter=
"10"
class=
"imgBox1_top"
>
<el-col
:span=
"8"
class=
"itemBox"
v-for=
"item in comparisonList"
>
<el-image
:src=
"item.picture_url"
:fit=
"'fill'"
class=
"single-image"
@
click=
'clickItem(item)'
>
</el-image>
<span
class=
"el-icon-picture-outline openImage"
@
click=
"openImage(item,$event)"
></span>
<span
class=
"el-icon-document downloadFile"
@
click=
"downloadFile(item,$event)"
></span>
<p
class=
"featureNum"
>
{{
item
.
featureNum
?(
item
.
featureNum
).
toFixed
(
2
):
0
}}
</p>
<div>
时间:
{{
item
.
counttime
}}
</div>
<div>
人员类型:
{{
item
.
person_type
==
1
?
'店员'
:
'顾客'
}}
</div>
<div
class=
"direction"
:class=
"'direction'+item.direction"
>
方向:
{{
formatDirection
(
item
.
direction
)
}}
</div>
<div>
地点:
{{
item
.
gate_name
}}
</div>
</el-col>
<a-empty
v-if=
'comparisonList.length==0'
style=
'margin: 0 auto;'
></a-empty>
</el-row>
</el-col>
<el-col
:span=
"8"
class=
'imgBox1'
v-loading=
'isLoading2'
>
<p
class=
"title"
>
<span
class=
"name"
>
重提特征后比对
</span>
<a-button
class=
"id"
type=
"primary"
@
click=
"reComparisonFeature"
>
重提特征比对
</a-button>
<span
class=
"num"
>
{{
reComparisonList
.
length
}}
张
</span>
</p>
<el-row
:gutter=
"10"
class=
"imgBox1_top"
>
<el-col
:span=
"8"
class=
"itemBox"
v-for=
"item in reComparisonList"
>
<el-image
:src=
"item.picture_url"
:fit=
"'fill'"
class=
"single-image"
@
click=
'clickItem(item)'
>
</el-image>
<span
class=
"el-icon-picture-outline openImage"
@
click=
"openImage(item,$event)"
></span>
<span
class=
"el-icon-document downloadFile"
@
click=
"downloadFile(item,$event)"
></span>
<p
class=
"featureNum"
>
{{
item
.
featureNum
?(
item
.
featureNum
).
toFixed
(
2
):
0
}}
</p>
<div>
时间:
{{
item
.
counttime
}}
</div>
<div>
人员类型:
{{
item
.
person_type
==
1
?
'店员'
:
'顾客'
}}
</div>
<div
class=
"direction"
:class=
"'direction'+item.direction"
>
方向:
{{
formatDirection
(
item
.
direction
)
}}
</div>
<div>
地点:
{{
item
.
gate_name
}}
</div>
</el-col>
<a-empty
v-if=
'reComparisonList.length==0'
style=
'margin: 0 auto;'
></a-empty>
</el-row>
</el-col>
</el-row>
<template
#
footer
>
<a-button
@
click=
"onCancel"
>
返回
</a-button>
</
template
>
</a-modal>
<imgDialog
ref=
'imgModelRef'
></imgDialog>
<imgOtherDialog
ref=
"imgOtherDialogRef"
></imgOtherDialog>
</template>
<
script
>
import
{
reactive
,
ref
,
watch
}
from
"vue"
;
import
featureApi
from
'@/views/FeatureComparisonVerification/api.js'
import
clusterResultApi
from
'@/views/SnapshotCluster/ClusterResult/ClusterResultApi'
import
{
isArray
}
from
'@/PublicUtil/Judgment'
import
imgDialog
from
'./imgDialog.vue'
import
imgOtherDialog
from
"../ComparisonCapturedPictures/imgOtherDialog.vue"
;
export
default
{
components
:{
imgDialog
,
imgOtherDialog
},
setup
()
{
const
isVisible
=
ref
(
false
);
const
isLoading
=
ref
(
false
);
const
isLoading1
=
ref
(
false
);
const
isLoading2
=
ref
(
false
);
const
detailData
=
ref
({});
const
featureList
=
ref
([])
const
imgModelRef
=
ref
();
const
imgOtherDialogRef
=
ref
();
const
comparisonList
=
ref
([])
const
reComparisonList
=
ref
([])
const
formatDirection
=
function
(
number
)
{
switch
(
number
)
{
case
1
:
{
return
'进'
}
case
-
1
:
{
return
'出'
}
case
0
:
{
return
'横穿'
}
default
:
{
break
}
}
}
watch
([
featureList
],(
newVal
,
oldVal
)
=>
{
},{
deep
:
true
})
const
initDialog
=
(
data
)
=>
{
isLoading
.
value
=
true
;
isLoading1
.
value
=
true
;
isLoading2
.
value
=
false
;
detailData
.
value
=
data
;
featureList
.
value
=
[]
reComparisonList
.
value
=
[]
featureApi
.
getPersonContrastList
(
data
).
then
((
r
)
=>
{
isLoading
.
value
=
false
if
(
r
.
data
&&
isArray
(
r
.
data
.
personList
))
{
r
.
data
.
personList
.
forEach
((
item
)
=>
{
if
(
item
.
features_url
)
{
item
.
features_url
=
window
.
_baseImgUrl
+
item
.
features_url
}
if
(
item
.
picture_url
)
{
item
.
picture_url
=
window
.
_baseImgUrl
+
item
.
picture_url
}
})
featureList
.
value
=
r
.
data
.
personList
}
}
)
comparisonList
.
value
=
[]
featureApi
.
getAllPersonContrastList
(
data
).
then
((
r
)
=>
{
isLoading1
.
value
=
false
if
(
isArray
(
r
.
data
))
{
if
(
r
.
data
.
length
>
0
){
r
.
data
.
forEach
((
item
)
=>
{
if
(
item
.
features_url
)
{
item
.
features_url
=
window
.
_baseImgUrl
+
item
.
features_url
}
if
(
item
.
picture_url
)
{
item
.
picture_url
=
window
.
_baseImgUrl
+
item
.
picture_url
}
})
comparisonList
.
value
=
r
.
data
}
}
}
)
isVisible
.
value
=
true
;
};
const
clickItem
=
function
(
data
){
clusterResultApi
.
getBodyPoint
({
'feature_url'
:
data
.
features_url
}).
then
((
r
)
=>
{
imgModelRef
.
value
.
initDialog
(
data
.
picture_url
,
r
.
data
);
})
}
const
reComparisonFeature
=
function
(){
isLoading2
.
value
=
true
reComparisonList
.
value
=
[]
featureApi
.
getNewPersonContrastList
(
detailData
.
value
).
then
((
r
)
=>
{
isLoading2
.
value
=
false
if
(
isArray
(
r
.
data
))
{
if
(
r
.
data
.
length
>
0
){
r
.
data
.
forEach
((
item
)
=>
{
if
(
item
.
features_url
)
{
item
.
features_url
=
window
.
_baseImgUrl
+
item
.
features_url
}
if
(
item
.
picture_url
)
{
item
.
picture_url
=
window
.
_baseImgUrl
+
item
.
picture_url
}
})
reComparisonList
.
value
=
r
.
data
}
}
}
)
}
const
downloadFile
=
function
(
item
,
event
){
event
.
stopPropagation
()
if
(
item
.
features_url
){
window
.
open
(
item
.
features_url
)
}
else
{
ElMessage
(
{
message
:
`该图片没有特征`
,
type
:
'warning'
}
)
return
}
}
const
openImage
=
function
(
item
,
event
){
event
.
stopPropagation
()
if
(
item
.
features_url
){
let
url
=
item
.
picture_url
imgOtherDialogRef
.
value
.
initDialog
(
url
.
split
(
'0.jpg'
)[
0
]
+
'1.jpg'
)
}
else
{
ElMessage
(
{
message
:
`该图片没有特征`
,
type
:
'warning'
}
)
return
}
}
const
onCancel
=
()
=>
{
isVisible
.
value
=
false
;
};
return
{
isVisible
,
onCancel
,
initDialog
,
isLoading
,
isLoading1
,
isLoading2
,
detailData
,
featureList
,
formatDirection
,
downloadFile
,
clickItem
,
imgModelRef
,
comparisonList
,
reComparisonList
,
reComparisonFeature
,
openImage
,
imgOtherDialogRef
};
},
};
</
script
>
<
style
lang=
"less"
scoped
>
.single-image
{
height
:
200px
;
width
:
150px
;
cursor
:
pointer
;
}
.direction
{
font-weight
:
900
;
background-color
:
red
;
color
:
white
;
}
.direction1
{
background-color
:
green
;
}
.direction0
{
background-color
:
orange
;
}
.title
{
height
:
32px
;
line-height
:
32px
;
padding
:
0
;
.name{
font-weight
:
900
;
font-size
:
18px
;
}
.id
{
margin-left
:
20px
;
}
.num
{
float
:
right
;
margin-right
:
15px
;
}
}
.imgBox1
{
//
border-left
:
10px
solid
#efefef
;
box-sizing
:
border-box
;
min-height
:
100%
;
.itemBox{
position
:
relative
;
}
.downloadFile
{
position
:
absolute
;
color
:
#1890ff
;
font-size
:
32px
;
top
:
0
;
right
:
10px
;
cursor
:
pointer
;
}
.openImage
{
position
:
absolute
;
color
:
#1890ff
;
font-size
:
32px
;
top
:
0
;
left
:
90px
;
cursor
:
pointer
;
}
.featureNum
{
position
:
absolute
;
top
:
0
;
left
:
15px
;
color
:
red
;
font-weight
:
900
;
font-size
:
16px
;
}
}
.imgBox1_top
{
min-height
:
400px
;
max-height
:
600px
;
overflow-y
:
auto
;
}
</
style
>
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