Commit c0fabd49 by 李乾广

增加事件图

1 parent 3687a857
<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"
@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"
@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.type" style="width: 240px">
<a-select-option :value="0">全场</a-select-option>
<a-select-option :value="1">广场出入口</a-select-option>
<a-select-option :value="2">楼层出入口</a-select-option>
<a-select-option :value="3">店铺出入口</a-select-option>
<a-select-option :value="4">其他</a-select-option>
<a-select-option :value="5">不以广场出入口开始</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="区域信息:" style="padding: 5px 0">
<a-select v-model:value="queryForm.zone_id"
style="width: 240px"
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: 240px"
mode="multiple"
:maxTagCount="1"
:options="gateList"
optionFilterProp="label"
show-search
>
</a-select>
</a-form-item>
<a-form-item label="事件类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.direction"
mode="multiple"
:maxTagCount="1"
style="width: 240px">
<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-option :value="9">收银</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="抓拍类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.picType" style="width: 240px">
<a-select-option :value="1">半身照</a-select-option>
<a-select-option :value="2">全身照</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="人员类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.personType"
mode="multiple"
:options="personTypeList"
optionFilterProp="label"
:maxTagCount="1"
style="width: 240px">
</a-select>
</a-form-item>
<!--<a-form-item label="年龄类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.childAdult"
mode="multiple"
:maxTagCount="1"
style="width: 240px">
<a-select-option :value="1">成人</a-select-option>
<a-select-option :value="0">儿童</a-select-option>
<a-select-option :value="-1">未知</a-select-option>
</a-select>
</a-form-item>-->
<a-form-item label="年龄类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.childAdult"
mode="multiple"
:maxTagCount="1"
style="width: 240px">
<a-select-option
v-for="item in childAdultAgeOptions"
:key="item.value"
:value="item.value"
>{{item.label}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="设备序列号:" style="padding: 5px 0;" class="label-width-wu">
<a-input v-model:value="queryForm.deviceSerialNum" style="width: 240px"/>
</a-form-item>
<a-form-item label="人ID:" style="padding: 5px 0">
<a-input v-model:value="queryForm.personUnid" style="width: 240px"/>
</a-form-item>
<a-form-item label="选择日期:" style="padding: 5px 0">
<a-date-picker v-model:value="queryForm.date" :format="'YYYY-MM-DD'" :allowClear="false" 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"/>
<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 v-model:value="queryForm.minPic" style="width: 129px"/>
<a-input v-model:value="queryForm.maxPic" style="width: 129px"/>
</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="comparativeFun">特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="singleComparativeFun">单张特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="clerkComparativeFun">店员特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="personnelComparativeFun">人员特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="updatePersonInfoByGroup">类型修正</a-button>
</a-form-item>
<a-form-item style="padding: 0px 5px;border: 1px solid #ccc;border-radius: 6px;">
<a-button type="primary" @click="handleMutipleOperation">{{mutipleOperationText}}</a-button>
<i class="el-icon-arrow-right" style="margin: 0px 10px;"></i>
<el-button type="text" :disabled="!isMultipleOperation" @click="movePersonRecord(person)">移动</el-button>
<!-- <a-popconfirm
title="将从本组中剔除,您确认吗?"
ok-text="是"
cancel-text="否"
"
>
</a-popconfirm> -->
<el-button type="text" :disabled="!isMultipleOperation" @click="deletePersonRecord(person)">剔除</el-button>
<a-popconfirm
title="是否添加至店员库"
ok-text="是"
cancel-text="否"
@confirm="addShopkeeper(person)"
>
<el-button type="text" :disabled="!isMultipleOperation">添加店员库</el-button>
</a-popconfirm>
<el-button type="text" :disabled="!isMultipleOperation" @click="addPersonnelPool(person)">添加人员库</el-button>
<a-popconfirm
title="将彻底删除,您确认吗?"
ok-text="是"
cancel-text="否"
@confirm="deleteRealPersonRecord(person)"
>
<el-button type="text" :disabled="!isMultipleOperation">删除</el-button>
</a-popconfirm>
</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>
<!--修正组类型数据-->
<!-- <span class="expandWord" @click='updatePersonInfoByGroup(person)'>类型修正</span> -->
<span class="expandWord" @click='uploadGroupData(person)'>上传数据</span>
<span class="expandWord" @click='searchPersonInfoByGroup(person)'>搜索</span>
<el-checkbox class="checkBox" v-model="person.checked" @change='checkChange(person)'></el-checkbox>
人id:{{ ' ' + person.person_unid }}
图片数量:{{ person.perrsonList.length }}
</div>
<el-row v-for="row in getPagedList(person.perrsonList, 8)">
<el-col :span="3" v-for="item in row">
<div
style="margin: 0 5px"
:class="[(currentItemId==item.id)?'actived':'', isSelectedPerson(item.id)?'actived-red':'']"
@click="handleClick(item, $event)"
>
<div style="">
<span @click="downloadTrajectoryFile(item.track_url)"
class="downBtn">
轨迹
</span>
<span @click="downloadFile(item.features_url)"
class="downBtn downBtn1">
特征
</span>
</div>
<el-image :src="item.picture_url"
:fit="'fill'"
class="single-image">
</el-image>
<div>时间:{{ item.counttime }}</div>
<div>人员类型:{{ personTypeStr(item.person_type)}}({{ formatChildAdult(item.childAdult) }})</div>
<div>性别:{{ formatGender(item.gender) }}({{item.age}})</div>
<div class="direction" :class="'direction'+item.direction">事件类型:{{ formatDirection(item.direction) }}</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;margin-top: 10px;"
/>
</div>
</div>
<!-- <imgDialog ref='imgModelRef'></imgDialog> -->
<DetailDialog ref="DetailDialogRef" />
<PersonnelDialog ref="personnelDialogRef" />
<DetailDialogComparison ref="DetailDialogComparisonRef" />
<singleImgComparisonDialog ref="singleImgComparisonRef"></singleImgComparisonDialog>
<PersonGroupEditor ref='personGroupEditorRef' @refresh="handleEditorRefresh" />
<UploadGroupDataEditor ref='uploadGroupDataEditorRef' @refresh="handleEditorRefresh" />
<PersonGroupMover ref='personGroupMoverRef' :data-params="currentSearchCondition" :data-list="dataList" @refresh="handleRefresh" />
<AddPersonnelPool ref='personnelPoolRef' :data-params="currentSearchCondition" @refresh="handleRefresh" />
<PersonGroupDialog ref='personGroupDialogRef' :query-form="queryForm" @refresh="handleRefresh" />
</template>
<script>
import {computed, reactive, ref, toRaw} from 'vue'
import clusterResultApi from '@/views/SnapshotCluster/ClusterResult/ClusterResultApi'
import {isArray} from '@/PublicUtil/Judgment'
import moment from 'moment'
import {filterEmptyValueInObject, formatDate, formatTime, getPagedList} from '@/PublicUtil/PublicUtil'
// import imgDialog from '../imgDialog.vue'
import {ElMessage} from 'element-plus'
import DetailDialog from "../../ComparisonCapturedPictures/DetailDialog.vue";
import PersonnelDialog from "../../ComparisonCapturedPictures/PersonnelDialog.vue";
import DetailDialogComparison from "../../ComparisonCapturedPictures/DetailDialogComparisonNew.vue";
import singleImgComparisonDialog from "../singleImgComparisonDialog.vue";
import PersonGroupEditor from "./PersonGroupEditor.vue";
import UploadGroupDataEditor from "./UploadGroupDataEditor.vue";
import PersonGroupDialog from "./PersonGroupDialog.vue";
import PersonGroupMover from "./PersonGroupMover.vue";
import AddPersonnelPool from "./AddPersonnelPool.vue";
export default {
components:{
PersonGroupEditor,
UploadGroupDataEditor,
PersonGroupDialog,
PersonGroupMover,
AddPersonnelPool,
// imgDialog
DetailDialog,
PersonnelDialog,
DetailDialogComparison,
singleImgComparisonDialog
},
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const currobj = ref({})
const currentItemId = ref()
// sequence
const dataList = ref([])
const accountList = ref([])
const plazaList = ref([])
const personTypeList = ref([])
const zoneList = ref([])
const gateList = ref([])
// const imgModelRef = ref();
const pagedTableDataList = computed(
() => {
return getPagedList(dataList.value, 8)
}
)
const DetailDialogRef = ref();
const personnelDialogRef = ref();
const DetailDialogComparisonRef = ref();
const singleImgComparisonRef = ref()
const queryForm = reactive(
{
account_id: '',
plaza_id: '',
zone_id: [],
gate_id: [],
type: 0,
direction: [1, -1, 0],
picType: 2,
personType: [],
date: moment(moment().format('YYYY-MM-DD'), 'YYYY-MM-DD'),
startTime: '00:00:00',
endTime: '23:59:59',
minPic: 0,
maxPic: 100,
childAdult:[],
deviceSerialNum:'',
}
)
const searchCondition = ref({})
if(window.localStorage.getItem('searchCondition')){
searchCondition.value = JSON.parse(window.localStorage.getItem('searchCondition'));
console.log(13,searchCondition.value)
queryForm.type = searchCondition.value.type;
queryForm.zone_id = searchCondition.value.zone_id;
queryForm.gate_id = searchCondition.value.gate_id;
queryForm.direction = searchCondition.value.direction;
queryForm.childAdult = searchCondition.value.childAdult;
queryForm.picType = searchCondition.value.picType;
queryForm.date = searchCondition.value.date;
queryForm.startTime = searchCondition.value.startTime;
queryForm.endTime = searchCondition.value.endTime;
queryForm.minPic = searchCondition.value.minPic||0;
queryForm.maxPic = searchCondition.value.maxPic||100;
queryForm.deviceSerialNum = searchCondition.value.deviceSerialNum;
}
// function
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)
// getZoneList()
// getGateList()
}
const onPlazaChange = function() {
reqPersonType()
getZoneList()
getGateList()
}
const onZoneChange = function() {
getGateList()
}
const getPlazaList = function(val) {
queryForm.plaza_id = ''
plazaList.value = []
clusterResultApi.getPlazaList(
{
account_id: queryForm.account_id
}
).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[0]
}else{
queryForm.plaza_id = plazaList.value[0].value
}
reqPersonType(1)
getZoneList(1)
getGateList(1)
}
}
}
)
}
const getZoneList = function(val) {
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 = []
}
}else{
queryForm.zone_id = []
}
}
}
)
}
const getGateList = function(val) {
gateList.value = []
clusterResultApi.getGateList(
{
account_id: queryForm.account_id,
plaza_id: queryForm.plaza_id,
zone_id: queryForm.zone_id?queryForm.zone_id.toString():'',
type: queryForm.type,
}
).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[0]
}else{
queryForm.account_id = accountList.value[0].value
}
getPlazaList()
}
}
}
)
}
const clickSearch = function() {
pageNum.value = 1
confirmSearch()
}
const handleRefresh = function() {
isMultipleOperation.value = false
selectedPersonList.value = []
confirmSearch()
}
const handleEditorRefresh = function() {
isMultipleOperation.value = false
selectedPersonList.value = []
confirmSearch(1)
}
const currentSearchCondition = ref()
const confirmSearch = function(type) {
isLoading.value = true
const rawData = toRaw(queryForm)
const data = filterEmptyValueInObject(
{
account_id: rawData.account_id,
type: rawData.type,
plaza_id: rawData.plaza_id,
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?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?rawData.childAdult.toString():'',
// 查询条件
age: rawData.childAdult?rawData.childAdult.toString():'',
personUnid: rawData.personUnid,
deviceSerialNum: rawData.deviceSerialNum,
}
)
const storageData = filterEmptyValueInObject(
{
account_id: [rawData.account_id],
type: rawData.type,
plaza_id: [rawData.plaza_id],
zone_id: rawData.zone_id,
gate_id: rawData.gate_id,
direction: rawData.direction,
picType: rawData.picType,
personType: rawData.personType,
childAdult: rawData.childAdult,
date: rawData.date,
minPic: rawData.minPic,
maxPic: rawData.maxPic,
startTime: rawData.startTime,
endTime: rawData.endTime,
deviceSerialNum: rawData.deviceSerialNum,
}
)
let searchCondition = JSON.parse(window.localStorage.getItem('searchCondition'));
let newSearchCondition = {
...searchCondition,
...storageData
}
window.localStorage.setItem('searchCondition',JSON.stringify(newSearchCondition))
clusterResultApi.getClusterResultList(data).then(
(r) => {
isLoading.value = false
sortDataList(r.data.persons)
r.data.persons.forEach((itemPerson)=>{
itemPerson.checked = false
itemPerson.expand = false
itemPerson.perrsonList.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.persons
total.value = r.data.pageNum
if(!type) {
document.getElementsByClassName('resultContent')[0].scrollTop = 0
}
currentSearchCondition.value = data
}
)
}
const personTypeStr = function(val){
return (personTypeList.value.filter(v => v.value == val)[0] || {label:'--'}).label
}
const childAdultAgeOptions = ref([
{ value: 0, label: '婴儿' },
{ value: 1, label: '儿童' },
{ value: 2, label: '少年' },
{ value: 3, label: '青年' },
{ value: 4, label: '中年' },
{ value: 5, label: '老年' },
{ value: -1, label: '未知' },
])
const childAdultOptions = ref([
{ value: 0, label: '儿童' },
{ value: 1, label: '成人' },
{ value: -1, label: '未知' },
])
const formatChildAdult = function(val) {
const targetitem = childAdultOptions.value.find(item => item.value === val)
if (targetitem) return targetitem.label
else return '未知'
}
const formatGender = function(number){
switch (number)
{
case 1:
{
return '男'
}
case -1:
{
return '未知'
}
case 0:
{
return '女'
}
default:
{
break
}
}
}
const formatDirection = function(number) {
switch (number)
{
case 1:
{
return '进'
}
case -1:
{
return '出'
}
case 9:
{
return '收银'
}
case 2:
{
return '过店'
}
case 0:
{
return '横穿'
}
default:
{
break
}
}
}
const sortDataList = function(list) {
list.sort(
(a, b) => {
return (b.perrsonList.length - a.perrsonList.length)
}
)
}
const reqPersonType = (val) => {
personTypeList.value = []
clusterResultApi.getPersonType({plaza_id:queryForm.plaza_id}).then(
(r) => {
console.log(1122,r)
if (isArray(r)) {
let personType = []
for (const item of r){
personType.push(item.id)
personTypeList.value.push({
value: item.id,
label: item.name,
})
}
if(personTypeList.value.length>0){
queryForm.personType = personType
}
}
if(val) {
confirmSearch()
}
}
)
};
// 人员类型修正
const personGroupEditorRef = ref();
// const isShowGroupEditor = ref(false)
const updatePersonInfoByGroup = function() {
let par = {
person_unids:[],
perrsonList:[],
personTypeList:personTypeList.value
}
dataList.value.forEach(item=>{
if (item.checked && item.checked == true) {
par.person_unids.push(item.person_unid)
par.perrsonList = (par.perrsonList.length==0&&item.perrsonList.length > 0)?item.perrsonList:par.perrsonList;
}
})
console.log('updatePersonInfoByGroup', par)
if(par.person_unids.length>0) {
personGroupEditorRef.value.initDialog(par);
}else{
ElMessage(
{
message: `请选择聚类图片`,
type: 'warning'
}
)
return
}
}
// 上传数据
const uploadGroupDataEditorRef = ref();
const uploadGroupData = function(data) {
let par = {
personUnid:data.person_unid,
countdate: moment(this.queryForm.date).format('YYYY-MM-DD'),
}
uploadGroupDataEditorRef.value.initDialog(par);
}
// 批量操作
const isMultipleOperation = ref(false)
const handleMutipleOperation = () => {
// 在当前组操作,批量按钮
if (isMultipleOperation.value) {
// 已经是多选状态
isMultipleOperation.value = false
selectedPersonList.value = []
} else {
// 非多选状态
isMultipleOperation.value = true
}
}
const mutipleOperationText = computed(() => {
if (isMultipleOperation.value) {
return '取消操作'
} else {
return '批量操作'
}
})
const isSelectedPerson = (id) => {
return selectedPersonList.value.some(item => item.id === id)
}
// 剔除人员
const selectedPersonList = ref([]) // 批量操作,选中的图片
const deletePersonRecord = () => {
console.log('deletePersonRecord', selectedPersonList)
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
const unidList = selectedPersonList.value.map(item => item.unid)
const params = {
unid: unidList.join(','),
personUnid: '',
countdate: selectedPersonList.value[0].counttime
}
clusterResultApi.updateRecognition(params).then(
(r) => {
if(r.msg_code==200){
ElMessage({
message: `剔除成功`,
type: 'success'
})
selectedPersonList.value = []
// 刷新列表
handleRefresh()
} else {
ElMessage({
message: `剔除失败`,
type: 'error'
})
}
}
)
}
// 删除人员
const deleteRealPersonRecord = () => {
console.log('deletePersonRecord', selectedPersonList)
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
const strIdList = selectedPersonList.value.map(item => item.id).join(',')
const params = {
id: strIdList,
}
clusterResultApi.deleteRecognition(params).then(
(r) => {
if(r.msg_code==200){
ElMessage({
message: `删除成功`,
type: 'success'
})
selectedPersonList.value = []
// 刷新列表
handleRefresh()
} else {
ElMessage({
message: `删除失败`,
type: 'error'
})
}
}
)
}
// 添加店员库
const addShopkeeper = () => {
console.log('addShopkeeper', selectedPersonList)
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
const strIdList = selectedPersonList.value.map(item => item.unid)
const rawData = toRaw(queryForm)
const params = {
unids: strIdList,
mallId:selectedPersonList.value[0].mall_id,
countdate:formatDate(rawData.date) + ' 00:00:00',
}
clusterResultApi.addDataToShopkeeper(params).then(
(r) => {
if(r.msg_code==200){
ElMessage({
message: `添加成功`,
type: 'success'
})
selectedPersonList.value = []
// 刷新列表
handleRefresh()
} else {
ElMessage({
message: `添加失败`,
type: 'error'
})
}
}
)
}
// 添加人员库
const personnelPoolRef = ref();
const addPersonnelPool = () => {
console.log('addPersonnelPool')
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
personnelPoolRef.value.initDialog(selectedPersonList.value);
}
// 移动人员
const personGroupMoverRef = ref();
const movePersonRecord = () => {
console.log('movePersonRecord')
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
personGroupMoverRef.value.initDialog(selectedPersonList.value);
}
// 查询组
const personGroupDialogRef = ref();
const searchPersonInfoByGroup = function(data) {
console.log('searchPersonInfoByGroup', data)
/* let parmas = {
// person_unid: currobj.value.person_unid,
pic_type: data.picType,
endTime:formatDate(rawData.date) + ' ' + rawData.endTime,
startTime:formatDate(rawData.date) + ' ' + rawData.startTime,
countdate:formatDate(rawData.date),
pic_id:currobj.value.id,
ip:window._baseImgUrl,
plaza_id:currobj.value.mall_id
} */
// singleImgComparisonRef.value.initDialog(parmas);
personGroupDialogRef.value.initDialog(data);
}
const downloadFile = function(url) {
window.open(url)
}
const downloadTrajectoryFile = function(url){
window.open(url)
}
const handleClick = function(data, event){
console.log('handleClick', data, event)
// 多选。只有设置为多选状态的组,才可以选中
if (isMultipleOperation.value) {
// 如果已选中,则取消。若未选中,则增加
const isExist = selectedPersonList.value.find(item => item.id === data.id)
if (isExist) {
selectedPersonList.value = selectedPersonList.value.filter(item => item.id !== data.id)
} else {
selectedPersonList.value.push(data)
}
} else {
currentItemId.value = data.id
currobj.value = data;
// 清空多选
selectedPersonList.value = []
}
}
const checkChange = function(data){
console.log(data)
}
const expandChange = function(data){
dataList.value.forEach(item=>{
if (data.person_unid == item.person_unid) {
item.expand = !item.expand
}
})
}
// 特征对比
const comparativeFun = function(){
const rawData = toRaw(queryForm)
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
let parmas = {
mall_id:currobj.value.mall_id,
picType:rawData.picType,
pic_id:currobj.value.id,
countdate:formatDate(rawData.date),
dataList:[]
}
dataList.value.forEach(item=>{
if (item.checked && item.checked == true) {
parmas.dataList.push(item)
}
})
if(parmas.dataList && parmas.dataList.length > 0){
DetailDialogComparisonRef.value.initDialog(currobj.value,parmas);
}else{
ElMessage(
{
message: `请选择聚类图片`,
type: 'warning'
}
)
return
}
}
//单张特征对比
const singleComparativeFun = function(){
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
const rawData = toRaw(queryForm)
console.log(queryForm)
console.log(rawData)
let parmas = {
person_unid:currobj.value.person_unid,
pic_type:rawData.picType,
endTime:formatDate(rawData.date) + ' ' + rawData.endTime,
startTime:formatDate(rawData.date) + ' ' + rawData.startTime,
countdate:formatDate(rawData.date),
pic_id:currobj.value.id,
ip:window._baseImgUrl,
plaza_id:currobj.value.mall_id
}
singleImgComparisonRef.value.initDialog(parmas);
}
// 店员特征对比
const clerkComparativeFun = function(){
const rawData = toRaw(queryForm)
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片进行对比`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
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 personnelComparativeFun = function(){
const rawData = toRaw(queryForm)
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片进行对比`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
let parmas = {
plaza_id:currobj.value.mall_id,
pic_type:rawData.picType,
pic_id:currobj.value.id,
ip:window._baseImgUrl,
countdate:formatDate(rawData.date)
}
personnelDialogRef.value.initDialog(currobj.value,parmas);
}
const contentHeight = ref(0)
const __main = function() {
getAccountList()
contentHeight.value = window.innerHeight - 280
}
__main()
return {
// scalar
isLoading,
pageNum,
pageSize,
total,
currentItemId,
currobj,
// sequence
accountList,
plazaList,
personTypeList,
zoneList,
gateList,
pagedTableDataList,
dataList,
contentHeight,
// mapping
queryForm,
// function
onPageNumChange,
onPageSizeChange,
onAccountChange,
onPlazaChange,
onZoneChange,
confirmSearch,
formatDirection,
downloadFile,
getPagedList,
handleClick,
comparativeFun,
checkChange,
expandChange,
updatePersonInfoByGroup,
uploadGroupData,
deletePersonRecord,
addPersonnelPool,
movePersonRecord,
searchPersonInfoByGroup,
isSelectedPerson,
selectedPersonList,
clerkComparativeFun,
personnelComparativeFun,
singleComparativeFun,
personTypeStr,
formatGender,
downloadTrajectoryFile,
clickSearch,
handleRefresh,
handleEditorRefresh,
currentSearchCondition,
// ref
// imgModelRef,
DetailDialogRef,
personnelDialogRef,
personGroupDialogRef,
personGroupEditorRef,
uploadGroupDataEditorRef,
DetailDialogComparisonRef,
singleImgComparisonRef,
personGroupMoverRef,
personnelPoolRef,
reqPersonType,
isMultipleOperation,
handleMutipleOperation,
mutipleOperationText,
deleteRealPersonRecord,
addShopkeeper,
childAdultAgeOptions,
childAdultOptions,
formatChildAdult
}
}
}
</script>
<style lang="less" scoped>
@import "./ClusterResult";
.actived{
border: 3px solid #1890ff;
}
.actived-red {
border: 3px solid red;
}
.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;
}
.multiple-operation {
display: inline-block;
margin-left: 20px;
}
</style>
<style type="text/css">
.label-width-wu .ant-form-item-label{
width: 84px!important;
}
</style>
<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"
@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"
@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.type" style="width: 240px">
<a-select-option :value="0">全场</a-select-option>
<a-select-option :value="1">广场出入口</a-select-option>
<a-select-option :value="2">楼层出入口</a-select-option>
<a-select-option :value="3">店铺出入口</a-select-option>
<a-select-option :value="4">其他</a-select-option>
<a-select-option :value="5">不以广场出入口开始</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="区域信息:" style="padding: 5px 0">
<a-select v-model:value="queryForm.zone_id"
style="width: 240px"
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: 240px"
mode="multiple"
:maxTagCount="1"
:options="gateList"
optionFilterProp="label"
show-search
>
</a-select>
</a-form-item>
<a-form-item label="事件类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.direction"
mode="multiple"
:maxTagCount="1"
style="width: 240px">
<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-option :value="9">收银</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="抓拍类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.picType" style="width: 240px">
<a-select-option :value="1">半身照</a-select-option>
<a-select-option :value="2">全身照</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="人员类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.personType"
mode="multiple"
:options="personTypeList"
optionFilterProp="label"
:maxTagCount="1"
style="width: 240px">
</a-select>
</a-form-item>
<!--<a-form-item label="年龄类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.childAdult"
mode="multiple"
:maxTagCount="1"
style="width: 240px">
<a-select-option :value="1">成人</a-select-option>
<a-select-option :value="0">儿童</a-select-option>
<a-select-option :value="-1">未知</a-select-option>
</a-select>
</a-form-item>-->
<a-form-item label="年龄类型:" style="padding: 5px 0">
<a-select v-model:value="queryForm.childAdult"
mode="multiple"
:maxTagCount="1"
style="width: 240px">
<a-select-option
v-for="item in childAdultAgeOptions"
:key="item.value"
:value="item.value"
>{{item.label}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="设备序列号:" style="padding: 5px 0;" class="label-width-wu">
<a-input v-model:value="queryForm.deviceSerialNum" style="width: 240px"/>
</a-form-item>
<a-form-item label="人ID:" style="padding: 5px 0">
<a-input v-model:value="queryForm.personUnid" style="width: 240px"/>
</a-form-item>
<a-form-item label="选择日期:" style="padding: 5px 0">
<a-date-picker v-model:value="queryForm.date" :format="'YYYY-MM-DD'" :allowClear="false" 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"/>
<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 v-model:value="queryForm.minPic" style="width: 129px"/>
<a-input v-model:value="queryForm.maxPic" style="width: 129px"/>
</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="comparativeFun">特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="singleComparativeFun">单张特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="clerkComparativeFun">店员特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="personnelComparativeFun">人员特征对比</a-button>
</a-form-item>
<a-form-item style="padding: 5px 0">
<a-button type="primary" @click="updatePersonInfoByGroup">类型修正</a-button>
</a-form-item>
<a-form-item style="padding: 0px 5px;border: 1px solid #ccc;border-radius: 6px;">
<a-button type="primary" @click="handleMutipleOperation">{{mutipleOperationText}}</a-button>
<i class="el-icon-arrow-right" style="margin: 0px 10px;"></i>
<el-button type="text" :disabled="!isMultipleOperation" @click="movePersonRecord(person)">移动</el-button>
<!-- <a-popconfirm
title="将从本组中剔除,您确认吗?"
ok-text="是"
cancel-text="否"
"
>
</a-popconfirm> -->
<el-button type="text" :disabled="!isMultipleOperation" @click="deletePersonRecord(person)">剔除</el-button>
<a-popconfirm
title="是否添加至店员库"
ok-text="是"
cancel-text="否"
@confirm="addShopkeeper(person)"
>
<el-button type="text" :disabled="!isMultipleOperation">添加店员库</el-button>
</a-popconfirm>
<el-button type="text" :disabled="!isMultipleOperation" @click="addPersonnelPool(person)">添加人员库</el-button>
<a-popconfirm
title="将彻底删除,您确认吗?"
ok-text="是"
cancel-text="否"
@confirm="deleteRealPersonRecord(person)"
>
<el-button type="text" :disabled="!isMultipleOperation">删除</el-button>
</a-popconfirm>
</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>
<!--修正组类型数据-->
<!-- <span class="expandWord" @click='updatePersonInfoByGroup(person)'>类型修正</span> -->
<span class="expandWord" @click='uploadGroupData(person)'>上传数据</span>
<span class="expandWord" @click='searchPersonInfoByGroup(person)'>搜索</span>
<el-checkbox class="checkBox" v-model="person.checked" @change='checkChange(person)'></el-checkbox>
人id:{{ ' ' + person.person_unid }}
图片数量:{{ person.perrsonList.length }}
<span style="margin-left: 20px;">当前显示:{{person.imageDisplayType?'事件图':'抓拍图'}}</span> <span style="color: #1890ff;margin-left: 20px;cursor: pointer;" @click='toggleImageDisplayType(person)'>{{person.imageDisplayType?'切换显示抓拍图':'切换显示事件图'}}</span>
</div>
<el-row v-for="row in getPagedList(person.perrsonList, 8)">
<el-col :span="3" v-for="item in row">
<div
style="margin: 0 5px"
:class="[(currentItemId==item.id)?'actived':'', isSelectedPerson(item.id)?'actived-red':'']"
@click="handleClick(item, $event)"
>
<div style="">
<span @click="downloadTrajectoryFile(item.track_url)"
class="downBtn">
轨迹
</span>
<span @click="downloadFile(item.features_url)"
class="downBtn downBtn1">
特征
</span>
</div>
<el-image v-if="person.imageDisplayType" :src="item.eventPic" :fit="'fill'" class="single-image"></el-image> <el-image v-else :src="item.picture_url" :fit="'fill'" class="single-image"></el-image>
<div>时间:{{ item.counttime }}</div>
<div>人员类型:{{ personTypeStr(item.person_type)}}({{ formatChildAdult(item.childAdult) }})</div>
<div>性别:{{ formatGender(item.gender) }}({{item.age}})</div>
<div class="direction" :class="'direction'+item.direction">事件类型:{{ formatDirection(item.direction) }}</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;margin-top: 10px;"
/>
</div>
</div>
<!-- <imgDialog ref='imgModelRef'></imgDialog> -->
<DetailDialog ref="DetailDialogRef" />
<PersonnelDialog ref="personnelDialogRef" />
<DetailDialogComparison ref="DetailDialogComparisonRef" />
<singleImgComparisonDialog ref="singleImgComparisonRef"></singleImgComparisonDialog>
<PersonGroupEditor ref='personGroupEditorRef' @refresh="handleEditorRefresh" />
<UploadGroupDataEditor ref='uploadGroupDataEditorRef' @refresh="handleEditorRefresh" />
<PersonGroupMover ref='personGroupMoverRef' :data-params="currentSearchCondition" :data-list="dataList" @refresh="handleRefresh" />
<AddPersonnelPool ref='personnelPoolRef' :data-params="currentSearchCondition" @refresh="handleRefresh" />
<PersonGroupDialog ref='personGroupDialogRef' :query-form="queryForm" @refresh="handleRefresh" />
</template>
<script>
import {computed, reactive, ref, toRaw} from 'vue'
import clusterResultApi from '@/views/SnapshotCluster/ClusterResult/ClusterResultApi'
import {isArray} from '@/PublicUtil/Judgment'
import moment from 'moment'
import {filterEmptyValueInObject, formatDate, formatTime, getPagedList} from '@/PublicUtil/PublicUtil'
// import imgDialog from '../imgDialog.vue'
import {ElMessage} from 'element-plus'
import DetailDialog from "../../ComparisonCapturedPictures/DetailDialog.vue";
import PersonnelDialog from "../../ComparisonCapturedPictures/PersonnelDialog.vue";
import DetailDialogComparison from "../../ComparisonCapturedPictures/DetailDialogComparisonNew.vue";
import singleImgComparisonDialog from "../singleImgComparisonDialog.vue";
import PersonGroupEditor from "./PersonGroupEditor.vue";
import UploadGroupDataEditor from "./UploadGroupDataEditor.vue";
import PersonGroupDialog from "./PersonGroupDialog.vue";
import PersonGroupMover from "./PersonGroupMover.vue";
import AddPersonnelPool from "./AddPersonnelPool.vue";
export default {
components:{
PersonGroupEditor,
UploadGroupDataEditor,
PersonGroupDialog,
PersonGroupMover,
AddPersonnelPool,
// imgDialog
DetailDialog,
PersonnelDialog,
DetailDialogComparison,
singleImgComparisonDialog
},
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const currobj = ref({})
const currentItemId = ref()
// sequence
const dataList = ref([])
const accountList = ref([])
const plazaList = ref([])
const personTypeList = ref([])
const zoneList = ref([])
const gateList = ref([])
// const imgModelRef = ref();
const pagedTableDataList = computed(
() => {
return getPagedList(dataList.value, 8)
}
)
const DetailDialogRef = ref();
const personnelDialogRef = ref();
const DetailDialogComparisonRef = ref();
const singleImgComparisonRef = ref()
const queryForm = reactive(
{
account_id: '',
plaza_id: '',
zone_id: [],
gate_id: [],
type: 0,
direction: [1, -1, 0],
picType: 2,
personType: [],
date: moment(moment().format('YYYY-MM-DD'), 'YYYY-MM-DD'),
startTime: '00:00:00',
endTime: '23:59:59',
minPic: 0,
maxPic: 100,
childAdult:[],
deviceSerialNum:'',
}
)
const searchCondition = ref({})
if(window.localStorage.getItem('searchCondition')){
searchCondition.value = JSON.parse(window.localStorage.getItem('searchCondition'));
console.log(13,searchCondition.value)
queryForm.type = searchCondition.value.type;
queryForm.zone_id = searchCondition.value.zone_id;
queryForm.gate_id = searchCondition.value.gate_id;
queryForm.direction = searchCondition.value.direction;
queryForm.childAdult = searchCondition.value.childAdult;
queryForm.picType = searchCondition.value.picType;
queryForm.date = searchCondition.value.date;
queryForm.startTime = searchCondition.value.startTime;
queryForm.endTime = searchCondition.value.endTime;
queryForm.minPic = searchCondition.value.minPic||0;
queryForm.maxPic = searchCondition.value.maxPic||100;
queryForm.deviceSerialNum = searchCondition.value.deviceSerialNum;
}
// function
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)
// getZoneList()
// getGateList()
}
const onPlazaChange = function() {
reqPersonType()
getZoneList()
getGateList()
}
const onZoneChange = function() {
getGateList()
}
const getPlazaList = function(val) {
queryForm.plaza_id = ''
plazaList.value = []
clusterResultApi.getPlazaList(
{
account_id: queryForm.account_id
}
).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[0]
}else{
queryForm.plaza_id = plazaList.value[0].value
}
reqPersonType(1)
getZoneList(1)
getGateList(1)
}
}
}
)
}
const getZoneList = function(val) {
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 = []
}
}else{
queryForm.zone_id = []
}
}
}
)
}
const getGateList = function(val) {
gateList.value = []
clusterResultApi.getGateList(
{
account_id: queryForm.account_id,
plaza_id: queryForm.plaza_id,
zone_id: queryForm.zone_id?queryForm.zone_id.toString():'',
type: queryForm.type,
}
).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[0]
}else{
queryForm.account_id = accountList.value[0].value
}
getPlazaList()
}
}
}
)
}
const clickSearch = function() {
pageNum.value = 1
confirmSearch()
}
const handleRefresh = function() {
isMultipleOperation.value = false
selectedPersonList.value = []
confirmSearch()
}
const handleEditorRefresh = function() {
isMultipleOperation.value = false
selectedPersonList.value = []
confirmSearch(1)
}
const currentSearchCondition = ref()
const confirmSearch = function(type) {
isLoading.value = true
const rawData = toRaw(queryForm)
const data = filterEmptyValueInObject(
{
account_id: rawData.account_id,
type: rawData.type,
plaza_id: rawData.plaza_id,
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?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?rawData.childAdult.toString():'',
// 查询条件
age: rawData.childAdult?rawData.childAdult.toString():'',
personUnid: rawData.personUnid,
deviceSerialNum: rawData.deviceSerialNum,
}
)
const storageData = filterEmptyValueInObject(
{
account_id: [rawData.account_id],
type: rawData.type,
plaza_id: [rawData.plaza_id],
zone_id: rawData.zone_id,
gate_id: rawData.gate_id,
direction: rawData.direction,
picType: rawData.picType,
personType: rawData.personType,
childAdult: rawData.childAdult,
date: rawData.date,
minPic: rawData.minPic,
maxPic: rawData.maxPic,
startTime: rawData.startTime,
endTime: rawData.endTime,
deviceSerialNum: rawData.deviceSerialNum,
}
)
let searchCondition = JSON.parse(window.localStorage.getItem('searchCondition'));
let newSearchCondition = {
...searchCondition,
...storageData
}
window.localStorage.setItem('searchCondition',JSON.stringify(newSearchCondition))
clusterResultApi.getClusterResultList(data).then(
(r) => {
isLoading.value = false
sortDataList(r.data.persons)
r.data.persons.forEach((itemPerson)=>{
itemPerson.checked = false
itemPerson.expand = false
itemPerson.perrsonList.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.eventPic) { item.eventPic = window._baseImgUrl + item.eventPic }
if (item.track_url) {
item.track_url = window._baseImgUrl + item.track_url
}
})
})
dataList.value = r.data.persons
total.value = r.data.pageNum
if(!type) {
document.getElementsByClassName('resultContent')[0].scrollTop = 0
}
currentSearchCondition.value = data
}
)
}
const personTypeStr = function(val){
return (personTypeList.value.filter(v => v.value == val)[0] || {label:'--'}).label
}
const childAdultAgeOptions = ref([
{ value: 0, label: '婴儿' },
{ value: 1, label: '儿童' },
{ value: 2, label: '少年' },
{ value: 3, label: '青年' },
{ value: 4, label: '中年' },
{ value: 5, label: '老年' },
{ value: -1, label: '未知' },
])
const childAdultOptions = ref([
{ value: 0, label: '儿童' },
{ value: 1, label: '成人' },
{ value: -1, label: '未知' },
])
const formatChildAdult = function(val) {
const targetitem = childAdultOptions.value.find(item => item.value === val)
if (targetitem) return targetitem.label
else return '未知'
}
const formatGender = function(number){
switch (number)
{
case 1:
{
return '男'
}
case -1:
{
return '未知'
}
case 0:
{
return '女'
}
default:
{
break
}
}
}
const formatDirection = function(number) {
switch (number)
{
case 1:
{
return '进'
}
case -1:
{
return '出'
}
case 9:
{
return '收银'
}
case 2:
{
return '过店'
}
case 0:
{
return '横穿'
}
default:
{
break
}
}
}
const sortDataList = function(list) {
list.sort(
(a, b) => {
return (b.perrsonList.length - a.perrsonList.length)
}
)
}
const reqPersonType = (val) => {
personTypeList.value = []
clusterResultApi.getPersonType({plaza_id:queryForm.plaza_id}).then(
(r) => {
console.log(1122,r)
if (isArray(r)) {
let personType = []
for (const item of r){
personType.push(item.id)
personTypeList.value.push({
value: item.id,
label: item.name,
})
}
if(personTypeList.value.length>0){
queryForm.personType = personType
}
}
if(val) {
confirmSearch()
}
}
)
};
// 人员类型修正
const personGroupEditorRef = ref();
// const isShowGroupEditor = ref(false)
const updatePersonInfoByGroup = function() {
let par = {
person_unids:[],
perrsonList:[],
personTypeList:personTypeList.value
}
dataList.value.forEach(item=>{
if (item.checked && item.checked == true) {
par.person_unids.push(item.person_unid)
par.perrsonList = (par.perrsonList.length==0&&item.perrsonList.length > 0)?item.perrsonList:par.perrsonList;
}
})
console.log('updatePersonInfoByGroup', par)
if(par.person_unids.length>0) {
personGroupEditorRef.value.initDialog(par);
}else{
ElMessage(
{
message: `请选择聚类图片`,
type: 'warning'
}
)
return
}
}
// 上传数据
const uploadGroupDataEditorRef = ref();
const uploadGroupData = function(data) {
let par = {
personUnid:data.person_unid,
countdate: moment(this.queryForm.date).format('YYYY-MM-DD'),
}
uploadGroupDataEditorRef.value.initDialog(par);
}
// 批量操作
const isMultipleOperation = ref(false)
const handleMutipleOperation = () => {
// 在当前组操作,批量按钮
if (isMultipleOperation.value) {
// 已经是多选状态
isMultipleOperation.value = false
selectedPersonList.value = []
} else {
// 非多选状态
isMultipleOperation.value = true
}
}
const mutipleOperationText = computed(() => {
if (isMultipleOperation.value) {
return '取消操作'
} else {
return '批量操作'
}
})
// 切换图片显示类型 const toggleImageDisplayType = function(person){ person.imageDisplayType = !person.imageDisplayType }
const isSelectedPerson = (id) => {
return selectedPersonList.value.some(item => item.id === id)
}
// 剔除人员
const selectedPersonList = ref([]) // 批量操作,选中的图片
const deletePersonRecord = () => {
console.log('deletePersonRecord', selectedPersonList)
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
const unidList = selectedPersonList.value.map(item => item.unid)
const params = {
unid: unidList.join(','),
personUnid: '',
countdate: selectedPersonList.value[0].counttime
}
clusterResultApi.updateRecognition(params).then(
(r) => {
if(r.msg_code==200){
ElMessage({
message: `剔除成功`,
type: 'success'
})
selectedPersonList.value = []
// 刷新列表
handleRefresh()
} else {
ElMessage({
message: `剔除失败`,
type: 'error'
})
}
}
)
}
// 删除人员
const deleteRealPersonRecord = () => {
console.log('deletePersonRecord', selectedPersonList)
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
const strIdList = selectedPersonList.value.map(item => item.id).join(',')
const params = {
id: strIdList,
}
clusterResultApi.deleteRecognition(params).then(
(r) => {
if(r.msg_code==200){
ElMessage({
message: `删除成功`,
type: 'success'
})
selectedPersonList.value = []
// 刷新列表
handleRefresh()
} else {
ElMessage({
message: `删除失败`,
type: 'error'
})
}
}
)
}
// 添加店员库
const addShopkeeper = () => {
console.log('addShopkeeper', selectedPersonList)
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
const strIdList = selectedPersonList.value.map(item => item.unid)
const rawData = toRaw(queryForm)
const params = {
unids: strIdList,
mallId:selectedPersonList.value[0].mall_id,
countdate:formatDate(rawData.date) + ' 00:00:00',
}
clusterResultApi.addDataToShopkeeper(params).then(
(r) => {
if(r.msg_code==200){
ElMessage({
message: `添加成功`,
type: 'success'
})
selectedPersonList.value = []
// 刷新列表
handleRefresh()
} else {
ElMessage({
message: `添加失败`,
type: 'error'
})
}
}
)
}
// 添加人员库
const personnelPoolRef = ref();
const addPersonnelPool = () => {
console.log('addPersonnelPool')
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
personnelPoolRef.value.initDialog(selectedPersonList.value);
}
// 移动人员
const personGroupMoverRef = ref();
const movePersonRecord = () => {
console.log('movePersonRecord')
if (selectedPersonList.value.length < 1) {
ElMessage({
message: `至少选择一条数据`,
type: 'error'
})
return
}
personGroupMoverRef.value.initDialog(selectedPersonList.value);
}
// 查询组
const personGroupDialogRef = ref();
const searchPersonInfoByGroup = function(data) {
console.log('searchPersonInfoByGroup', data)
/* let parmas = {
// person_unid: currobj.value.person_unid,
pic_type: data.picType,
endTime:formatDate(rawData.date) + ' ' + rawData.endTime,
startTime:formatDate(rawData.date) + ' ' + rawData.startTime,
countdate:formatDate(rawData.date),
pic_id:currobj.value.id,
ip:window._baseImgUrl,
plaza_id:currobj.value.mall_id
} */
// singleImgComparisonRef.value.initDialog(parmas);
personGroupDialogRef.value.initDialog(data);
}
const downloadFile = function(url) {
window.open(url)
}
const downloadTrajectoryFile = function(url){
window.open(url)
}
const handleClick = function(data, event){
console.log('handleClick', data, event)
// 多选。只有设置为多选状态的组,才可以选中
if (isMultipleOperation.value) {
// 如果已选中,则取消。若未选中,则增加
const isExist = selectedPersonList.value.find(item => item.id === data.id)
if (isExist) {
selectedPersonList.value = selectedPersonList.value.filter(item => item.id !== data.id)
} else {
selectedPersonList.value.push(data)
}
} else {
currentItemId.value = data.id
currobj.value = data;
// 清空多选
selectedPersonList.value = []
}
}
const checkChange = function(data){
console.log(data)
}
const expandChange = function(data){
dataList.value.forEach(item=>{
if (data.person_unid == item.person_unid) {
item.expand = !item.expand
}
})
}
// 特征对比
const comparativeFun = function(){
const rawData = toRaw(queryForm)
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
let parmas = {
mall_id:currobj.value.mall_id,
picType:rawData.picType,
pic_id:currobj.value.id,
countdate:formatDate(rawData.date),
dataList:[]
}
dataList.value.forEach(item=>{
if (item.checked && item.checked == true) {
parmas.dataList.push(item)
}
})
if(parmas.dataList && parmas.dataList.length > 0){
DetailDialogComparisonRef.value.initDialog(currobj.value,parmas);
}else{
ElMessage(
{
message: `请选择聚类图片`,
type: 'warning'
}
)
return
}
}
//单张特征对比
const singleComparativeFun = function(){
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
const rawData = toRaw(queryForm)
console.log(queryForm)
console.log(rawData)
let parmas = {
person_unid:currobj.value.person_unid,
pic_type:rawData.picType,
endTime:formatDate(rawData.date) + ' ' + rawData.endTime,
startTime:formatDate(rawData.date) + ' ' + rawData.startTime,
countdate:formatDate(rawData.date),
pic_id:currobj.value.id,
ip:window._baseImgUrl,
plaza_id:currobj.value.mall_id
}
singleImgComparisonRef.value.initDialog(parmas);
}
// 店员特征对比
const clerkComparativeFun = function(){
const rawData = toRaw(queryForm)
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片进行对比`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
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 personnelComparativeFun = function(){
const rawData = toRaw(queryForm)
if(!currobj.value.id){
ElMessage(
{
message: `请选择图片进行对比`,
type: 'warning'
}
)
return
}
if(!currobj.value.picture_url){
ElMessage(
{
message: `该图片没有特征,请选择有效的图片`,
type: 'warning'
}
)
return
}
let parmas = {
plaza_id:currobj.value.mall_id,
pic_type:rawData.picType,
pic_id:currobj.value.id,
ip:window._baseImgUrl,
countdate:formatDate(rawData.date)
}
personnelDialogRef.value.initDialog(currobj.value,parmas);
}
const contentHeight = ref(0)
const __main = function() {
getAccountList()
contentHeight.value = window.innerHeight - 280
}
__main()
return {
// scalar
isLoading,
pageNum,
pageSize,
total,
currentItemId,
currobj,
// sequence
accountList,
plazaList,
personTypeList,
zoneList,
gateList,
pagedTableDataList,
dataList,
contentHeight,
// mapping
queryForm,
// function
onPageNumChange,
onPageSizeChange,
onAccountChange,
onPlazaChange,
onZoneChange,
confirmSearch,
formatDirection,
downloadFile,
getPagedList,
handleClick,
comparativeFun,
checkChange,
expandChange,
updatePersonInfoByGroup,
toggleImageDisplayType,
uploadGroupData,
deletePersonRecord,
addPersonnelPool,
movePersonRecord,
searchPersonInfoByGroup,
isSelectedPerson,
selectedPersonList,
clerkComparativeFun,
personnelComparativeFun,
singleComparativeFun,
personTypeStr,
formatGender,
downloadTrajectoryFile,
clickSearch,
handleRefresh,
handleEditorRefresh,
currentSearchCondition,
// ref
// imgModelRef,
DetailDialogRef,
personnelDialogRef,
personGroupDialogRef,
personGroupEditorRef,
uploadGroupDataEditorRef,
DetailDialogComparisonRef,
singleImgComparisonRef,
personGroupMoverRef,
personnelPoolRef,
reqPersonType,
isMultipleOperation,
handleMutipleOperation,
mutipleOperationText,
deleteRealPersonRecord,
addShopkeeper,
childAdultAgeOptions,
childAdultOptions,
formatChildAdult
}
}
}
</script>
<style lang="less" scoped>
@import "./ClusterResult";
.actived{
border: 3px solid #1890ff;
}
.actived-red {
border: 3px solid red;
}
.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;
}
.multiple-operation {
display: inline-block;
margin-left: 20px;
}
</style>
<style type="text/css">
.label-width-wu .ant-form-item-label{
width: 84px!important;
}
</style>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!