Commit eb251211 by 李君

记录增加删除

1 parent 4c5642f8
window._serverHost = ['localhost', '192.168.1.168'].includes(window.location.hostname) ? 'mall.keliuyun.com' : window.location.host window._serverHost = ['localhost', '192.168.1.134'].includes(window.location.hostname) ? '117.133.143.116:33333' : window.location.host
window._baseUrl = ['localhost', '192.168.1.168'].includes(window.location.hostname) ? 'https://mall.keliuyun.com//tool/' : `${window.location.origin}/btool/` window._baseUrl = ['localhost', '192.168.1.134'].includes(window.location.hostname) ? 'http://117.133.143.116:33333/tool/' : `${window.location.origin}/btool/`
window._baseImgUrl = ['localhost', '192.168.1.168'].includes(window.location.hostname) ? 'https://mall.keliuyun.com/images/' : `${window.location.origin}/images/` window._baseImgUrl = ['localhost', '192.168.1.134'].includes(window.location.hostname) ? 'http://117.133.143.116:33333/images/' : `${window.location.origin}/images/`
window._socketUrl = ['localhost', '192.168.1.168'].includes(window.location.hostname) ? `wss://${window._serverHost}/btool/` : `wss://${window._serverHost}/btool/` window._socketUrl = ['localhost', '192.168.1.134'].includes(window.location.hostname) ? `wss://${window._serverHost}/btool/` : `wss://${window._serverHost}/btool/`
const log = console.log.bind(console) const log = console.log.bind(console)
\ No newline at end of file \ No newline at end of file
...@@ -4,7 +4,7 @@ import Cookies from "js-cookie" ...@@ -4,7 +4,7 @@ import Cookies from "js-cookie"
import {getTimestampString} from "@/PublicUtil/PublicUtil" import {getTimestampString} from "@/PublicUtil/PublicUtil"
import {ElMessage} from 'element-plus' import {ElMessage} from 'element-plus'
// 创建 axios 的一个实例 // 创建 axios 的一个实例
let baseURL = ['localhost', '192.168.1.28'].includes(window.location.hostname) ? '' : window._baseUrl let baseURL = ['localhost', '192.168.1.134'].includes(window.location.hostname) ? '' : window._baseUrl
const axiosInstance = axios.create( const axiosInstance = axios.create(
{ {
baseURL: baseURL, baseURL: baseURL,
...@@ -14,14 +14,14 @@ const axiosInstance = axios.create( ...@@ -14,14 +14,14 @@ const axiosInstance = axios.create(
// 请求拦截器 // 请求拦截器
axiosInstance.interceptors.request.use( axiosInstance.interceptors.request.use(
config => { config => {
// Cookies.set('atoken','8367538e-7bb0-4f9e-984e-d01aba8e70bd') Cookies.set('atoken','8246b767-9f23-47ac-bf2c-ef0ddfe8d629')
if(!Cookies.get('atoken')){ if(!Cookies.get('atoken')){
ElMessage({ ElMessage({
message: `登录过期,请重新登录`, message: `登录过期,请重新登录`,
type: 'warning' type: 'warning'
}) })
setTimeout(()=>{ setTimeout(()=>{
let url = ['localhost', '192.168.1.28'].includes(window.location.hostname) ? 'https://store.keliuyun.com/' : window.location.origin let url = ['localhost', '192.168.1.134'].includes(window.location.hostname) ? 'https://store.keliuyun.com/' : window.location.origin
// if(url.includes('36.112.68.214')){ // if(url.includes('36.112.68.214')){
// url = 'http://36.112.68.214:33333/' // url = 'http://36.112.68.214:33333/'
// } // }
...@@ -45,7 +45,7 @@ axiosInstance.interceptors.response.use( ...@@ -45,7 +45,7 @@ axiosInstance.interceptors.response.use(
type: 'warning' type: 'warning'
}) })
setTimeout(()=>{ setTimeout(()=>{
let url = ['localhost', '192.168.1.28'].includes(window.location.hostname) ? 'https://store.keliuyun.com/' : window.location.origin let url = ['localhost', '192.168.1.134'].includes(window.location.hostname) ? 'https://store.keliuyun.com/' : window.location.origin
// if(url.includes('36.112.68.214')){ // if(url.includes('36.112.68.214')){
// url = 'http://36.112.68.214:33333/' // url = 'http://36.112.68.214:33333/'
// } // }
......
...@@ -30,6 +30,10 @@ const menuRoute = [ ...@@ -30,6 +30,10 @@ const menuRoute = [
component: () => import("@/views/SnapshotCluster/SnapshotCluster.vue"), component: () => import("@/views/SnapshotCluster/SnapshotCluster.vue"),
}, },
{ {
path: 'SnapshotCluster1',
component: () => import("@/views/SnapshotCluster1/SnapshotCluster.vue"),
},
{
path: 'EquipmentTimeErrorVerification', path: 'EquipmentTimeErrorVerification',
component: () => import("@/views/EquipmentTimeErrorVerification/EquipmentTimeErrorVerification.vue"), component: () => import("@/views/EquipmentTimeErrorVerification/EquipmentTimeErrorVerification.vue"),
}, },
......
...@@ -115,6 +115,12 @@ ...@@ -115,6 +115,12 @@
<span style="padding: 0 5px">停留时长检索</span> <span style="padding: 0 5px">停留时长检索</span>
</div> </div>
</a-menu-item> </a-menu-item>
<a-menu-item :key="'/Main/SnapshotCluster1'">
<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> </a-menu>
</el-aside> </el-aside>
<el-main> <el-main>
......
...@@ -77,6 +77,14 @@ class SnapshotRecordApi { ...@@ -77,6 +77,14 @@ class SnapshotRecordApi {
} }
) )
} }
delRecord(data) {
return axiosInstance.request(
{
method: 'DELETE',
url: `/faceRecognitions/${data.id}`,
}
)
}
} }
......
.single-image {
height: 300px;
width: 100%;
}
.direction{
font-weight: 900;
background-color: red;
color: white;
}
.direction1{
background-color: green;
}
.direction0{
background-color: orange;
}
import axiosInstance from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class ClusterResultApi {
getClusterResultList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/faceRecognitions/faceRecordGroup`,
params: filterEmptyValueInObject(
data
)
}
)
}
getAccountList() {
return axiosInstance.request(
{
method: 'GET',
url: `/accounts`,
}
)
}
getPlazaList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/malls`,
params: filterEmptyValueInObject(
{
accountIds: data.account_id
},
)
}
)
}
getZoneList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/zones/zoneList`,
params: filterEmptyValueInObject(
{
account_id: data.account_id,
plaza_id: data.plaza_id,
},
)
}
)
}
getGateList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/gates/gateByInfo`,
params: filterEmptyValueInObject(
{
account_id: data.account_id,
plaza_id: data.plaza_id,
zone_id: data.zone_id,
type: data.type,
},
)
}
)
}
getBodyPoint(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/feature/bodyPoint`,
params: filterEmptyValueInObject(
data
)
}
)
}
}
const clusterResultApi = new ClusterResultApi()
export default clusterResultApi
<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>
.single-image {
height: 300px;
width: 100%;
}
.direction{
font-weight: 900;
background-color: red;
color: white;
}
.direction1{
background-color: green;
}
.direction0{
background-color: orange;
}
import axiosInstance from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class SnapshotRecordApi {
getSnapshotRecordList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/faceRecognitions/faceRecord`,
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,
},
)
}
)
}
}
const snapshotRecordApi = new SnapshotRecordApi()
export default snapshotRecordApi
<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>
<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>
...@@ -58,7 +58,8 @@ module.exports = { ...@@ -58,7 +58,8 @@ module.exports = {
devServer: { devServer: {
proxy: { proxy: {
'/': { '/': {
target: 'https://mall.keliuyun.com/btool/', // target: 'https://mall.keliuyun.com/btool/',
target: 'http://117.133.143.116:33333/btool/',
changeOrigin: true changeOrigin: true
} }
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!