Commit a2828121 by 李金轩

ljx

1 parent b7a09e5f
Showing 64 changed files with 768 additions and 2459 deletions
// window._serverHost = '36.112.68.214:12101'
window._serverHost = '101.201.36.180:12100' // 正式
// window._serverHost = '101.201.36.180:12200' // 测试
window._baseUrl = `http://${window._serverHost}`
window._serverHost2 = '101.201.36.180:12111'
// window._serverHost2 ='192.168.1.195:12101'
window._baseUrl2 = `http://${window._serverHost2}`
window._baseUrl = window.location.hostname === 'localhost' ? 'http://store.keliuyun.com:9998' : ''
const log = console.log.bind(console)
......@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>logo.png">
<title>数据标注平台</title>
<title>tools</title>
<script src="<%= BASE_URL %>config.js"></script>
</head>
<body>
......
<template>
<div id="app">
<router-view></router-view>
</div>
<a-locale-provider :locale="zh_CN">
<div id="app">
<router-view></router-view>
</div>
</a-locale-provider>
</template>
<script>
import zh_CN from 'ant-design-vue/lib/locale-provider/zh_CN'
export default {
data() {
return {
zh_CN,
}
},
}
</script>
<style lang="less">
html, body, #app, .el-container {
width: 100%;
......
......@@ -10,51 +10,31 @@ const axiosInstance = axios.create(
}
)
const axiosInstance2 = axios.create(
{
baseURL: window._baseUrl2,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
)
// 请求拦截器
axiosInstance.interceptors.request.use(
config => {
config.headers.token = Cookies.get('token')
return config
}
)
// 响应拦截器
axiosInstance.interceptors.response.use(
(r) => {
const responseData = r.data
const message = responseData.msg
if (message === '当前会话未登录')
if (window.location.hostname === 'localhost')
{
router.push(
'/'
)
config.headers.Authorization = '68e02bdc-5815-44e1-94c2-8a01d3270c4c'
}
else
{
return responseData
const authorization = Cookies.get('atoken')
if (authorization !== undefined)
{
config.headers.Authorization = authorization
}
}
},
(e) => {
const responseData = e.response
return responseData
return config
}
)
axiosInstance2.interceptors.response.use(
// 响应拦截器
axiosInstance.interceptors.response.use(
(r) => {
const responseData = r.data
return responseData
},
(e) => {
......@@ -64,4 +44,4 @@ axiosInstance2.interceptors.response.use(
}
)
export {axiosInstance, axiosInstance2}
export default axiosInstance
......@@ -2,77 +2,32 @@ import {createRouter, createWebHashHistory} from 'vue-router'
const menuRoute = [
{
path: '/DataLabel',
path: '/Main',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: 'ImagePackage',
component: () => import("@/views/DataLabel/ImagePackage/ImagePackage.vue"),
path: 'DataRerun',
component: () => import("@/views/DataRerun/DataRerun.vue"),
},
{
path: 'PeopleLabel',
component: () => import("@/views/DataLabel/PeopleLabel/PeopleLabel.vue"),
path: 'DataRepair',
component: () => import("@/views/DataRepair/DataRepair.vue"),
},
{
path: 'Labeling',
component: () => import("@/views/DataLabel/Labeling/Labeling.vue"),
path: 'FeatureReExtract',
component: () => import("@/views/FeatureReExtract/FeatureReExtract.vue"),
},
{
path: 'SubmitQualityInspect',
component: () => import("@/views/DataLabel/SubmitQualityInspect/SubmitQualityInspect.vue"),
path: 'FeatureLibraryRebuild',
component: () => import("@/views/FeatureLibraryRebuild/FeatureLibraryRebuild.vue"),
},
{
path: 'LabelWorkbook',
component: () => import("@/views/DataLabel/LabelWorkbook/LabelWorkbook.vue"),
path: 'PeopleReContrast',
component: () => import("@/views/PeopleReContrast/PeopleReContrast.vue"),
},
]
},
{
path: '/QualityInspect',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: 'QualityInspectExamine',
component: () => import("@/views/QualityInspect/QualityInspectExamine/QualityInspectExamine.vue"),
},
]
},
{
path: '/Project',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: 'ProjectManagement',
component: () => import("@/views/Project/ProjectManagement/ProjectManagement.vue"),
},
]
},
{
path: '/BackgroundManagement',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: 'OutsourceCompany',
component: () => import("@/views/BackgroundManagement/OutsourceCompany/OutsourceCompany.vue"),
},
{
path: 'UserManagement',
component: () => import("@/views/BackgroundManagement/UserManagement/UserManagement.vue"),
},
]
},
{
path: '/DataClean',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: 'DataClean',
component: () => import("@/views/DataClean/DataClean/DataClean.vue"),
},
{
path: 'CleanManagement',
component: () => import("@/views/DataClean/CleanManagement/CleanManagement.vue"),
path: 'SnapshotCluster',
component: () => import("@/views/SnapshotCluster/SnapshotCluster.vue"),
},
]
},
......@@ -81,75 +36,11 @@ const menuRoute = [
const route = [
{
path: '/',
redirect: '/Login',
},
{
path: '/Test',
component: () => import("@/views/Test/Test.vue"),
},
{
path: '/Login',
component: () => import("@/views/Login/Login.vue"),
},
{
path: '/ClassAmongClean',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: '',
component: () => import("@/views/ClassAmongClean/ClassAmongClean.vue"),
},
]
},
{
path: '/ClassInsideClean',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: '',
component: () => import("@/views/ClassInsideClean/ClassInsideClean.vue"),
},
]
},
{
path: '/JudgePeople',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: '',
component: () => import("@/views/JudgePeople/JudgePeople.vue"),
},
]
},
{
path: '/ClassInsideJudgePerson',
component: () => import("@/views/Main/Main.vue"),
children: [
{
path: '',
component: () => import("@/views/ClassInsideJudgePerson/ClassInsideJudgePerson.vue"),
},
]
redirect: '/Main/DataRerun',
},
...menuRoute
]
export const getUrlByTitle = function(title) {
const map = {
"标注": '/DataLabel/ImagePackage',
"提交质检": '/DataLabel/SubmitQualityInspect',
"标注工作薄": '/DataLabel/LabelWorkbook',
"质检审核": '/QualityInspect/QualityInspectExamine',
"项目管理": '/Project/ProjectManagement',
"外包公司": '/BackgroundManagement/OutsourceCompany',
"用户管理": '/BackgroundManagement/UserManagement',
"数据清洗": '/DataClean/DataClean',
"清洗管理": '/DataClean/CleanManagement',
}
return map[title]
}
const router = createRouter(
{
history: createWebHashHistory(),
......
import {axiosInstance} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class OutsourceCompanyApi {
getOutsourceCompanyList() {
return axiosInstance.request(
{
method: 'GET',
url: '/accounts',
}
)
}
addOutsourceCompany(data) {
return axiosInstance.request(
{
method: 'POST',
url: '/accounts',
data: filterEmptyValueInObject(
{
name: data.name,
managerId: data.managerId,
description: data.description,
createUser: localStorage.getItem('currentUserId'),
}
)
}
)
}
editOutsourceCompany(id, data) {
return axiosInstance.request(
{
method: 'POST',
url: `/accounts/${id}`,
data: data
}
)
}
deleteOutsourceCompany(id) {
return axiosInstance.request(
{
method: 'DELETE',
url: `/accounts/${id}`,
}
)
}
prohibitOutsourceCompany(id) {
return axiosInstance.request(
{
method: 'POST',
url: `/accounts/${id}`,
data: {
status: 0
}
}
)
}
resumeOutsourceCompany(id) {
return axiosInstance.request(
{
method: 'POST',
url: `/accounts/${id}`,
data: {
status: 1
}
}
)
}
getUserList() {
return axiosInstance.request(
{
method: 'GET',
url: `/users`,
}
)
}
}
const outsourceCompanyApi = new OutsourceCompanyApi()
export default outsourceCompanyApi
import {axiosInstance} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject, } from "@/PublicUtil/PublicUtil"
class UserApi {
getUserList() {
return axiosInstance.request(
{
method: 'GET',
url: '/users',
}
)
}
addUser(data) {
return axiosInstance.request(
{
method: 'POST',
url: '/users',
data: filterEmptyValueInObject(
{
username: data.username,
name: data.name,
password: data.password,
accountId: data.accountId,
type: data.type,
createUser: localStorage.getItem('currentUserId'),
}
)
}
)
}
editUser(id, data) {
return axiosInstance.request(
{
method: 'POST',
url: `/users/${id}`,
data: data
}
)
}
deleteUser(id) {
return axiosInstance.request(
{
method: 'DELETE',
url: `/users/${id}`,
}
)
}
}
const userApi = new UserApi()
export default userApi
import {axiosInstance2} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject,} from "@/PublicUtil/PublicUtil"
class DataCleanApi {
getDataCleanList(data) {
return axiosInstance2.request(
{
method: 'GET',
url: '/clean2/list',
params: filterEmptyValueInObject(
{
packId: data.packId,
status: data.status,
pageNum: data.pageNum,
pageSize: data.pageSize,
}
)
}
)
}
getCleanAmongResult(data) {
return axiosInstance2.request(
{
method: 'GET',
url: '/clean2/getClean2',
params: filterEmptyValueInObject(
{
id: data.id,
packId: data.packId,
}
)
}
)
}
}
const dataCleanApi = new DataCleanApi()
export default dataCleanApi
import {axiosInstance2} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject, getFormDataByObject} from "@/PublicUtil/PublicUtil"
class ClassInsideCleanApi {
getClassInsideCleanList(data) {
return axiosInstance2.request(
{
method: 'GET',
url: '/clean1-person/list',
params: filterEmptyValueInObject(
{
packId: data.packId,
status: data.status,
pageNum: data.pageNum,
pageSize: data.pageSize,
}
)
}
)
}
getCleanInsideResult(data) {
return axiosInstance2.request(
{
method: 'GET',
url: '/clean1-person/getClean1',
params: {
personId: data.personId,
packId: data.packId,
}
}
)
}
split(data) {
return axiosInstance2.request(
{
method: 'POST',
url: '/clean1-person/split',
data: getFormDataByObject(
{
personId: data.personId,
packId: data.packId,
picIds: data.picIds,
}
)
}
)
}
}
const classInsideCleanApi = new ClassInsideCleanApi()
export default classInsideCleanApi
.Labeling {
background: white;
}
.el-main {
margin: 0;
padding: 0;
}
.el-header {
padding: 0;
}
.isSelected {
border: 2px solid #4487f7 !important;
}
.isFolderSelected {
background: aquamarine;
}
.isSelected:after {
bottom: 0px;
right: 0px;
content: "";
position: absolute;
width: 0;
height: 0;
border-bottom: 42px solid #4487f7;
border-left: 42px solid transparent;
}
.isSelected:before {
content: '';
position: absolute;
width: 14px;
height: 8px;
background: transparent;
bottom: 12px;
right: 5px;
border: 2px solid white;
border-top: none;
border-right: none;
-webkit-transform: rotate(-55deg);
-ms-transform: rotate(-55deg);
transform: rotate(-55deg);
z-index: 9;
}
.single-image-parent {
//display: inline-block;
position: relative;
border: 2px solid white;
text-align: center;
}
.single-image {
height: 300px;
width: 100%;
cursor: pointer;
}
.right-image-folder-list {
//border-radius: 10px;
margin: 10px 0;
}
.container {
margin: 0;
padding: 0;
overflow: auto;
}
.clearfix::after {
content: '';
display: block;
clear: both;
}
.empty {
float: left;
}
.single-image-parent {
position: relative;
border: 2px solid white;
text-align: center;
}
.single-image {
height: 300px;
width: 100%;
cursor: pointer;
}
.el-row {
height: 326px !important;
}
.isSelected {
border: 2px solid #4487f7 !important;
}
.isSelected:after {
bottom: 0px;
right: 0px;
content: "";
position: absolute;
width: 0;
height: 0;
border-bottom: 42px solid #4487f7;
border-left: 42px solid transparent;
}
.isSelected:before {
content: '';
position: absolute;
width: 14px;
height: 8px;
background: transparent;
bottom: 12px;
right: 5px;
border: 2px solid white;
border-top: none;
border-right: none;
-webkit-transform: rotate(-55deg);
-ms-transform: rotate(-55deg);
transform: rotate(-55deg);
z-index: 9;
}
<template>
<div class="container clearfix" ref="containerRef" style="height: 100%">
<div class="empty" :style="{ height: emptyHeight }"></div>
<div :style="{ transform: `translateY(${translateY})` }">
<el-row v-for="row in showedList">
<el-col :span="8" v-for="item in row" @click="selectImage(item.unid)">
<div v-bind:class="{ 'isSelected': item.isSelected}"
class="single-image-parent flex-vertical-center"
@contextmenu.prevent=""
@click.right="previewImage(getImageUrl(item.picId))">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image">
</el-image>
</div>
<div>
{{ item.createTime }} {{ getDirectionTitle(item.direction) }}
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import {computed, onMounted, ref} from 'vue'
import {getImageUrl, getPagedList, previewImage} from '@/PublicUtil/PublicUtil'
export default {
props: {
dataList: {
default: []
},
},
setup(props, {emit}) {
const dataList = props.dataList
const containerRef = ref()
const itemHeight = 326
const start = ref(0)
const translateY = ref(0)
const showedList = computed(
() => {
return dataList.slice(start.value, start.value + 3)
}
)
const emptyHeight = itemHeight * (dataList.length + 1)
const getDirectionTitle = function(v) {
switch (v)
{
case 1:
{
return '进'
}
case -1:
{
return '出'
}
default:
{
break
}
}
}
const selectImage = function(unid) {
emit('imageClick', unid)
}
onMounted(
() => {
containerRef.value.addEventListener(
'scroll',
(event) => {
const {scrollTop} = event.target
start.value = Math.floor(scrollTop / itemHeight)
translateY.value = scrollTop + 'px'
}
)
}
)
return {
containerRef,
translateY,
itemHeight: itemHeight + 'px',
emptyHeight: emptyHeight + 'px',
// sequence
showedList,
// function
selectImage,
getDirectionTitle,
getImageUrl,
previewImage,
}
}
}
</script>
<style lang="less" scoped>
@import "./VirtualList";
</style>
import {axiosInstance2} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject, getFormDataByObject,} from "@/PublicUtil/PublicUtil"
import {getImagePackageMap} from '@/Request/DictionaryRequest'
class DataCleanApi {
getDataCleanList(data) {
return axiosInstance2.request(
{
method: 'GET',
url: '/pack-clean/list',
params: {
pageNum: data.pageNum,
pageSize: data.pageSize,
}
}
)
}
addDataClean(data) {
return axiosInstance2.request(
{
method: 'POST',
url: '/pack-clean',
params: filterEmptyValueInObject(
{
packId: data.packId,
name: data.name,
}
)
}
)
}
cleanInsideClean(data) {
return axiosInstance2.request(
{
method: 'POST',
url: `/cleaning/clean1`,
data: getFormDataByObject(
{
taskId: data.taskId,
score: data.score,
percent: data.percent,
}
)
}
)
}
cleanAmongClean(data) {
return axiosInstance2.request(
{
method: 'POST',
url: `/cleaning/clean2`,
data: getFormDataByObject(
{
taskId: data.taskId,
score: data.score,
percent: data.percent,
maxNum: data.maxNum,
}
)
}
)
}
completeClean(taskId) {
return axiosInstance2.request(
{
method: 'POST',
url: `/cleaning/completeClean`,
data: getFormDataByObject(
{
taskId: taskId
}
)
}
)
}
getImagePackageMap() {
return axiosInstance2.request(
{
method: 'GET',
url: `/pack-clean/listPacks`,
}
)
}
}
const dataCleanApi = new DataCleanApi()
export default dataCleanApi
import {axiosInstance2} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject, getFormDataByObject} from "@/PublicUtil/PublicUtil"
import {getImagePackageMap} from '@/Request/DictionaryRequest'
class DataCleanApi {
getDataCleanList(data) {
return axiosInstance2.request(
{
method: 'GET',
url: '/pack-clean/list',
params: {
pageNum: data.pageNum,
pageSize: data.pageSize,
}
}
)
}
addDataClean(data) {
return axiosInstance2.request(
{
method: 'POST',
url: '/pack-clean',
params: filterEmptyValueInObject(
{
packId: data.packId,
name: data.name,
}
)
}
)
}
clean(cleanType, taskId) {
return axiosInstance2.request(
{
method: 'POST',
url: `/cleaning/clean${cleanType}`,
data: getFormDataByObject(
{
taskId: taskId
}
)
}
)
}
completeClean(taskId) {
return axiosInstance2.request(
{
method: 'POST',
url: `/cleaning/completeClean`,
data: getFormDataByObject(
{
taskId: taskId
}
)
}
)
}
getImagePackageMap() {
return axiosInstance2.request(
{
method: 'GET',
url: `/pack-clean/listPacks`,
}
)
}
}
const dataCleanApi = new DataCleanApi()
export default dataCleanApi
.ImagePackage {
background: white;
.image-package {
background: white;
}
.name {
height: 100%;
font-size: 17px;
font-weight: bold;
font-family: PingFangSC-Medium, PingFang SC;
color: rgba(0, 0, 0, 0.8);
}
}
<template>
<a-layout class="ImagePackage">
<el-form :model="queryImagePackageForm" :inline="true" size="small">
<el-form-item label="公司:">
<el-select v-model="queryImagePackageForm.companyId" @change="onSelectCompanyInQuery" style="width: 100%">
<el-option v-for="(name, value) in companyMap" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目:">
<el-select v-model="queryImagePackageForm.projectId" style="width: 100%">
<el-option v-for="(value, name) in projectMapInQuery" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="图包:">-->
<!-- <el-select v-model="queryImagePackageForm.imagePackageId" style="width: 100%">-->
<!-- <el-option v-for="(value, key) in imagePackageMapInQuery" :label="value" :value="key"></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item>
<el-button @click="confirmQueryImagePackage" type="primary">查询</el-button>
<el-button @click="reset">重置</el-button>
</el-form-item>
</el-form>
<el-row v-for="(row, index) in pagedTableData" v-loading="isLoading">
<el-col :span="6" v-for="(item, index) in row" style="cursor: pointer;">
<div class="image-package">
<el-row @click="gotoPeopleLabel(item.id)">
<el-col :span="4">
<img :src="require('./image/imagePackage.svg')"/>
</el-col>
<el-col :span="20">
<div class="name">
<div class="flex-vertical-center flex-horizontal-center">
图包: {{ item?.name }}
</div>
<div class="flex-vertical-center flex-horizontal-center">
公司: {{ companyMap[item?.task?.accountId] }}
</div>
<div class="flex-vertical-center flex-horizontal-center">
项目: {{ item?.task?.name }}
</div>
</div>
</el-col>
</el-row>
<a-button v-if="isDownloadShowed" @click="downloadCompletedImages(item.id)" type="link">下载</a-button>
</div>
</el-col>
</el-row>
</a-layout>
</template>
<script>
import {computed, defineComponent, reactive, ref, toRaw, toRefs, watch} from 'vue'
import {useRouter} from 'vue-router'
import peopleLabelApi from '@/views/DataLabel/PeopleLabel/PeopleLabelApi'
import {cloneObject, getKeyByValueInObject} from '@/PublicUtil/PublicUtil'
import imagePackageApi from '@/views/DataLabel/ImagePackage/ImagePackageApi'
import Cookies from 'js-cookie'
import {getCompanyMap} from '@/Request/DictionaryRequest'
import projectApi from '@/views/Project/ProjectManagement/ProjectManagementApi'
export default defineComponent(
{
setup() {
const router = useRouter()
const peopleFolderList = ref([])
const imagePackageList = ref([])
const isLoading = ref(false)
const isDownloadShowed = ref(localStorage.getItem('currentUserType') === '0')
const pagedTableData = computed(
() => {
let baseArray = imagePackageList.value
let len = baseArray.length
let n = 4 //每行显示4个
let lineNum = len % n === 0 ? len / n : Math.floor((len / n) + 1)
let result = []
for (let i = 0; i < lineNum; i++)
{
// slice() 方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象。且原始数组不会被修改。
let temp = baseArray.slice(i * n, i * n + n)
result.push(temp)
}
return result
}
)
// mapping
const queryImagePackageForm = reactive(
{
companyId: '',
projectId: '',
imagePackageId: '',
}
)
const companyMap = reactive({})
const projectMapInQuery = reactive({})
const imagePackageMapInQuery = reactive({})
const downloadCompletedImages = function(packId) {
window.open(
` ${window._baseUrl}/reid/downloadLabeledPicAsZip`
+
`?packId=${packId}&token=${Cookies.get('token')}`
)
}
const gotoPeopleLabel = function(packId) {
router.push(
{
path: '/DataLabel/PeopleLabel',
query: {
packId: packId,
pageNum: 1,
}
}
)
}
const reset = function() {
for (let key in queryImagePackageForm)
{
queryImagePackageForm[key] = ''
}
}
const getProjectMapByCompanyId = async function(companyId) {
const {data} = await projectApi.getProjectList(companyId)
let map = {}
for (const project of data)
{
map[project.name] = project.id
}
return map
}
//
// const getFloorMapByprojectId = function(projectId) {
// }
const onSelectCompanyInQuery = async function(companyId) {
queryImagePackageForm.projectId = ''
queryImagePackageForm.imagePackageId = ''
const map = await getProjectMapByCompanyId(parseInt(companyId))
cloneObject(projectMapInQuery, map)
}
// const onSelectProjectInQuery = function(projectId) {
// queryImagePackageForm.imagePackageId = ''
// cloneObject(imagePackageMapInQuery, getFloorMapByprojectId(parseInt(projectId)))
// }
const confirmQueryImagePackage = function() {
isLoading.value = true
const rawData = toRaw(queryImagePackageForm)
const data = {
companyId: rawData.companyId,
projectId: rawData.projectId,
}
imagePackageApi.getImagePackageList(data).then(
(r) => {
isLoading.value = false
imagePackageList.value = r.data
}
)
}
const initialize = function() {
confirmQueryImagePackage()
getCompanyMap(companyMap)
}
initialize()
return {
// scalar
isLoading,
isDownloadShowed,
// sequence
peopleFolderList,
pagedTableData,
// mapping
queryImagePackageForm,
companyMap,
projectMapInQuery,
imagePackageMapInQuery,
// function
reset,
onSelectCompanyInQuery,
// onSelectProjectInQuery,
gotoPeopleLabel,
downloadCompletedImages,
confirmQueryImagePackage,
getKeyByValueInObject,
}
},
}
)
</script>
<style lang="less" scoped>
@import "./ImagePackage.less";
</style>
import {axiosInstance} from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class ImagePackageApi {
getImagePackageList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/packs`,
params: filterEmptyValueInObject(
{
accountId: data?.companyId,
taskId: data?.projectId,
type: 1,
}
)
}
)
}
}
const imagePackageApi = new ImagePackageApi()
export default imagePackageApi
<?xml version="1.0" encoding="UTF-8"?>
<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>wenjianjia</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1.1数据标注_人行标注" transform="translate(-336.000000, -259.000000)" fill-rule="nonzero">
<g id="文件夹1" transform="translate(312.000000, 218.000000)">
<g id="wenjianjia" transform="translate(24.000000, 41.000000)">
<path d="M0,30 C0,46.5685425 13.4314575,60 30,60 C46.5685425,60 60,46.5685425 60,30 C60,13.4314575 46.5685425,0 30,0 C13.4314575,0 0,13.4314575 0,30 Z" id="路径" fill="#6F9AFF" opacity="0.15072955"></path>
<g id="编组" transform="translate(15.000000, 18.000000)">
<path d="M27.1107989,6.385231 L12.5367594,6.385231 C11.7221508,6.38536458 10.9992431,5.86424184 10.7433631,5.09242471 L10.6299287,4.75960069 C10.2020168,3.47433429 8.99689379,2.60744721 7.63980047,2.60869565 L3.15347366,2.60869565 C1.41326149,2.60994376 0.00250167591,4.01684454 0,5.75354456 L0,20.8551524 C0.00250047866,22.591411 1.41257011,23.9981295 3.15233935,24 L27.1085303,24 C28.8482995,23.9981294 30.2583691,22.591411 30.2608696,20.8551524 L30.2608696,9.53460681 C30.2583705,7.79878957 28.8489908,6.39225327 27.1096646,6.38975926" id="路径" fill="#6F9AFF"></path>
<path d="M25.5546678,0.000567944867 L7.43673523,0.000567944867 C7.20640021,-0.00923103112 6.98925259,0.108368919 6.87117036,0.306859121 C6.75308814,0.505349323 6.75308814,0.752763455 6.87117036,0.951253656 C6.98925259,1.14974386 7.20640021,1.26734381 7.43673523,1.25754483 C9.32670802,1.25669534 11.004785,2.46932433 11.601388,4.26704849 L11.7142513,4.60646621 C11.8000054,4.86347742 12.0398243,5.03695174 12.310169,5.03752666 L26.8085782,5.03752666 C27.1795791,5.04216465 27.5483824,5.09541437 27.9056087,5.1959216 C28.0942468,5.24662743 28.2956815,5.20639846 28.4505319,5.0870938 C28.6053823,4.96778914 28.6959924,4.78301189 28.6956522,4.58723251 L28.6956522,3.15036426 C28.6937851,1.41467951 27.2906327,0.00809561432 25.5591823,0.00622491766" id="路径" fill="#4076F7"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<template>
<el-form :model="exportDataForm" :inline="true" size="small">
<el-form-item label="公司:">
<el-select v-model="exportDataForm.companyId" @change="onSelectCompanyInQuery">
<el-option v-for="(name, value) in companyMap" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目:">
<el-select v-model="exportDataForm.projectId" @change="onSelectProjectInQuery">
<el-option v-for="(value, name) in projectMapInQuery" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="图包:">
<el-select v-model="exportDataForm.imagePackageId">
<el-option v-for="(value, name) in imagePackageMapInQuery" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="日期:">
<el-date-picker v-model="exportDataForm.time" type="daterange"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button @click="exportData" :loading="isLoading" type="primary">导出数据</el-button>
</el-form-item>
</el-form>
</template>
<script>
import {computed, defineComponent, reactive, ref, toRaw, toRefs, watch} from 'vue'
import imagePackageApi from '@/views/DataLabel/ImagePackage/ImagePackageApi'
import {cloneObject, filterEmptyValueInObject, formatDate} from '@/PublicUtil/PublicUtil'
import Cookies from 'js-cookie'
import projectApi from '@/views/Project/ProjectManagement/ProjectManagementApi'
import {getCompanyMap} from '@/Request/DictionaryRequest'
export default defineComponent(
{
setup() {
// scalar
const isLoading = ref()
// sequence
const imagePackageList = ref([])
// mapping
const exportDataForm = reactive(
{
companyId: '',
projectId: '',
imagePackageId: '',
start: '',
end: '',
time: '',
}
)
const companyMap = reactive({})
const projectMapInQuery = reactive({})
const imagePackageMapInQuery = reactive({})
// function
const exportData = function() {
const rawData = toRaw(exportDataForm)
const data = filterEmptyValueInObject(
{
accountId: rawData.companyId,
taskId: rawData.projectId,
packId: rawData.imagePackageId,
start: formatDate(rawData.time[0]),
end: formatDate(rawData.time[1]),
}
)
let url = ''
for (const key in data)
{
const value = data[key]
const t = `${key}` + '=' + value
url += '&' + t
}
window.open(
` ${window._baseUrl}/reid/export`
+
`?token=${Cookies.get('token') + url}`
)
}
const getProjectMapByCompanyId = async function(companyId) {
const {data} = await projectApi.getProjectList(companyId)
let map = {}
for (const project of data)
{
map[project.name] = project.id
}
return map
}
const getImagePackageMapByProjectId = async function(projectId) {
const {data} = await imagePackageApi.getImagePackageList(
{
projectId: projectId
}
)
let map = {}
for (const imagePackage of data)
{
map[imagePackage.name] = imagePackage.id
}
return map
}
const onSelectCompanyInQuery = async function(companyId) {
exportDataForm.projectId = ''
exportDataForm.imagePackageId = ''
const map = await getProjectMapByCompanyId(parseInt(companyId))
cloneObject(projectMapInQuery, map)
}
const onSelectProjectInQuery = async function(projectId) {
exportDataForm.imagePackageId = ''
const map = await getImagePackageMapByProjectId(parseInt(projectId))
cloneObject(imagePackageMapInQuery, map)
}
const initialize = function() {
getCompanyMap(companyMap)
}
initialize()
return {
// scalar
isLoading,
// sequence
imagePackageList,
// mapping
exportDataForm,
companyMap,
projectMapInQuery,
imagePackageMapInQuery,
// function
onSelectCompanyInQuery,
onSelectProjectInQuery,
exportData,
}
},
}
)
</script>
<style lang="less" scoped>
@import "./LabelWorkbook.less";
</style>
.Labeling {
background: white;
}
.el-main {
margin: 0;
padding: 0;
}
.el-header {
padding: 0;
}
.isFolderSelected {
background: aquamarine;
}
.isSelected {
border: 2px solid #4487f7 !important;
}
.isSelected:after {
bottom: 0px;
right: 0px;
content: "";
position: absolute;
width: 0;
height: 0;
border-bottom: 42px solid #4487f7;
border-left: 42px solid transparent;
}
.isSelected:before {
content: '';
position: absolute;
width: 14px;
height: 8px;
background: transparent;
bottom: 12px;
right: 5px;
border: 2px solid white;
border-top: none;
border-right: none;
-webkit-transform: rotate(-55deg);
-ms-transform: rotate(-55deg);
transform: rotate(-55deg);
z-index: 9;
}
.single-image-parent {
position: relative;
border: 2px solid white;
text-align: center;
}
.single-image {
height: 300px;
width: 100%;
cursor: pointer;
}
.right-image-folder-list {
//border-radius: 10px;
margin: 10px 0;
}
import {axiosInstance} from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject, getCountGte, getCountLte} from "@/PublicUtil/PublicUtil"
class LabelingApi {
getPeopleImageList(packId, personUnid) {
return axiosInstance.request(
{
method: 'GET',
url: `/subTasks`,
params: {
packId: packId,
personUnid: personUnid,
sortName: 'create_time'
},
}
)
}
getSimilarPeopleImageFolderList(picIdArr, folderNum, packId, minutes, currentPersonUnid) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/getSimilarPerson`,
params: {
picIdArr: picIdArr,
size: folderNum,
packId: packId,
timeInterval: minutes,
currentPerson: currentPersonUnid,
},
}
)
}
completeLabel(personUnid, packId) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/setPure`,
params: {
personUnid: personUnid,
packId: packId,
},
}
)
}
mergeImagesAsNewPerson(picIdArr, packId) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/mergeAsNewPerson`,
params: {
picIdArr: picIdArr,
packId: packId,
},
}
)
}
mergeMultiplePersonsAsNewPerson(personUnidArr, packId, currentPersonUnid) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/mergePerson`,
params: {
personUnidArr: personUnidArr,
packId: packId,
currentPerson: currentPersonUnid,
},
}
)
}
mergeMultipleImagesToOnePerson(picIdArr, personUnid, packId, currentPersonUnid) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/mergeTo`,
params: {
picIdArr: picIdArr,
personUnid: personUnid,
packId: packId,
currentPerson: currentPersonUnid,
},
}
)
}
deleteImages(picIdArr, packId) {
return axiosInstance.request(
{
method: 'DELETE',
url: `/reid/deletePic`,
params: {
picIdArr: picIdArr,
packId: packId,
},
}
)
}
recycle(personUnid, subTaskIdArr, packId) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/recovery`,
params: filterEmptyValueInObject(
{
personUnid: personUnid,
subTaskIdArr: subTaskIdArr,
packId: packId,
}
),
}
)
}
highQualityExtract(personUnid, subTaskIdArr, packId, currentPersonUnid) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/mergeAndTodo`,
params: filterEmptyValueInObject(
{
personUnidArr: personUnid,
subTaskIdArr: subTaskIdArr,
packId: packId,
currentPerson: currentPersonUnid,
}
),
}
)
}
lowQualityExtract(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/mergeAndLowQuality`,
params: filterEmptyValueInObject(
{
personUnidArr: data.personUnidArr,
subTaskIdArr: data.subTaskIdArr,
packId: data.packId,
currentPerson: data.currentPerson,
}
),
}
)
}
exitLabeling(personUnid, packId) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/exitLabeling`,
params: {
personUnid: personUnid,
packId: packId,
},
}
)
}
getPreviousPerson(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/getOtherPeople`,
params: filterEmptyValueInObject(
{
personUnid: data.personUnid,
packId: data.packId,
type: 1,
status: data.status,
countGTE: getCountGte(),
countLTE: getCountLte(),
}
),
}
)
}
getNextPerson(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/getOtherPeople`,
params: filterEmptyValueInObject(
{
personUnid: data.personUnid,
packId: data.packId,
type: 0,
status: data.status,
countGTE: getCountGte(),
countLTE: getCountLte(),
}
),
}
)
}
}
const labelingApi = new LabelingApi()
export default labelingApi
.container {
margin: 0;
padding: 0;
overflow: auto;
}
.clearfix::after {
content: '';
display: block;
clear: both;
}
.empty {
float: left;
}
.single-image-parent {
position: relative;
border: 2px solid white;
text-align: center;
}
.single-image {
height: 300px;
width: 100%;
cursor: pointer;
}
.el-row {
height: 326px !important;
}
.isSelected {
border: 2px solid #4487f7 !important;
}
.isSelected:after {
bottom: 0px;
right: 0px;
content: "";
position: absolute;
width: 0;
height: 0;
border-bottom: 42px solid #4487f7;
border-left: 42px solid transparent;
}
.isSelected:before {
content: '';
position: absolute;
width: 14px;
height: 8px;
background: transparent;
bottom: 12px;
right: 5px;
border: 2px solid white;
border-top: none;
border-right: none;
-webkit-transform: rotate(-55deg);
-ms-transform: rotate(-55deg);
transform: rotate(-55deg);
z-index: 9;
}
<template>
<div class="container clearfix" ref="containerRef" style="height: 100%">
<div class="empty" :style="{ height: emptyHeight }"></div>
<div :style="{ transform: `translateY(${translateY})` }">
<el-row v-for="row in showedList">
<el-col :span="8" v-for="item in row" @click="selectImage(item.id)">
<div v-bind:class="{ 'isSelected': item.isSelected}"
class="single-image-parent flex-vertical-center"
@contextmenu.prevent=""
@click.right="previewImage(getImageUrl(item.picId))">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image">
</el-image>
</div>
<div>
{{ item.createTime }} {{ getDirectionTitle(item.direction) }}
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import {computed, onMounted, ref} from 'vue'
import {getImageUrl, getPagedList, previewImage} from '@/PublicUtil/PublicUtil'
export default {
props: {
dataList: {
default: []
},
},
setup(props, {emit}) {
const dataList = props.dataList
const containerRef = ref()
const itemHeight = 326
const start = ref(0)
const translateY = ref(0)
const showedList = computed(
() => {
return dataList.slice(start.value, start.value + 3)
}
)
const emptyHeight = itemHeight * (dataList.length + 1)
const getDirectionTitle = function(v) {
switch (v)
{
case 1:
{
return '进'
}
case -1:
{
return '出'
}
default:
{
break
}
}
}
const selectImage = function(id) {
emit('imageClick', id)
}
onMounted(
() => {
containerRef.value.addEventListener(
'scroll',
(event) => {
const {scrollTop} = event.target
start.value = Math.floor(scrollTop / itemHeight)
translateY.value = scrollTop + 'px'
}
)
}
)
return {
containerRef,
translateY,
itemHeight: itemHeight + 'px',
emptyHeight: emptyHeight + 'px',
// sequence
showedList,
// function
selectImage,
getDirectionTitle,
getImageUrl,
previewImage,
}
}
}
</script>
<style lang="less" scoped>
@import "./VirtualList";
</style>
.PeopleLabel {
background: white;
}
.folder {
width: 400px;
cursor: pointer;
}
.folder-title {
color: white;
padding: 0 0 0 20px;
}
.folder-body {
//padding: 0 0 0 20px;
margin: 0 auto;
}
.folder-cover-image {
//width: 200px;
text-align: center
//padding: 0 0 0 20px;
}
.column-title-font {
padding: 0 0 0 18px
}
import {axiosInstance} from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class PeopleLabelApi {
getPeopleImageFolderList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/getPeople`,
params: filterEmptyValueInObject(
{
packId: data.packId,
status: data.status,
annotatorId: data.annotatorId,
page: data.pageNum,
size: data.pageSize,
countGTE: data.countGTE,
countLTE: data.countLTE,
}
),
}
)
}
enterLabeling(personUnid, packId) {
return axiosInstance.request(
{
method: 'GET',
url: `/reid/labeling`,
params: filterEmptyValueInObject(
{
personUnid: personUnid,
packId: packId,
}
),
}
)
}
searchFolder(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/subTasks`,
params: filterEmptyValueInObject(
{
personUnid_like: '%' + data.personUnid_like + '%',
packId: data.packId,
group: 'true',
sortName: 'create_time'
}
),
}
)
}
submitReview(data) {
return axiosInstance.request(
{
method: 'POST',
url: `/reid/verify`,
data: filterEmptyValueInObject(
{
personUnidArr: data.personUnidArr,
status: data.status,
}
),
}
)
}
}
const peopleLabelApi = new PeopleLabelApi()
export default peopleLabelApi
.ProjectManagement {
.el-header {
display: flex;
margin: 0 20px;
align-items: center;
background: #FFFFFF;
}
.el-main {
margin: 20px;
padding: 20px;
background: #FFFFFF;
.project-form {
padding: 40px 40px 0 20px
}
}
}
<template>
<el-container class="QualityInspectManagement">
<el-header height="50px">
<div>
<span class="title-text">提交质检</span>
</div>
</el-header>
<el-main>
<el-menu mode="horizontal" @select="handleMenuSelect" :default-active="'1'">
<el-menu-item :index="'1'">
待标注
</el-menu-item>
<el-menu-item :index="'5'">
审核驳回
</el-menu-item>
<el-menu-item :index="'6'">
审核通过
</el-menu-item>
</el-menu>
<el-table :data="qualityInspectList" v-loading="isLoading">
<el-table-column prop="taskName" label="taskName" align="center"></el-table-column>
<el-table-column prop="packName" label="packName" align="center"></el-table-column>
<el-table-column prop="accountId" label="所属公司" align="center">
<template #default="scope">
{{ companyMap[scope.row.accountId] }}
</template>
</el-table-column>
<el-table-column prop="count" label="count" align="center"></el-table-column>
<el-table-column prop="finishCount" label="finishCount" align="center"></el-table-column>
<el-table-column prop="toBeLabeledCount" label="toBeLabeledCount" align="center"></el-table-column>
<el-table-column prop="operation" label="操作" align="center">
<template #default="scope">
<el-button @click="submitInspect(scope.row.packId)" type="text">提交审核</el-button>
<el-button @click="viewDetails(scope.row.packId)" type="text">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-main>
</el-container>
</template>
<script>
import {reactive, ref, toRaw,} from "vue"
import {
filterEmptyValueInObject, getKeyByValueInObject,
resetForm
} from "@/PublicUtil/PublicUtil"
import qualityInspectApi from './SubmitQualityInspectApi'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getCompanyMap} from '@/Request/DictionaryRequest'
import {useRouter} from 'vue-router'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const router = useRouter()
let selectedMenuIndex = '1'
const qualityInspectList = ref([])
// computed
// mapping
const companyMap = reactive({})
// function
const handlePageNumChange = function(num) {
pageNum.value = num
getQualityInspectList()
}
const handlePageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getQualityInspectList()
}
const handleMenuSelect = function(index) {
selectedMenuIndex = index
getQualityInspectList()
}
const viewDetails = function(packId) {
router.push(
{
path: '/DataLabel/PeopleLabel',
query: {
packId: packId,
pageNum: 1,
}
}
)
}
const submitInspect = function(id) {
qualityInspectApi.submitInspect(id).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
}
)
}
const getQualityInspectList = function() {
isLoading.value = true
qualityInspectApi.getQualityInspectList(selectedMenuIndex).then(
({data}) => {
isLoading.value = false
qualityInspectList.value = data
// formatPaginatedTableData(
// qualityInspectList,
// data,
// total,
// )
}
)
}
const initialize = function() {
getQualityInspectList()
getCompanyMap(companyMap)
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
qualityInspectList,
// mapping
companyMap,
// function
handlePageNumChange,
handlePageSizeChange,
getKeyByValueInObject,
handleMenuSelect,
viewDetails,
submitInspect,
}
},
}
</script>
<style lang="less" scoped>
@import "./SubmitQualityInspect.less";
</style>
import {axiosInstance} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject,} from "@/PublicUtil/PublicUtil"
class QualityInspectApi {
getQualityInspectList(status) {
return axiosInstance.request(
{
method: 'GET',
url: '/packs/info',
params: filterEmptyValueInObject(
{
accountId: localStorage.getItem('currentAccountId'),
status: status,
}
)
}
)
}
submitInspect(id) {
return axiosInstance.request(
{
method: 'POST',
url: `/packs/${id}`,
data: {
status: 1
}
}
)
}
}
const qualityInspectApi = new QualityInspectApi()
export default qualityInspectApi
<template>
<h2>{{ options.length }} Items</h2>
<a-select
v-model:value="value"
mode="multiple"
style="width: 100%"
placeholder="Please select"
:options="options"
/>
</template>
<script>
import {defineComponent, reactive} from 'vue'
const options = []
for (let i = 0; i < 100000; i++)
{
const value = `${i.toString(36)}${i}`
options.push({
value,
disabled: i === 10,
})
}
export default defineComponent({
setup() {
const state = reactive({
options,
value: ['a10', 'c12'],
})
return state
},
})
</script>
<template>
<a-select v-model:value="value" mode="multiple" style="width: 200px">
<a-select-option value="jack">全选</a-select-option>
<a-select-option value="jack">Jack</a-select-option>
<a-select-option value="lucy">Lucy</a-select-option>
<a-select-option value="disabled">Disabled</a-select-option>
<a-select-option value="Yiminghe">yiminghe</a-select-option>
</a-select>
</template>
<script>
import {reactive, ref} from 'vue'
import dataRerunApi from '@/views/DataRerun/DataRerunApi'
export default {
setup: function() {
// scalar
const value = ref()
// sequence
// mapping
const accountMap = reactive({})
// function
const getAccountList = function() {
dataRerunApi.getAccountList().then(
(r) => {
for (const item of r)
{
accountMap[item.id] = item.name
}
}
)
}
const initialize = function() {
getAccountList()
}
initialize()
return {
// scalar
value,
// sequence
// mapping
// function
}
}
}
</script>
<style scoped>
</style>
import axiosInstance from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class DataRerunApi {
getAccountList(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/accounts`,
}
)
}
}
const dataRerunApi = new DataRerunApi()
export default dataRerunApi
<template>
</template>
<script>
export default {
name: "FeatureLibraryRebuild"
}
</script>
<style scoped>
</style>
<template>
</template>
<script>
export default {
name: "FeatureRe-extract"
}
</script>
<style scoped>
</style>
import {axiosInstance2} from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject, getFormDataByObject, } from "@/PublicUtil/PublicUtil"
class JudgePeopleApi {
notSamePerson(id) {
return axiosInstance2.request(
{
method: 'POST',
url: `/clean2/${id}`,
data: getFormDataByObject(
{
same: 0
}
)
}
)
}
samePerson(id) {
return axiosInstance2.request(
{
method: 'POST',
url: `/clean2/${id}`,
data: getFormDataByObject(
{
same: 1
}
)
}
)
}
}
const judgePeopleApi = new JudgePeopleApi()
export default judgePeopleApi
.Labeling {
background: white;
}
.el-main {
margin: 0;
padding: 0;
}
.el-header {
padding: 0;
}
.isSelected {
border: 2px solid #4487f7 !important;
}
.isFolderSelected {
background: aquamarine;
}
.isSelected:after {
bottom: 0px;
right: 0px;
content: "";
position: absolute;
width: 0;
height: 0;
border-bottom: 42px solid #4487f7;
border-left: 42px solid transparent;
}
.isSelected:before {
content: '';
position: absolute;
width: 14px;
height: 8px;
background: transparent;
bottom: 12px;
right: 5px;
border: 2px solid white;
border-top: none;
border-right: none;
-webkit-transform: rotate(-55deg);
-ms-transform: rotate(-55deg);
transform: rotate(-55deg);
z-index: 9;
}
.single-image-parent {
//display: inline-block;
position: relative;
border: 2px solid white;
text-align: center;
}
.single-image {
height: 300px;
width: 100%;
}
.right-image-folder-list {
//border-radius: 10px;
margin: 10px 0;
}
<template>
<el-container>
<el-aside width="200px">
<div class="logo"/>
<el-menu :router="true" :default-openeds="getOpeneds()">
<el-submenu v-for="(list, name ,index) in accessedMenu" :index="index" :key="index">
<template #title>
<span>{{ name }}</span>
</template>
<el-menu-item-group>
<el-menu-item v-for="(title, i) in list" :index="getUrlByTitle(title)" :key="i">
{{
title
}}
</el-menu-item>
</el-menu-item-group>
</el-submenu>
<!-- <el-submenu :index="100">-->
<!-- <template #title>-->
<!-- <span> 数据清洗 </span>-->
<!-- </template>-->
<!-- <el-menu-item-group>-->
<!-- <el-menu-item :index="'/DataClean/DataClean'">-->
<!-- 数据清洗-->
<!-- </el-menu-item>-->
<!-- </el-menu-item-group>-->
<!-- </el-submenu>-->
</el-menu>
<el-aside style="background: black" width="200px">
<a-menu mode="inline" theme="dark" @click="onClick">
<a-menu-item :key="'/Main/DataRerun'">
<span>数据重跑</span>
</a-menu-item>
<a-menu-item :key="'/Main/DataRepair'">
<span>数据修补</span>
</a-menu-item>
<a-menu-item :key="'/Main/FeatureReExtract'">
<span>特征重提</span>
</a-menu-item>
<a-menu-item :key="'/Main/FeatureLibraryRebuild'">
<span>特征库重建</span>
</a-menu-item>
<a-menu-item :key="'/Main/PeopleReContrast'">
<span>人员重新比对</span>
</a-menu-item>
<a-menu-item :key="'/Main/SnapshotCluster'">
<span>抓拍聚类</span>
</a-menu-item>
</a-menu>
</el-aside>
<el-container>
<el-header style="background: #fff; padding: 0;height: 35px">
<div style="display: flex; justify-content: flex-end;">
<el-button @click="logout">退出登录</el-button>
</div>
</el-header>
<el-main>
<router-view :key="$route.fullPath"></router-view>
</el-main>
</el-container>
<el-main>
<router-view :key="$route.fullPath"></router-view>
</el-main>
</el-container>
</template>
<script>
import {defineComponent, ref} from 'vue'
import {useRouter} from 'vue-router'
import {getAccessedMenu,} from '@/PublicUtil/PublicUtil'
import {getUrlByTitle} from '@/router'
import loginApi from '@/views/Login/LoginApi'
export default defineComponent({
setup() {
const accessedMenu = getAccessedMenu()
const router = useRouter()
const goto = function(path) {
......@@ -65,11 +48,9 @@ export default defineComponent({
return result
}
const logout = function() {
loginApi.logout().then(
() => {
router.push('/')
}
const onClick = function({key}) {
router.push(
`${key}`
)
}
......@@ -83,12 +64,10 @@ export default defineComponent({
// scalar
// sequence
// mapping
accessedMenu,
// function
goto,
getUrlByTitle,
getOpeneds,
logout,
onClick,
}
},
})
......
<template>
</template>
<script>
export default {
name: "PeopleReContrast"
}
</script>
<style scoped>
</style>
import {axiosInstance} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject, } from "@/PublicUtil/PublicUtil"
class ProjectApi {
getProjectList(id) {
return axiosInstance.request(
{
method: 'GET',
url: '/tasks',
params: filterEmptyValueInObject(
{
accountId: id
}
)
}
)
}
addProject(data) {
return axiosInstance.request(
{
method: 'POST',
url: '/tasks',
data: filterEmptyValueInObject(
{
name: data.name,
description: data.description,
type: 1,
labelType: 0,
createUser: localStorage.getItem('currentUserId'),
}
)
}
)
}
editProject(id, data) {
return axiosInstance.request(
{
method: 'POST',
url: `/tasks/${id}`,
data: data
}
)
}
finishProject(id) {
return axiosInstance.request(
{
method: 'POST',
url: `/tasks/${id}`,
data: {
status: 0
}
}
)
}
startProject(id) {
return axiosInstance.request(
{
method: 'POST',
url: `/tasks/${id}`,
data: {
status: 1
}
}
)
}
getUsedBatchList(id) {
return axiosInstance.request(
{
method: 'GET',
url: `/packs`,
params: filterEmptyValueInObject(
{
taskId: id
}
)
}
)
}
getUnusedBatchList() {
return axiosInstance.request(
{
method: 'GET',
url: `/packs`,
params: filterEmptyValueInObject(
{
taskId_null: 'true'
}
)
}
)
}
distributeBatch(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/packs/assignTo`,
params: filterEmptyValueInObject(
{
taskId: data.taskId,
packIds: data.packIds,
}
)
}
)
}
cancelDistributeBatch(data) {
return axiosInstance.request(
{
method: 'GET',
url: `/packs/assignTo`,
params: filterEmptyValueInObject(
{
packIds: data.packIds,
}
)
}
)
}
}
const projectApi = new ProjectApi()
export default projectApi
<template>
<el-container class="QualityInspectManagement">
<el-header height="50px">
<div>
<span class="title-text">质检审核</span>
</div>
</el-header>
<el-main>
<el-menu mode="horizontal" @select="handleMenuSelect" :default-active="'1'">
<el-menu-item :index="'1'">
待标注
</el-menu-item>
</el-menu>
<el-table :data="qualityInspectList" v-loading="isLoading">
<el-table-column prop="taskName" label="taskName" align="center"></el-table-column>
<el-table-column prop="packName" label="packName" align="center"></el-table-column>
<el-table-column prop="accountId" label="所属公司" align="center">
<template #default="scope">
{{ companyMap[scope.row.accountId] }}
</template>
</el-table-column>
<el-table-column prop="count" label="count" align="center"></el-table-column>
<el-table-column prop="finishCount" label="finishCount" align="center"></el-table-column>
<el-table-column prop="toBeLabeledCount" label="toBeLabeledCount" align="center"></el-table-column>
<el-table-column prop="operation" label="操作" align="center">
<template #default="scope">
<el-button @click="viewDetails(scope.row.packId)" type="text">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-main>
</el-container>
</template>
<script>
import {reactive, ref, toRaw,} from "vue"
import {
filterEmptyValueInObject, getKeyByValueInObject,
resetForm
} from "@/PublicUtil/PublicUtil"
import qualityInspectApi from './QualityInspectExamineApi'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getCompanyMap} from '@/Request/DictionaryRequest'
import {useRouter} from 'vue-router'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const router = useRouter()
let selectedMenuIndex = '1'
const qualityInspectList = ref([])
// computed
// mapping
const companyMap = reactive({})
// function
const handlePageNumChange = function(num) {
pageNum.value = num
getQualityInspectList()
}
const handlePageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getQualityInspectList()
}
const handleMenuSelect = function(index) {
selectedMenuIndex = index
getQualityInspectList()
}
const viewDetails = function(packId) {
router.push(
{
path: '/DataLabel/PeopleLabel',
query: {
packId: packId,
isReviewAccessed: true,
pageNum: 1,
}
}
)
}
const submitInspect = function(id) {
qualityInspectApi.submitInspect(id).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
}
)
}
const getQualityInspectList = function() {
isLoading.value = true
qualityInspectApi.getQualityInspectList(selectedMenuIndex).then(
({data}) => {
isLoading.value = false
qualityInspectList.value = data
// formatPaginatedTableData(
// qualityInspectList,
// data,
// total,
// )
}
)
}
const initialize = function() {
getQualityInspectList()
getCompanyMap(companyMap)
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
qualityInspectList,
// mapping
companyMap,
// function
handlePageNumChange,
handlePageSizeChange,
getKeyByValueInObject,
handleMenuSelect,
viewDetails,
submitInspect,
}
},
}
</script>
<style lang="less" scoped>
@import "./QualityInspectExamine.less";
</style>
import {axiosInstance} from '@/Request/PublicAxiosInstance'
import {filterEmptyValueInObject,} from "@/PublicUtil/PublicUtil"
class QualityInspectApi {
getQualityInspectList(status) {
return axiosInstance.request(
{
method: 'GET',
url: '/packs/info',
params: filterEmptyValueInObject(
{
accountId: localStorage.getItem('currentAccountId'),
status: status,
}
)
}
)
}
submitInspect(id) {
return axiosInstance.request(
{
method: 'POST',
url: `/packs/${id}`,
data: {
status: 1
}
}
)
}
}
const qualityInspectApi = new QualityInspectApi()
export default qualityInspectApi
<template>
<a-form :model="queryAlarmEventForm" layout="inline">
<a-form-item label="平台:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="集团:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="广场:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="出入类型:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="门店:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="监控点:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="方向:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="抓怕类型:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="人员类型:">
<a-select v-model:value="queryAlarmEventForm.buildingId" style="width: 200px">
<a-select-option value="shanghai">Zone one</a-select-option>
<a-select-option value="beijing">Zone two</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="选择日期:">
<a-range-picker
v-model:value="queryAlarmEventForm.time"
:show-time="{ format: 'HH:mm' }"
format="YYYY-MM-DD HH:mm"
/>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="onSubmit">查询</a-button>
</a-form-item>
</a-form>
<el-row>
<el-col :span="6">
<div>
<div class="folder-body">
<div class="folder-cover-image">
<el-image :fit="'contain'"
style="height: 300px;">
</el-image>
</div>
</div>
</div>
</el-col>
</el-row>
<el-pagination @current-change="onPageNumChange"
@size-change="onPageSizeChange"
:current-page="pageNum"
:page-size="pageSize"
:total="total"
:page-sizes="[12, 24, 36, 48]"
layout="total, sizes, prev, pager, next, jumper"
style="text-align:center"
>
</el-pagination>
</template>
<script>
import {reactive, ref} from 'vue'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(12)
const total = ref()
const queryAlarmEventForm = reactive(
{
projectId: 'jack',
buildingId: '',
floorId: '',
monitorPointId: '',
deviceNo: '',
startDate: '',
endDate: '',
sjlx: '',
typeId: '',
urgency: '',
time: '',
}
)
// function
const onPageNumChange = function(num) {
pageNum.value = num
getPeopleImageFolderList()
}
const onPageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getPeopleImageFolderList()
}
const getPeopleImageFolderList = function() {
}
const onSubmit = function() {
}
return {
// scalar
pageNum,
pageSize,
total,
// sequence
// mapping
queryAlarmEventForm,
// function
onPageNumChange,
onPageSizeChange,
onSubmit,
}
}
}
</script>
<style scoped>
</style>
<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>
<template>
<a-form :model="queryAlarmEventForm" layout="inline">
<a-form-item label="集团:">
<a-select v-model:value="queryAlarmEventForm.account_id"
style="width: 200px"
mode="multiple"
:maxTagCount="1"
@change="onAccountChange"
>
<a-select-option
v-for="item in accountList"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="广场:">
<a-select v-model:value="queryAlarmEventForm.plaza_id"
style="width: 200px"
mode="multiple"
:maxTagCount="1"
@change="onPlazaChange"
>
<a-select-option
v-for="item in plazaList"
:value="item.id">
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="出入类型:">
<a-select v-model:value="queryAlarmEventForm.type" style="width: 200px">
<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>
</a-form-item>
<a-form-item label="区域信息:">
<a-select v-model:value="queryAlarmEventForm.zone_id"
style="width: 200px"
mode="multiple"
:maxTagCount="1"
@change="onZoneChange">
<a-select-option
v-for="item in zoneList"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="监控点:">
<a-select v-model:value="queryAlarmEventForm.gate_id"
style="width: 200px"
mode="multiple"
:maxTagCount="1">
<a-select-option
v-for="item in gateList"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="方向:">
<a-select v-model:value="queryAlarmEventForm.direction" style="width: 200px">
<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="抓怕类型:">
<a-select v-model:value="queryAlarmEventForm.picType" style="width: 200px">
<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="人员类型:">
<a-select v-model:value="queryAlarmEventForm.personType" style="width: 200px">
<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="选择日期:">
<a-range-picker
v-model:value="queryAlarmEventForm.time"
:show-time="{ format: 'HH:mm' }"
format="YYYY-MM-DD HH:mm"
/>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="onSubmit">查询</a-button>
</a-form-item>
</a-form>
<el-pagination @current-change="onPageNumChange"
@size-change="onPageSizeChange"
:current-page="pageNum"
:page-size="pageSize"
:total="total"
:page-sizes="[12, 24, 36, 48]"
layout="total, sizes, prev, pager, next, jumper"
style="text-align:center"
>
</el-pagination>
</template>
<script>
import {reactive, ref} from 'vue'
import snapshotRecordApi from '@/views/SnapshotCluster/SnapshotRecord/SnapshotRecordApi'
import {isArray} from '@/PublicUtil/Judgment'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(12)
const total = ref()
const accountList = ref([])
const plazaList = ref([])
const zoneList = ref([])
const gateList = ref([])
const queryAlarmEventForm = reactive(
{
account_id: [],
plaza_id: [],
zone_id: [],
gate_id: [],
type: 0,
direction: '',
picType: '',
personType: '',
startTime: '',
endTime: '',
time: '',
}
)
// function
const onPageNumChange = function(num) {
pageNum.value = num
getPeopleImageFolderList()
}
const onPageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getPeopleImageFolderList()
}
const getPeopleImageFolderList = function() {
}
const onSubmit = function() {
}
const onAccountChange = function() {
getPlazaList()
getZoneList()
getGateList()
}
const onPlazaChange = function() {
getZoneList()
getGateList()
}
const onZoneChange = function() {
getGateList()
}
const getPlazaList = function() {
queryAlarmEventForm.plaza_id = []
plazaList.value = []
snapshotRecordApi.getPlazaList(
{
account_id: queryAlarmEventForm.account_id.toString()
}
).then(
(r) => {
if (isArray(r))
{
plazaList.value = r
}
}
)
}
const getZoneList = function() {
queryAlarmEventForm.zone_id = []
zoneList.value = []
snapshotRecordApi.getZoneList(
{
account_id: queryAlarmEventForm.account_id.toString(),
plaza_id: queryAlarmEventForm.plaza_id.toString(),
}
).then(
(r) => {
if (isArray(r))
{
zoneList.value = r
}
}
)
}
const getGateList = function() {
queryAlarmEventForm.gate_id = []
gateList.value = []
snapshotRecordApi.getGateList(
{
account_id: queryAlarmEventForm.account_id.toString(),
plaza_id: queryAlarmEventForm.plaza_id.toString(),
zone_id: queryAlarmEventForm.zone_id.toString(),
type: queryAlarmEventForm.type,
}
).then(
(r) => {
if (isArray(r.data))
{
gateList.value = r.data
}
}
)
}
const getAccountList = function() {
queryAlarmEventForm.account_id = []
accountList.value = []
snapshotRecordApi.getAccountList().then(
(r) => {
if (isArray(r))
{
accountList.value = r
}
}
)
}
const initialize = function() {
getAccountList()
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
// sequence
// mapping
accountList,
plazaList,
zoneList,
gateList,
queryAlarmEventForm,
// function
onPageNumChange,
onPageSizeChange,
onSubmit,
onAccountChange,
onPlazaChange,
onZoneChange,
}
}
}
</script>
<style scoped>
</style>
import axiosInstance from "@/Request/PublicAxiosInstance"
import {filterEmptyValueInObject} from "@/PublicUtil/PublicUtil"
class SnapshotRecordApi {
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,
},
)
}
)
}
}
const snapshotRecordApi = new SnapshotRecordApi()
export default snapshotRecordApi
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!