Commit a2828121 by 李金轩

ljx

1 parent b7a09e5f
Showing 64 changed files with 762 additions and 7140 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>
<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(),
......
<template>
<el-container class="OutsourceCompanyManagement">
<el-header height="50px">
<div>
<span class="title-text">外包公司</span>
</div>
</el-header>
<el-main>
<el-button type="primary" @click="addOutsourceCompany">新建</el-button>
<el-table :data="outsourceCompanyList" v-loading="isLoading">
<el-table-column prop="name" label="名称" align="center"></el-table-column>
<el-table-column prop="description" label="描述" align="center"></el-table-column>
<el-table-column prop="description" label="状态" align="center">
<template #default="scope">
{{ getStatusTitle(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="operation" label="操作" align="center">
<template #default="scope">
<el-button @click="prohibitOutsourceCompany(scope.row.id)" type="text">禁用</el-button>
<el-button @click="resumeOutsourceCompany(scope.row.id)" type="text">解禁</el-button>
<el-button @click="editOutsourceCompany(scope.row)" type="text">编辑</el-button>
<el-button @click="confirmDeleteOutsourceCompany(scope.row.id)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-drawer title="新建外包公司" v-model="addOutsourceCompanyVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="outsourceCompany-form">
<el-form :model="addOutsourceCompanyForm" :rules="rules" ref="ref_addOutsourceCompanyForm">
<el-form-item label="公司名称:" prop="outsourceCompanyName" :label-width="'120px'">
<el-input v-model.trim="addOutsourceCompanyForm.name"></el-input>
</el-form-item>
<el-form-item label="管理人:" prop="outsourceCompanyYear" :label-width="'120px'">
<el-select v-model="addOutsourceCompanyForm.managerId" style="width: 100%">
<el-option v-for="(value, name) in userNameIdMap" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="管理人电话:" prop="groupId" :label-width="'120px'">
<el-input v-model.trim="addOutsourceCompanyForm.description"></el-input>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="addOutsourceCompanyVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmAddOutsourceCompany">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<el-drawer title="编辑外包公司" v-model="editOutsourceCompanyVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="outsourceCompany-form">
<el-form :model="editOutsourceCompanyForm" :rules="rules" ref="ref_editOutsourceCompanyForm">
<el-form-item label="公司名称:" prop="outsourceCompanyName" :label-width="'120px'">
<el-input v-model.trim="editOutsourceCompanyForm.name"></el-input>
</el-form-item>
<el-form-item label="管理人:" prop="outsourceCompanyYear" :label-width="'120px'">
<el-select v-model="editOutsourceCompanyForm.managerId" style="width: 100%">
<el-option v-for="(value, name) in userNameIdMap" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="管理人电话:" prop="groupId" :label-width="'120px'">
<el-input v-model.trim="editOutsourceCompanyForm.description"></el-input>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="editOutsourceCompanyVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmEditOutsourceCompany">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
</el-main>
</el-container>
</template>
<script>
import {computed, onMounted, reactive, ref, toRaw, toRefs, watch} from "vue"
import {
filterEmptyValueInObject,
resetForm
} from "@/PublicUtil/PublicUtil"
import outsourceCompanyApi from './OutsourceCompanyApi'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import moment from "moment"
import {getUserNameIdMap} from '@/Request/DictionaryRequest'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const addOutsourceCompanyVisible = ref(false)
const editOutsourceCompanyVisible = ref(false)
const outsourceCompanyList = ref([])
const ref_addOutsourceCompanyForm = ref()
const ref_editOutsourceCompanyForm = ref()
// computed
// mapping
const rules = reactive(
{
// outsourceCompanyName: [
// {
// required: true,
// message: '请输入外包公司名称',
// },
// ],
// outsourceCompanyYear: [
// {
// type: 'date',
// required: true,
// message: '请输入建成年份',
// trigger: 'change'
// }
// ],
// groupId: [
// {
// required: true,
// message: '请选择集团',
// },
// ],
}
)
const userNameIdMap = reactive({})
const addOutsourceCompanyForm = reactive(
{
name: '', // 公司名
managerId: '', // 管理人Id
description: '', // 电话
}
)
const editOutsourceCompanyForm = reactive(
{
name: '', // 公司名
managerId: '', // 管理人Id
description: '', // 电话
id: '',
}
)
// function
const handlePageNumChange = function(num) {
pageNum.value = num
getOutsourceCompanyList()
}
const handlePageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getOutsourceCompanyList()
}
const confirmAddOutsourceCompany = function() {
ref_addOutsourceCompanyForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(addOutsourceCompanyForm)
const data = filterEmptyValueInObject(rawData)
outsourceCompanyApi.addOutsourceCompany(data).then(
(r) => {
addOutsourceCompanyVisible.value = false
const message = r.msg
ElMessage(`${message}`)
getOutsourceCompanyList()
}
)
}
}
)
}
const editOutsourceCompany = function(row) {
editOutsourceCompanyVisible.value = true
editOutsourceCompanyForm.id = row.id
editOutsourceCompanyForm.name = row.name
editOutsourceCompanyForm.managerId = row.managerId
editOutsourceCompanyForm.description = row.description
}
const confirmEditOutsourceCompany = function() {
ref_editOutsourceCompanyForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(editOutsourceCompanyForm)
const data = filterEmptyValueInObject(
{
name: rawData.name,
managerId: rawData.managerId,
description: rawData.description,
}
)
outsourceCompanyApi.editOutsourceCompany(rawData.id, data).then(
(r) => {
const message = r.msg
getOutsourceCompanyList()
ElMessage(`${message}`)
}
)
editOutsourceCompanyVisible.value = false
}
}
)
}
const confirmDeleteOutsourceCompany = function(id) {
ElMessageBox.confirm(
"删除后此外包公司相关数据全部都会消失,你确定要删除吗?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
outsourceCompanyApi.deleteOutsourceCompany(id).then(
(r) => {
const message = r.msg
getOutsourceCompanyList()
ElMessage(`${message}`)
}
)
}
)
}
const addOutsourceCompany = function() {
resetForm(addOutsourceCompanyForm)
addOutsourceCompanyVisible.value = true
}
const getOutsourceCompanyList = function() {
isLoading.value = true
outsourceCompanyApi.getOutsourceCompanyList().then(
({data}) => {
isLoading.value = false
outsourceCompanyList.value = data
log(444, data)
// formatPaginatedTableData(
// outsourceCompanyList,
// data,
// total,
// )
}
)
}
const getStatusTitle = function(status) {
switch (status)
{
case 0:
{
return '禁用中'
}
case 1:
{
return '使用中'
}
default:
{
break
}
}
}
const prohibitOutsourceCompany = function(id) {
ElMessageBox.confirm(
"确定要禁用该公司?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
outsourceCompanyApi.prohibitOutsourceCompany(id).then(
(r) => {
const message = r.msg
getOutsourceCompanyList()
ElMessage(`${message}`)
}
)
}
)
}
const resumeOutsourceCompany = function(id) {
ElMessageBox.confirm(
"确定要解禁该公司?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
outsourceCompanyApi.resumeOutsourceCompany(id).then(
(r) => {
const message = r.msg
getOutsourceCompanyList()
ElMessage(`${message}`)
}
)
}
)
}
const initialize = function() {
getOutsourceCompanyList()
getUserNameIdMap(userNameIdMap)
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
outsourceCompanyList,
ref_addOutsourceCompanyForm,
ref_editOutsourceCompanyForm,
addOutsourceCompanyVisible,
editOutsourceCompanyVisible,
// mapping
userNameIdMap,
addOutsourceCompanyForm,
editOutsourceCompanyForm,
rules,
// function
handlePageNumChange,
handlePageSizeChange,
addOutsourceCompany,
editOutsourceCompany,
confirmEditOutsourceCompany,
confirmAddOutsourceCompany,
confirmDeleteOutsourceCompany,
prohibitOutsourceCompany,
resumeOutsourceCompany,
getStatusTitle,
}
},
}
</script>
<style lang="less" scoped>
@import "./OutsourceCompany.less";
</style>
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
<template>
<el-container class="UserManagement">
<el-header height="50px">
<div>
<span class="title-text">用户管理</span>
</div>
</el-header>
<el-main>
<el-button type="primary" @click="addUser">新建</el-button>
<el-table :data="userList" v-loading="isLoading">
<el-table-column prop="name" label="用户名称" align="center"></el-table-column>
<el-table-column prop="username" label="账号" 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="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="operation" label="操作" align="center">
<template #default="scope">
<el-button @click="editUser(scope.row)" type="text">编辑
</el-button>
<el-button @click="confirmDeleteUser(scope.row.id)" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-drawer title="新建用户" v-model="addUserVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="user-form">
<el-form :model="addUserForm" :rules="rules" ref="ref_addUserForm">
<el-form-item label="用户名称:" prop="username" :label-width="'120px'">
<el-input v-model.trim="addUserForm.name"></el-input>
</el-form-item>
<el-form-item label="账号:" prop="name" :label-width="'120px'">
<el-input v-model.trim="addUserForm.username" style="width: 100%"></el-input>
</el-form-item>
<el-form-item label="密码:" prop="password" :label-width="'120px'">
<el-input v-model.trim="addUserForm.password"></el-input>
</el-form-item>
<el-form-item label="所属公司:" prop="accountId" :label-width="'120px'">
<el-select v-model="addUserForm.accountId" style="width: 100%">
<el-option v-for="(name, value) in companyMap" :label="name" :value="parseInt(value)"></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据权限管理:" prop="type" :label-width="'120px'">
<el-select v-model="addUserForm.type" style="width: 100%">
<el-option v-for="(value, name) in getCanCreateUsernameIdMap()" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="addUserVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmAddUser">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<el-drawer title="编辑用户" v-model="editUserVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="user-form">
<el-form :model="editUserForm" :rules="rules" ref="ref_editUserForm">
<el-form-item label="用户名称:" prop="username" :label-width="'120px'">
<el-input v-model.trim="editUserForm.name"></el-input>
</el-form-item>
<el-form-item label="账号:" prop="name" :label-width="'120px'">
<el-input v-model.trim="editUserForm.username" style="width: 100%"></el-input>
</el-form-item>
<el-form-item label="密码:" prop="password" :label-width="'120px'">
<el-input v-model.trim="editUserForm.password"></el-input>
</el-form-item>
<el-form-item label="所属公司:" prop="accountId" :label-width="'120px'">
<el-select v-model="editUserForm.accountId" style="width: 100%">
<el-option v-for="(name, value) in companyMap" :label="name" :value="parseInt(value)"></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据权限管理:" prop="type" :label-width="'120px'">
<el-select v-model="editUserForm.type" style="width: 100%">
<el-option v-for="(value, name) in getCanCreateUsernameIdMap()" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="editUserVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmEditUser">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
</el-main>
</el-container>
</template>
<script>
import {reactive, ref, toRaw,} from "vue"
import {
filterEmptyValueInObject, getKeyByValueInObject,
resetForm
} from "@/PublicUtil/PublicUtil"
import userApi from './UserManagementApi'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getCanCreateUsernameIdMap, getCompanyMap} from '@/Request/DictionaryRequest'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const addUserVisible = ref(false)
const editUserVisible = ref(false)
const userList = ref([])
const ref_addUserForm = ref()
const ref_editUserForm = ref()
// computed
// mapping
const rules = reactive(
{
// userName: [
// {
// required: true,
// message: '请输入用户名称',
// },
// ],
// userYear: [
// {
// type: 'date',
// required: true,
// message: '请输入建成年份',
// trigger: 'change'
// }
// ],
// groupId: [
// {
// required: true,
// message: '请选择集团',
// },
// ],
}
)
const companyMap = reactive({})
const addUserForm = reactive(
{
username: '', // 用户名称
name: '', // 账号
password: '', // 密码
accountId: '', // 所属公司
type: '', // 数据权限管理
}
)
const editUserForm = reactive(
{
username: '', // 用户名称
name: '', // 账号
password: '', // 密码
accountId: '', // 所属公司
type: '', // 数据权限管理
id: '',
}
)
// function
const handlePageNumChange = function(num) {
pageNum.value = num
getUserList()
}
const handlePageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getUserList()
}
const confirmAddUser = function() {
ref_addUserForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(addUserForm)
const data = filterEmptyValueInObject(rawData)
userApi.addUser(data).then(
(r) => {
addUserVisible.value = false
const message = r.msg
ElMessage(`${message}`)
getUserList()
}
)
}
}
)
}
const editUser = function(row) {
editUserVisible.value = true
editUserForm.username = row.username
editUserForm.name = row.name
editUserForm.password = row.password
editUserForm.accountId = row.accountId
editUserForm.type = row.type
editUserForm.id = row.id
}
const confirmEditUser = function() {
ref_editUserForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(editUserForm)
const data = filterEmptyValueInObject(
{
username: rawData.username,
name: rawData.name,
password: rawData.password,
accountId: rawData.accountId,
type: rawData.type,
}
)
userApi.editUser(rawData.id, data).then(
(r) => {
const message = r.msg
getUserList()
ElMessage(`${message}`)
}
)
editUserVisible.value = false
}
}
)
}
const confirmDeleteUser = function(id) {
ElMessageBox.confirm(
"删除后此用户相关数据全部都会消失,你确定要删除吗?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
userApi.deleteUser(id).then(
(r) => {
const message = r.msg
getUserList()
ElMessage(`${message}`)
}
)
}
)
}
const addUser = function() {
resetForm(addUserForm)
addUserVisible.value = true
}
const getUserList = function() {
isLoading.value = true
userApi.getUserList().then(
({data}) => {
isLoading.value = false
userList.value = data
// formatPaginatedTableData(
// userList,
// data,
// total,
// )
}
)
}
const initialize = function() {
getUserList()
getCompanyMap(companyMap)
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
userList,
ref_addUserForm,
ref_editUserForm,
addUserVisible,
editUserVisible,
// mapping
companyMap,
addUserForm,
editUserForm,
rules,
// function
handlePageNumChange,
handlePageSizeChange,
addUser,
editUser,
confirmEditUser,
confirmAddUser,
confirmDeleteUser,
getCanCreateUsernameIdMap,
getKeyByValueInObject,
}
},
}
</script>
<style lang="less" scoped>
@import "./UserManagement.less";
</style>
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
<template>
<el-container class="DataClean">
<el-header height="auto">
<span class="title-text">类间清洗</span>
<div style="display: flex; justify-content:flex-end">
<el-button @click="goBack">返回上一页</el-button>
</div>
<div style="font-size: 20px">任务名:{{ name }}</div>
<div style="font-size: 20px">批次:{{ packName }}</div>
<el-menu mode="horizontal" @select="onMenuSelect" :default-active="''">
<el-menu-item :index="'0'">
未处理
</el-menu-item>
<el-menu-item :index="'1'">
已处理
</el-menu-item>
<el-menu-item :index="''">
全部
</el-menu-item>
</el-menu>
</el-header>
<el-main>
<el-table :data="dataCleanList" v-loading="isLoading">
<el-table-column prop="personId" label="左侧ID" align="center"></el-table-column>
<el-table-column prop="simPersonId" label="右侧ID" align="center"></el-table-column>
<el-table-column prop="same" label="是否是同一个人" align="center">
<template #default="scope">
{{ getSameTitle(scope.row.same) }}
</template>
</el-table-column>
<el-table-column prop="status" label="状态" align="center">
<template #default="scope">
{{ getStatusTitle(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" align="center">
<template #default="scope">
<el-button @click="gotoHandle(scope.row)" type="text">进入</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination @current-change="onPageNumChange"
@size-change="onPageSizeChange"
:current-page="pageNum"
:page-size="pageSize"
:total="total"
:page-sizes="[10, 20, 40, 80]"
layout="total, sizes, prev, pager, next, jumper"
style="text-align:center"
>
</el-pagination>
</el-main>
</el-container>
</template>
<script>
import {computed, onMounted, reactive, ref, toRaw, toRefs, watch} from "vue"
import {
filterEmptyValueInObject, goBack,
resetForm
} from "@/PublicUtil/PublicUtil"
import dataCleanApi from './ClassAmongClean'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getImagePackageMap, getUserNameIdMap} from '@/Request/DictionaryRequest'
import router from '@/router'
import {useRoute, useRouter} from 'vue-router'
export default {
setup() {
// scalar
const packId = useRoute().query.packId
const name = useRoute().query.name
const packName = useRoute().query.packName
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const addDataCleanVisible = ref(false)
const editDataCleanVisible = ref(false)
const dataCleanList = ref([])
const ref_addDataCleanForm = ref()
const ref_editDataCleanForm = ref()
const router = useRouter()
let selectedMenuIndex = ''
// computed
// mapping
const rules = reactive(
{}
)
const userNameIdMap = reactive({})
const imagePackageMap = reactive({})
const addDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
const editDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
// function
const onPageNumChange = function(num) {
pageNum.value = num
getDataCleanList()
}
const onPageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getDataCleanList()
}
const confirmAddDataClean = function() {
ref_addDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
addDataCleanVisible.value = false
const rawData = toRaw(addDataCleanForm)
const data = filterEmptyValueInObject(rawData)
dataCleanApi.addDataClean(data).then(
(r) => {
const message = r.msg
ElMessage(`${message}`)
getDataCleanList()
}
)
}
}
)
}
const editDataClean = function(row) {
editDataCleanVisible.value = true
editDataCleanForm.id = row.id
editDataCleanForm.name = row.name
editDataCleanForm.managerId = row.managerId
editDataCleanForm.description = row.description
}
const confirmEditDataClean = function() {
ref_editDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(editDataCleanForm)
const data = filterEmptyValueInObject(
{
name: rawData.name,
managerId: rawData.managerId,
description: rawData.description,
}
)
dataCleanApi.editDataClean(rawData.id, data).then(
(r) => {
const message = r.msg
getDataCleanList()
ElMessage(`${message}`)
}
)
editDataCleanVisible.value = false
}
}
)
}
const confirmDeleteDataClean = function(id) {
ElMessageBox.confirm(
"删除后此数据清洗相关数据全部都会消失,你确定要删除吗?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
dataCleanApi.deleteDataClean(id).then(
(r) => {
const message = r.msg
getDataCleanList()
ElMessage(`${message}`)
}
)
}
)
}
const addDataClean = function() {
resetForm(addDataCleanForm)
addDataCleanVisible.value = true
}
const getDataCleanList = function() {
isLoading.value = true
dataCleanApi.getDataCleanList({
packId: packId,
status: selectedMenuIndex,
pageNum: pageNum.value,
pageSize: pageSize.value,
}).then(
({data}) => {
isLoading.value = false
dataCleanList.value = data.list
total.value = data.total
}
)
}
const getStatusTitle = function(status) {
switch (status)
{
case 0:
{
return '未处理'
}
case 1:
{
return '已处理'
}
case 2:
{
return '处理中'
}
default:
{
break
}
}
}
const getTypeTitle = function(status) {
switch (status)
{
case 1:
{
return '类内清洗'
}
case 2:
{
return '类间清洗'
}
{
break
}
}
}
const gotoHandle = function(row) {
const data = {
id: row.id,
packId: row.packId,
}
dataCleanApi.getCleanAmongResult(data).then(
({data}) => {
router.push(
{
path: '/JudgePeople',
query: {
id: row.id,
packId: row.packId,
leftPersonId: data.personId,
rightPersonId: data.simPersonId,
same: getSameTitle(row.same),
name: name,
packName: packName,
personId: row.personId,
}
}
)
}
)
}
const onMenuSelect = function(index) {
selectedMenuIndex = index
getDataCleanList()
}
const getSameTitle = function(same) {
switch (same)
{
case 0:
{
return '不是'
}
case 1:
{
return '是'
}
default:
{
break
}
}
}
// const goBack = function() {
// router.push(
// {
// path: '/DataClean/DataClean',
// }
// )
// }
const initialize = function() {
getDataCleanList()
getUserNameIdMap(userNameIdMap)
getImagePackageMap(imagePackageMap)
}
initialize()
return {
// scalar
name,
packName,
pageNum,
pageSize,
total,
isLoading,
dataCleanList,
ref_addDataCleanForm,
ref_editDataCleanForm,
addDataCleanVisible,
editDataCleanVisible,
// mapping
userNameIdMap,
imagePackageMap,
addDataCleanForm,
editDataCleanForm,
rules,
// function
onPageNumChange,
onPageSizeChange,
addDataClean,
editDataClean,
confirmEditDataClean,
confirmAddDataClean,
confirmDeleteDataClean,
gotoHandle,
getStatusTitle,
getTypeTitle,
getSameTitle,
onMenuSelect,
goBack,
}
},
}
</script>
<style lang="less" scoped>
@import "./ClassAmongClean.less";
</style>
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
<template>
<el-container class="DataClean">
<el-header height="auto">
<span class="title-text">类内清洗</span>
<div style="display: flex; justify-content:flex-end">
<el-button @click="goBack">返回上一页</el-button>
</div>
<div style="font-size: 20px">任务名:{{ name }}</div>
<div style="font-size: 20px">批次:{{ packName }}</div>
<el-menu mode="horizontal" @select="onMenuSelect" :default-active="''">
<el-menu-item :index="'0'">
未处理
</el-menu-item>
<el-menu-item :index="'1'">
已处理
</el-menu-item>
<el-menu-item :index="''">
全部
</el-menu-item>
</el-menu>
</el-header>
<el-main>
<el-table :data="dataCleanList" v-loading="isLoading">
<el-table-column prop="personId" label="ID" align="center"></el-table-column>
<el-table-column prop="status" label="状态" align="center">
<template #default="scope">
{{ getStatusTitle(scope.row.status) }}
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" align="center">
<template #default="scope">
<el-button @click="gotoHandle(scope.row)" type="text">进入处理</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination @current-change="onPageNumChange"
@size-change="onPageSizeChange"
:current-page="pageNum"
:page-size="pageSize"
:total="total"
:page-sizes="[10, 20, 40, 80]"
layout="total, sizes, prev, pager, next, jumper"
style="text-align:center"
>
</el-pagination>
</el-main>
</el-container>
</template>
<script>
import {computed, onMounted, reactive, ref, toRaw, toRefs, watch} from "vue"
import {
filterEmptyValueInObject, goBack,
resetForm
} from "@/PublicUtil/PublicUtil"
import classInsideCleanApi from './ClassInsideClean'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getImagePackageMap, getUserNameIdMap} from '@/Request/DictionaryRequest'
import router from '@/router'
import {useRoute, useRouter} from 'vue-router'
export default {
setup() {
// scalar
const packId = useRoute().query.packId
const name = useRoute().query.name
const packName = useRoute().query.packName
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const addDataCleanVisible = ref(false)
const editDataCleanVisible = ref(false)
const dataCleanList = ref([])
const ref_addDataCleanForm = ref()
const ref_editDataCleanForm = ref()
const router = useRouter()
let selectedMenuIndex = ''
// computed
// mapping
const rules = reactive(
{}
)
const userNameIdMap = reactive({})
const imagePackageMap = reactive({})
const addDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
const editDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
// function
const onPageNumChange = function(num) {
pageNum.value = num
getDataCleanList()
}
const onPageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getDataCleanList()
}
const confirmAddDataClean = function() {
ref_addDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
addDataCleanVisible.value = false
const rawData = toRaw(addDataCleanForm)
const data = filterEmptyValueInObject(rawData)
classInsideCleanApi.addDataClean(data).then(
(r) => {
const message = r.msg
ElMessage(`${message}`)
getDataCleanList()
}
)
}
}
)
}
const editDataClean = function(row) {
editDataCleanVisible.value = true
editDataCleanForm.id = row.id
editDataCleanForm.name = row.name
editDataCleanForm.managerId = row.managerId
editDataCleanForm.description = row.description
}
const confirmEditDataClean = function() {
ref_editDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(editDataCleanForm)
const data = filterEmptyValueInObject(
{
name: rawData.name,
managerId: rawData.managerId,
description: rawData.description,
}
)
classInsideCleanApi.editDataClean(rawData.id, data).then(
(r) => {
const message = r.msg
getDataCleanList()
ElMessage(`${message}`)
}
)
editDataCleanVisible.value = false
}
}
)
}
const confirmDeleteDataClean = function(id) {
ElMessageBox.confirm(
"删除后此数据清洗相关数据全部都会消失,你确定要删除吗?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
classInsideCleanApi.deleteDataClean(id).then(
(r) => {
const message = r.msg
getDataCleanList()
ElMessage(`${message}`)
}
)
}
)
}
const addDataClean = function() {
resetForm(addDataCleanForm)
addDataCleanVisible.value = true
}
const getDataCleanList = function() {
isLoading.value = true
classInsideCleanApi.getClassInsideCleanList({
packId: packId,
status: selectedMenuIndex,
pageNum: pageNum.value,
pageSize: pageSize.value,
}).then(
({data}) => {
isLoading.value = false
dataCleanList.value = data.list
total.value = data.total
}
)
}
const getStatusTitle = function(status) {
switch (status)
{
case 0:
{
return '未处理'
}
case 1:
{
return '已处理'
}
case 2:
{
return '处理中'
}
default:
{
break
}
}
}
const getTypeTitle = function(status) {
switch (status)
{
case 1:
{
return '类内清洗'
}
case 2:
{
return '类间清洗'
}
{
break
}
}
}
const gotoHandle = function(row) {
router.push(
{
path: '/ClassInsideJudgePerson',
query: {
personId: row.personId,
packId: row.packId,
name: name,
packName: packName,
}
}
)
}
const onMenuSelect = function(index) {
selectedMenuIndex = index
getDataCleanList()
}
const getSameTitle = function(same) {
switch (same)
{
case 0:
{
return '不是'
}
case 1:
{
return '是'
}
default:
{
break
}
}
}
// const goBack = function() {
// router.push(
// {
// path: '/DataClean/DataClean',
// }
// )
// }
const initialize = function() {
getDataCleanList()
getUserNameIdMap(userNameIdMap)
getImagePackageMap(imagePackageMap)
}
initialize()
return {
// scalar
name,
packName,
pageNum,
pageSize,
total,
isLoading,
dataCleanList,
ref_addDataCleanForm,
ref_editDataCleanForm,
addDataCleanVisible,
editDataCleanVisible,
// mapping
userNameIdMap,
imagePackageMap,
addDataCleanForm,
editDataCleanForm,
rules,
// function
onPageNumChange,
onPageSizeChange,
addDataClean,
editDataClean,
confirmEditDataClean,
confirmAddDataClean,
confirmDeleteDataClean,
gotoHandle,
getStatusTitle,
getTypeTitle,
getSameTitle,
onMenuSelect,
goBack,
}
},
}
</script>
<style lang="less" scoped>
@import "./ClassInsideClean.less";
</style>
.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;
}
<template>
<el-container>
<el-header height="auto">
<div style="display: flex; justify-content:flex-end">
<el-button @click="goBack">返回上一页</el-button>
</div>
<el-row>
<el-col :span="12">
<span style="font-size: 20px">ID:{{ personId }}</span>
</el-col>
<el-col :span="12">
<span style="font-size: 20px">异常图片</span>
</el-col>
</el-row>
</el-header>
<el-main>
<el-container>
<el-aside :width="'50%'" style="border-right: red 1px solid">
<!-- <VirtualList-->
<!-- :dataList="leftPagedTableData"-->
<!-- :key="leftPagedTableData"-->
<!-- @imageClick="selectImage"-->
<!-- >-->
<!-- </VirtualList>-->
<el-row v-for="row in leftPagedTableData">
<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">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image">
</el-image>
</div>
</el-col>
</el-row>
</el-aside>
<el-main>
<!-- <VirtualList-->
<!-- :dataList="rightPagedTableData"-->
<!-- :key="rightPagedTableData"-->
<!-- @imageClick="selectImage"-->
<!-- >-->
<!-- </VirtualList>-->
<el-row v-for="row in rightPagedTableData">
<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">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image">
</el-image>
</div>
</el-col>
</el-row>
</el-main>
</el-container>
</el-main>
<el-footer>
<div style="display: flex; justify-content:flex-end;height: 100%" class="flex-vertical-center">
<el-button type="primary" @click="onlySplit">只拆分(A)</el-button>
<el-button type="primary" @click="split">拆分并完成(D)</el-button>
</div>
</el-footer>
</el-container>
</template>
<script>
import {useRoute, useRouter} from 'vue-router'
import {
getPagedList,
getImageUrl,
} from '@/PublicUtil/PublicUtil'
import {computed, onBeforeUnmount, reactive, ref} from 'vue'
import labelingApi from '@/views/DataLabel/Labeling/LabelingApi'
import {ElMessage} from 'element-plus'
import classInsideCleanApi from '@/views/ClassInsideClean/ClassInsideClean'
import VirtualList from './VirtualList/VirtualList'
export default {
components: {
VirtualList,
},
setup() {
const name = useRoute().query.name
const packName = useRoute().query.packName
const personId = useRoute().query.personId
const packId = useRoute().query.packId
const leftPeopleImageList = ref([])
const rightPeopleImageList = ref([])
let leftSelectedImageUnidList = []
let rightSelectedImageUnidList = []
let allSelectedImageIdList = []
const router = useRouter()
const leftPagedTableData = computed(
() => {
return getPagedList(leftPeopleImageList.value, 3)
}
)
const rightPagedTableData = computed(
() => {
return getPagedList(rightPeopleImageList.value, 3)
}
)
const getLeftPeopleImageList = function() {
labelingApi.getPeopleImageList(packId, personId).then(
(r) => {
leftPeopleImageList.value = r.data
for (const peopleImage of leftPeopleImageList.value)
{
peopleImage['isSelected'] = false
}
}
)
}
const getRightPeopleImageList = function() {
const data = {
personId: personId,
packId: packId,
}
classInsideCleanApi.getCleanInsideResult(data).then(
({data}) => {
rightPeopleImageList.value = data
for (const peopleImage of rightPeopleImageList.value)
{
peopleImage['isSelected'] = false
}
}
)
}
const onlySplit = function() {
const data = {
personId: personId,
packId: packId,
picIds: allSelectedImageIdList.toString(),
}
classInsideCleanApi.split(data).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
window.location.reload()
}
)
}
const split = function() {
const data = {
personId: personId,
packId: packId,
picIds: allSelectedImageIdList.toString(),
}
classInsideCleanApi.split(data).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
if (r.code === 200)
{
classInsideCleanApi.getCleanInsideResult({packId: packId}).then(
({data}) => {
router.push(
{
path: '/ClassInsideJudgePerson',
query: {
personId: data[0].personUnid,
packId: packId,
}
}
)
}
)
}
}
)
}
const changeSelectedImageIdList = function(item, position) {
item['isSelected'] = !item['isSelected']
if (item['isSelected'] === true)
{
if (position === 'left')
{
leftSelectedImageUnidList.push(item.unid)
}
else
{
rightSelectedImageUnidList.push(item.unid)
}
}
else
{
if (position === 'left')
{
leftSelectedImageUnidList.splice(leftSelectedImageUnidList.indexOf(item.unid), 1)
}
else
{
rightSelectedImageUnidList.splice(rightSelectedImageUnidList.indexOf(item.unid), 1)
}
}
allSelectedImageIdList = leftSelectedImageUnidList.concat(rightSelectedImageUnidList)
allSelectedImageIdList = [...new Set(allSelectedImageIdList)]
}
const selectImage = function(unid) {
for (let row of leftPagedTableData.value)
{
for (let item of row)
{
if (item.unid === unid)
{
changeSelectedImageIdList(item, 'left')
}
}
}
for (let row of rightPagedTableData.value)
{
for (let item of row)
{
if (item.unid === unid)
{
changeSelectedImageIdList(item, 'right')
}
}
}
}
const goBack = function() {
router.push(
{
path: '/ClassInsideClean',
query: {
packId: packId,
name: name,
packName: packName,
}
}
)
}
const addShortcutKey = function(event) {
if (event.code === 'KeyA')
{
onlySplit()
}
if (event.code === 'KeyD')
{
split()
}
}
onBeforeUnmount(
() => {
document.removeEventListener('keydown', addShortcutKey)
}
)
const initialize = function() {
getLeftPeopleImageList()
getRightPeopleImageList()
document.addEventListener('keydown', addShortcutKey)
}
initialize()
return {
// scalar
personId,
// sequence
leftPagedTableData,
rightPagedTableData,
// mapping
// function
onlySplit,
split,
selectImage,
getImageUrl,
goBack,
}
}
}
</script>
<style lang="less" scoped>
@import "./ClassInsideJudgePerson.less";
</style>
.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>
<template>
<el-container class="DataClean">
<el-header height="50px">
<div>
<span class="title-text">清洗管理</span>
</div>
</el-header>
<el-main>
<el-button type="primary" @click="addDataClean">新建</el-button>
<el-button type="primary" @click="refreshTable">刷新列表</el-button>
<el-table :data="dataCleanList" v-loading="isLoading">
<el-table-column prop="name" label="名称" align="center"></el-table-column>
<el-table-column prop="cleanType" label="清洗类型" align="center">
<template #default="scope">
{{ getTypeTitle(scope.row.cleanType) }}
</template>
</el-table-column>
<el-table-column prop="status" label="清洗状态" align="center">
<template #default="scope">
{{ getStatusTitle(scope.row.status, scope.row.progress) }}
</template>
</el-table-column>
<el-table-column prop="packName" label="批次名" align="center"></el-table-column>
<el-table-column prop="updateTime" label="修改时间" align="center"></el-table-column>
<el-table-column prop="score" label="阈值" align="center"></el-table-column>
<el-table-column prop="percent" label="占比" align="center"></el-table-column>
<el-table-column prop="maxNum" label="抽取数量" align="center">
<template #default="scope">
{{ scope.row.cleanType === 2 ? scope.row.maxNum : '' }}
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" align="center" width="350">
<template #default="scope">
<el-button @click="classInsideClean(scope.row.id)" v-if="[1, 5].includes(scope.row.status)" type="text" v-loading="isButtonLoading">类内清洗</el-button>
<el-button @click="classAmongClean(scope.row.id)" v-if="[1, 5].includes(scope.row.status)" type="text" v-loading="isButtonLoading">类间清洗</el-button>
<el-button @click="gotoHandle(scope.row)" v-if="[3].includes(scope.row.status)" type="text" v-loading="isButtonLoading">进入处理</el-button>
<el-button @click="completeClean(scope.row.id)" v-if="[3].includes(scope.row.status)" type="text" v-loading="isButtonLoading">完成清洗</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination @current-change="onPageNumChange"
@size-change="onPageSizeChange"
:current-page="pageNum"
:page-size="pageSize"
:total="total"
:page-sizes="[10, 20, 40, 80]"
layout="total, sizes, prev, pager, next, jumper"
style="text-align:center"
>
</el-pagination>
<el-drawer title="新建数据清洗" v-model="addDataCleanVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="dataClean-form">
<el-form :model="addDataCleanForm" :rules="rules" ref="ref_addDataCleanForm">
<el-form-item label="批次:" :label-width="'120px'">
<el-select v-model="addDataCleanForm.packId" style="width: 100%">
<el-option v-for="(name, value) in imagePackageMap" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="任务名:" :label-width="'120px'">
<el-input v-model.trim="addDataCleanForm.name"></el-input>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="addDataCleanVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmAddDataClean">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<el-dialog title="类内清洗" v-model="isClassInsideCleanVisible" width="30%" :destroy-on-close="true" center>
<el-form :model="classInsideCleanForm">
<el-form-item label="阈值:">
<el-input-number v-model="classInsideCleanForm.score" :step="0.1" :min="0" :max="1" style="width: 100%"/>
<div>范围:0-1之间,可为小数</div>
</el-form-item>
<el-form-item label="比例:">
<el-input-number v-model="classInsideCleanForm.percent" :step="0.1" :min="0" :max="1" style="width: 100%"/>
<div>范围:0-1之间,可为小数</div>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="isClassInsideCleanVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmClassInsideClean">确 定</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog title="类间清洗" v-model="isClassAmongCleanVisible" width="30%" :destroy-on-close="true" center>
<el-form :model="classAmongCleanForm">
<el-form-item label="阈值:" :label-width="'140px'">
<el-input-number v-model="classAmongCleanForm.score" :step="0.1" :min="0" :max="1" style="width: 100%"/>
<div>范围:0.7-1之间,可为小数</div>
</el-form-item>
<el-form-item label="比例:" :label-width="'140px'">
<el-input-number v-model="classAmongCleanForm.percent" :step="0.1" :min="0" :max="1" style="width: 100%"/>
<div>范围:0-1之间,可为小数</div>
</el-form-item>
<el-form-item label="抽取每人图片数量:" :label-width="'140px'">
<el-input-number v-model="classAmongCleanForm.maxNum" :step="1" :min="0" style="width: 100%"/>
<div>数量越小,清洗越快</div>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="isClassAmongCleanVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmClassAmongClean">确 定</el-button>
</el-form-item>
</el-form>
</el-dialog>
</el-main>
</el-container>
</template>
<script>
import {computed, onMounted, reactive, ref, toRaw, toRefs, watch} from "vue"
import {
filterEmptyValueInObject,
resetForm
} from "@/PublicUtil/PublicUtil"
import dataCleanApi from './DataCleanApi'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getImagePackageMap, getUserNameIdMap} from '@/Request/DictionaryRequest'
import router from '@/router'
import {useRouter} from 'vue-router'
import {isEmptyValue} from '@/PublicUtil/Judgment'
import imagePackageApi from '@/views/DataLabel/ImagePackage/ImagePackageApi'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const addDataCleanVisible = ref(false)
const editDataCleanVisible = ref(false)
const isButtonLoading = ref(false)
const isClassInsideCleanVisible = ref(false)
const isClassAmongCleanVisible = ref(false)
const dataCleanList = ref([])
const ref_addDataCleanForm = ref()
const ref_editDataCleanForm = ref()
const router = useRouter()
// computed
// mapping
const rules = reactive(
{}
)
const userNameIdMap = reactive({})
const imagePackageMap = reactive({})
const addDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
const editDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
const classInsideCleanForm = reactive(
{
taskId: '',
score: '',
percent: '',
}
)
const classAmongCleanForm = reactive(
{
taskId: '',
score: '',
percent: '',
maxNum: '',
}
)
// function
const onPageNumChange = function(num) {
pageNum.value = num
getDataCleanList()
}
const onPageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getDataCleanList()
}
const confirmAddDataClean = function() {
ref_addDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
addDataCleanVisible.value = false
const rawData = toRaw(addDataCleanForm)
const data = filterEmptyValueInObject(rawData)
dataCleanApi.addDataClean(data).then(
(r) => {
const message = r.msg
ElMessage(`${message}`)
getDataCleanList()
}
)
}
}
)
}
const editDataClean = function(row) {
editDataCleanVisible.value = true
editDataCleanForm.id = row.id
editDataCleanForm.name = row.name
editDataCleanForm.managerId = row.managerId
editDataCleanForm.description = row.description
}
const confirmEditDataClean = function() {
ref_editDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(editDataCleanForm)
const data = filterEmptyValueInObject(
{
name: rawData.name,
managerId: rawData.managerId,
description: rawData.description,
}
)
dataCleanApi.editDataClean(rawData.id, data).then(
(r) => {
const message = r.msg
getDataCleanList()
ElMessage(`${message}`)
}
)
editDataCleanVisible.value = false
}
}
)
}
const addDataClean = function() {
resetForm(addDataCleanForm)
addDataCleanVisible.value = true
}
const getDataCleanList = function() {
isLoading.value = true
dataCleanApi.getDataCleanList({
pageNum: pageNum.value,
pageSize: pageSize.value,
}).then(
({data}) => {
isLoading.value = false
dataCleanList.value = data.list
total.value = data.total
}
)
}
const getStatusTitle = function(status, progress) {
if (isEmptyValue(progress))
{
progress = ''
}
switch (status)
{
case 1:
{
return '待清洗' + progress
}
case 2:
{
return '清洗中' + progress
}
case 3:
{
return '人工处理中' + progress
}
case 4:
{
return '合并中' + progress
}
case 5:
{
return '清洗完成' + progress
}
default:
{
break
}
}
}
const classInsideClean = function(id) {
classInsideCleanForm.taskId = id
isClassInsideCleanVisible.value = true
}
const classAmongClean = function(id) {
classAmongCleanForm.taskId = id
isClassAmongCleanVisible.value = true
}
const confirmClassInsideClean = function() {
isClassInsideCleanVisible.value = false
isButtonLoading.value = true
const data = filterEmptyValueInObject(toRaw(classInsideCleanForm))
dataCleanApi.cleanInsideClean(data).then(
(r) => {
isButtonLoading.value = false
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
getDataCleanList()
}
)
}
const confirmClassAmongClean = function() {
isClassAmongCleanVisible.value = false
isButtonLoading.value = true
const data = filterEmptyValueInObject(toRaw(classAmongCleanForm))
dataCleanApi.cleanAmongClean(data).then(
(r) => {
isButtonLoading.value = false
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
getDataCleanList()
}
)
}
const getTypeTitle = function(cleanType) {
switch (cleanType)
{
case 1:
{
return '类内清洗'
}
case 2:
{
return '类间清洗'
}
{
break
}
}
}
const gotoHandle = function(row) {
switch (row.cleanType)
{
case 1:
{
router.push(
{
path: '/ClassInsideClean',
query: {
packId: row.packId,
name: row.name,
packName: row.packName,
}
}
)
break
}
case 2:
{
router.push(
{
path: '/ClassAmongClean',
query: {
packId: row.packId,
name: row.name,
packName: row.packName,
}
}
)
break
}
default:
{
break
}
}
}
const completeClean = function(id) {
isButtonLoading.value = true
dataCleanApi.completeClean(id).then(
(r) => {
isButtonLoading.value = false
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
getDataCleanList()
}
)
}
const getImagePackageMap = function() {
dataCleanApi.getImagePackageMap().then(
({data}) => {
for (const item of data)
{
imagePackageMap[item.id] = item.name
}
}
)
}
const refreshTable = function() {
getDataCleanList()
}
const initialize = function() {
getDataCleanList()
getImagePackageMap()
getUserNameIdMap(userNameIdMap)
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
dataCleanList,
ref_addDataCleanForm,
ref_editDataCleanForm,
addDataCleanVisible,
editDataCleanVisible,
isButtonLoading,
isClassInsideCleanVisible,
isClassAmongCleanVisible,
// mapping
userNameIdMap,
imagePackageMap,
addDataCleanForm,
editDataCleanForm,
rules,
classInsideCleanForm,
classAmongCleanForm,
// function
onPageNumChange,
onPageSizeChange,
addDataClean,
editDataClean,
confirmEditDataClean,
confirmAddDataClean,
gotoHandle,
getStatusTitle,
getTypeTitle,
classInsideClean,
classAmongClean,
completeClean,
refreshTable,
confirmClassInsideClean,
confirmClassAmongClean,
}
},
}
</script>
<style lang="less" scoped>
@import "./DataClean.less";
</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
<template>
<el-container class="DataClean">
<el-header height="50px">
<div>
<span class="title-text">数据清洗</span>
</div>
</el-header>
<el-main>
<!-- <el-button type="primary" @click="addDataClean">新建</el-button>-->
<el-button type="primary" @click="refreshTable">刷新列表</el-button>
<el-table :data="dataCleanList" v-loading="isLoading">
<el-table-column prop="name" label="名称" align="center"></el-table-column>
<el-table-column prop="cleanType" label="清洗类型" align="center">
<template #default="scope">
{{ getTypeTitle(scope.row.cleanType) }}
</template>
</el-table-column>
<el-table-column prop="status" label="清洗状态" align="center">
<template #default="scope">
{{ getStatusTitle(scope.row.status, scope.row.progress) }}
</template>
</el-table-column>
<el-table-column prop="packName" label="批次名" align="center"></el-table-column>
<el-table-column prop="updateTime" label="修改时间" align="center"></el-table-column>
<el-table-column prop="score" label="阈值" align="center"></el-table-column>
<el-table-column prop="percent" label="占比" align="center"></el-table-column>
<el-table-column prop="maxNum" label="抽取数量" align="center">
<template #default="scope">
{{ scope.row.cleanType === 2 ? scope.row.maxNum : '' }}
</template>
</el-table-column>
<el-table-column prop="operation" label="操作" align="center" width="350">
<template #default="scope">
<!-- <el-button @click="clean(scope.row.id, '类内清洗')" v-if="[1, 5].includes(scope.row.status)" type="text" v-loading="isButtonLoading">类内清洗</el-button>-->
<!-- <el-button @click="clean(scope.row.id, '类间清洗')" v-if="[1, 5].includes(scope.row.status)" type="text" v-loading="isButtonLoading">类间清洗</el-button>-->
<el-button @click="gotoHandle(scope.row)" v-if="[3].includes(scope.row.status)" type="text" v-loading="isButtonLoading">进入处理</el-button>
<!-- <el-button @click="completeClean(scope.row.id)" v-if="[3].includes(scope.row.status)" type="text" v-loading="isButtonLoading">完成清洗</el-button>-->
</template>
</el-table-column>
</el-table>
<el-pagination @current-change="onPageNumChange"
@size-change="onPageSizeChange"
:current-page="pageNum"
:page-size="pageSize"
:total="total"
:page-sizes="[10, 20, 40, 80]"
layout="total, sizes, prev, pager, next, jumper"
style="text-align:center"
>
</el-pagination>
<el-drawer title="新建数据清洗" v-model="addDataCleanVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="dataClean-form">
<el-form :model="addDataCleanForm" :rules="rules" ref="ref_addDataCleanForm">
<el-form-item label="批次:" :label-width="'120px'">
<el-select v-model="addDataCleanForm.packId" style="width: 100%">
<el-option v-for="(name, value) in imagePackageMap" :label="name" :value="value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="任务名:" :label-width="'120px'">
<el-input v-model.trim="addDataCleanForm.name"></el-input>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="addDataCleanVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmAddDataClean">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
</el-main>
</el-container>
</template>
<script>
import {computed, onMounted, reactive, ref, toRaw, toRefs, watch} from "vue"
import {
filterEmptyValueInObject,
resetForm
} from "@/PublicUtil/PublicUtil"
import dataCleanApi from './DataCleanApi'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getImagePackageMap, getUserNameIdMap} from '@/Request/DictionaryRequest'
import router from '@/router'
import {useRouter} from 'vue-router'
import {isEmptyValue} from '@/PublicUtil/Judgment'
import imagePackageApi from '@/views/DataLabel/ImagePackage/ImagePackageApi'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const addDataCleanVisible = ref(false)
const editDataCleanVisible = ref(false)
const isButtonLoading = ref(false)
const dataCleanList = ref([])
const ref_addDataCleanForm = ref()
const ref_editDataCleanForm = ref()
const router = useRouter()
// computed
// mapping
const rules = reactive(
{}
)
const userNameIdMap = reactive({})
const imagePackageMap = reactive({})
const addDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
const editDataCleanForm = reactive(
{
packId: '',
name: '',
}
)
// function
const onPageNumChange = function(num) {
pageNum.value = num
getDataCleanList()
}
const onPageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getDataCleanList()
}
const confirmAddDataClean = function() {
ref_addDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
addDataCleanVisible.value = false
const rawData = toRaw(addDataCleanForm)
const data = filterEmptyValueInObject(rawData)
dataCleanApi.addDataClean(data).then(
(r) => {
const message = r.msg
ElMessage(`${message}`)
getDataCleanList()
}
)
}
}
)
}
const editDataClean = function(row) {
editDataCleanVisible.value = true
editDataCleanForm.id = row.id
editDataCleanForm.name = row.name
editDataCleanForm.managerId = row.managerId
editDataCleanForm.description = row.description
}
const confirmEditDataClean = function() {
ref_editDataCleanForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(editDataCleanForm)
const data = filterEmptyValueInObject(
{
name: rawData.name,
managerId: rawData.managerId,
description: rawData.description,
}
)
dataCleanApi.editDataClean(rawData.id, data).then(
(r) => {
const message = r.msg
getDataCleanList()
ElMessage(`${message}`)
}
)
editDataCleanVisible.value = false
}
}
)
}
const addDataClean = function() {
resetForm(addDataCleanForm)
addDataCleanVisible.value = true
}
const getDataCleanList = function() {
isLoading.value = true
dataCleanApi.getDataCleanList({
pageNum: pageNum.value,
pageSize: pageSize.value,
}).then(
({data}) => {
isLoading.value = false
dataCleanList.value = data.list
total.value = data.total
}
)
}
const getStatusTitle = function(status, progress) {
if (isEmptyValue(progress))
{
progress = ''
}
switch (status)
{
case 1:
{
return '待清洗' + progress
}
case 2:
{
return '清洗中' + progress
}
case 3:
{
return '人工处理中' + progress
}
case 4:
{
return '合并中' + progress
}
case 5:
{
return '清洗完成' + progress
}
default:
{
break
}
}
}
const clean = function(id, typeText) {
isButtonLoading.value = true
switch (typeText)
{
case '类内清洗':
{
dataCleanApi.clean(1, id).then(
(r) => {
isButtonLoading.value = false
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
getDataCleanList()
}
)
break
}
case '类间清洗':
{
dataCleanApi.clean(2, id).then(
(r) => {
isButtonLoading.value = false
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
getDataCleanList()
}
)
break
}
default:
{
isButtonLoading.value = false
break
}
}
}
const getTypeTitle = function(cleanType) {
switch (cleanType)
{
case 1:
{
return '类内清洗'
}
case 2:
{
return '类间清洗'
}
{
break
}
}
}
const gotoHandle = function(row) {
switch (row.cleanType)
{
case 1:
{
router.push(
{
path: '/ClassInsideClean',
query: {
packId: row.packId,
name: row.name,
packName: row.packName,
}
}
)
break
}
case 2:
{
router.push(
{
path: '/ClassAmongClean',
query: {
packId: row.packId,
name: row.name,
packName: row.packName,
}
}
)
break
}
default:
{
break
}
}
}
const completeClean = function(id) {
isButtonLoading.value = true
dataCleanApi.completeClean(id).then(
(r) => {
isButtonLoading.value = false
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
getDataCleanList()
}
)
}
const getImagePackageMap = function() {
dataCleanApi.getImagePackageMap().then(
({data}) => {
for (const item of data)
{
imagePackageMap[item.id] = item.name
}
}
)
}
const refreshTable = function() {
getDataCleanList()
}
const initialize = function() {
getDataCleanList()
getImagePackageMap()
getUserNameIdMap(userNameIdMap)
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
dataCleanList,
ref_addDataCleanForm,
ref_editDataCleanForm,
addDataCleanVisible,
editDataCleanVisible,
isButtonLoading,
// mapping
userNameIdMap,
imagePackageMap,
addDataCleanForm,
editDataCleanForm,
rules,
// function
onPageNumChange,
onPageSizeChange,
addDataClean,
editDataClean,
confirmEditDataClean,
confirmAddDataClean,
gotoHandle,
getStatusTitle,
getTypeTitle,
clean,
completeClean,
refreshTable,
}
},
}
</script>
<style lang="less" scoped>
@import "./DataClean.less";
</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,
}
)
}
)
}
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;
}
<template>
<el-container class="Labeling">
<el-header height="auto">
<div style="display: flex;justify-content: space-between">
标注中
<a-button @click="goBack" style="margin: 0 0 10px 0">返回上一页</a-button>
</div>
</el-header>
<el-main>
<el-container>
<el-aside :width="'50%'">
<el-container>
<el-header height="auto">
<el-row>
<el-col :span="18">
文件夹数量:
<el-input v-model.trim="folderNum" @input="onFolderNumChange" placeholder="文件夹数量" size="small" style="width: 100px"></el-input>
分钟数:
<el-input v-model.trim="minuteNum" @input="onMinuteNumChange" placeholder="分钟数" size="small" style="width: 100px"></el-input>
<a-button @click="confirmSearch" :loading="isSearchLoading" type="primary">搜索选中数据</a-button>
</el-col>
<el-col :span="6">
<div style="display: flex;justify-content: flex-end">
<a-button @click="confirmMerge" :loading="isMergeLoading" type="primary" style="margin: 0 0 0 5px">合并(Q)</a-button>
<a-button @click="highQualityExtract" type="primary" style="margin: 0 0 0 10px">优质提取</a-button>
<a-button @click="confirmDeleteImages" type="danger" style="margin: 0 10px">删除图片</a-button>
</div>
</el-col>
</el-row>
<div>图片</div>
<div v-bind:class="{ 'isFolderSelected' : isLeftImageFolderChecked }"
style="display:flex;justify-content: flex-end"
>
<a-checkbox v-model:checked="isLeftImageFolderChecked"
@change="selectImageFolder(currentPersonUnid)"
style="margin: 5px 2px">
选择文件夹
</a-checkbox>
</div>
</el-header>
<el-main v-bind:class="{ 'isFolderSelected' : isLeftImageFolderChecked }">
<!-- <VirtualList-->
<!-- :dataList="leftPagedTableData"-->
<!-- @imageClick="selectImage"-->
<!-- :key="leftPagedTableData"-->
<!-- ></VirtualList>-->
<el-row v-for="row in leftPagedTableData">
<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>
</el-main>
</el-container>
</el-aside>
<el-main>
<el-container>
<el-header>
<div style="display: flex;justify-content: space-between">
<span>
<a-button @click="lowQualityExtract" type="primary" style="margin: 0 10px">低质提取</a-button>
<a-button @click="recycle" type="primary">回收</a-button>
</span>
<a-button @click="completeLabel" type="primary">完成标注</a-button>
</div>
<div>文件夹</div>
</el-header>
<el-main>
<button id="right-anchor-button"></button>
<div v-for="(value, personUnid) in displayedRightPeopleImageMap"
class="right-image-folder-list"
:style="'border: 5px solid' + getFolderColor(value.list[0].status)"
v-bind:class="{ 'isFolderSelected' : value.isSelected }"
>
<div :style="'background: ' + getFolderColor(value.list[0].status)" style="height: 20px;color: white">{{ getFolderTitle(value.list[0].status) }}</div>
<a-checkbox @change="selectImageFolder(personUnid)" style="margin: 5px 2px">选择文件夹</a-checkbox>
<el-row v-for="row in getPagedList(value.list, 3)">
<el-col :span="8"
v-for="item in row"
@click="selectImage(item.id)"
style="content-visibility: auto"
>
<div v-bind:class="{ 'isSelected' : item.isSelected }"
@contextmenu.prevent=""
@click.right="previewImage(getImageUrl(item.picId))"
class="single-image-parent flex-vertical-center">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image"
>
</el-image>
</div>
</el-col>
</el-row>
</div>
<a-button @click="isFilteredDataShowed = true" v-if="isFilterButtonShowed" type="primary" style="width: 100%">展开过滤数据</a-button>
<div v-if="isFilteredDataShowed">
<div v-for="(value, personUnid) in hiddenRightPeopleImageMap"
class="right-image-folder-list"
:style="'border: 5px solid' + getFolderColor(value.list[0].status)"
v-bind:class="{ 'isFolderSelected' : value.isSelected }"
>
<div :style="'background: ' + getFolderColor(value.list[0].status)" style="height: 20px;color: white">{{ getFolderTitle(value.list[0].status) }}</div>
<a-checkbox @change="selectImageFolder(personUnid)" style="margin: 5px 2px">选择文件夹</a-checkbox>
<el-row v-for="row in getPagedList(value.list, 3)">
<el-col :span="8"
v-for="item in row"
@click="selectImage(item.id)"
style="content-visibility: auto">
<div v-bind:class="{ 'isSelected' : item.isSelected }"
@contextmenu.prevent=""
@click.right="previewImage(getImageUrl(item.picId))"
class="single-image-parent flex-vertical-center">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image">
</el-image>
</div>
</el-col>
</el-row>
</div>
</div>
</el-main>
</el-container>
</el-main>
</el-container>
</el-main>
<div style="display: flex;justify-content: flex-end">
<a-button @click="previousPerson">上一个</a-button>
<a-button @click="nextPerson">下一个</a-button>
</div>
</el-container>
</template>
<script>
import {useRoute} from 'vue-router'
import {
cloneObject,
emptyObject,
getPagedList,
getImageUrl,
resetForm,
filterEmptyValueInObject, getMinuteNum, getFolderNum, getFolderTitle, getFolderColor
} from '@/PublicUtil/PublicUtil'
import {computed, createVNode, onBeforeUnmount, reactive, ref} from 'vue'
import labelingApi from '@/views/DataLabel/Labeling/LabelingApi'
import {isEmptyArray, isNotEmptyArray} from '@/PublicUtil/Judgment'
import router from '@/router'
import {message, Modal} from 'ant-design-vue'
import {ExclamationCircleOutlined} from '@ant-design/icons-vue'
import VirtualList from '@/views/DataLabel/Labeling/VirtualList/VirtualList'
export default {
components: {
VirtualList,
},
setup() {
const packId = useRoute().query.packId
const currentPersonUnid = useRoute().query.personUnid
const status = useRoute().query.status
const isSearchLoading = ref(false)
const isMergeLoading = ref(false)
const isLeftImageFolderChecked = ref(true)
const ref_rightMain = ref()
const isFilterButtonShowed = ref(false)
const isFilteredDataShowed = ref(false)
const folderNum = ref(getFolderNum())
const minuteNum = ref(getMinuteNum())
const leftPeopleImageList = ref([])
const rightPeopleImageMap = reactive({})
const displayedRightPeopleImageMap = reactive({})
const hiddenRightPeopleImageMap = reactive({})
let selectedImageFolderIdList = [currentPersonUnid]
let allSelectedImageIdList = []
let leftSelectedImageIdList = []
let rightSelectedImageIdList = []
let webSocket = undefined
const leftPagedTableData = computed(
() => {
return getPagedList(leftPeopleImageList.value, 3)
}
)
const getPeopleImageList = function() {
labelingApi.getPeopleImageList(packId, currentPersonUnid).then(
(r) => {
leftPeopleImageList.value = r.data
for (const peopleImage of leftPeopleImageList.value)
{
peopleImage['isSelected'] = false
}
}
)
}
const resetAll = function() {
isMergeLoading.value = false
isFilterButtonShowed.value = false
isFilteredDataShowed.value = false
if (isLeftImageFolderChecked.value === true)
{
selectedImageFolderIdList = [currentPersonUnid]
}
else
{
selectedImageFolderIdList = []
}
leftSelectedImageIdList = []
rightSelectedImageIdList = []
allSelectedImageIdList = []
emptyObject(displayedRightPeopleImageMap)
emptyObject(hiddenRightPeopleImageMap)
emptyObject(rightPeopleImageMap)
getPeopleImageList()
}
const confirmMerge = function() {
log(selectedImageFolderIdList, allSelectedImageIdList)
isMergeLoading.value = true
if (
isEmptyArray(selectedImageFolderIdList)
&& isNotEmptyArray(allSelectedImageIdList)
)
{
// 没有文件夹被选中,有图片被选中
// 将多张图片合成新的文件夹
log(1, '没有文件夹被选中,有图片被选中')
labelingApi.mergeImagesAsNewPerson(
allSelectedImageIdList.toString(),
packId
).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
else if (
isNotEmptyArray(selectedImageFolderIdList)
&& selectedImageFolderIdList.length !== 1
&& isEmptyArray(allSelectedImageIdList)
)
{
// 有多个文件夹被选中,没有图片被选中
// 将多个文件夹合成一个文件夹
log(2, '有多个文件夹被选中,没有图片被选中')
labelingApi.mergeMultiplePersonsAsNewPerson(
selectedImageFolderIdList.toString(),
packId,
currentPersonUnid
).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
else if (
selectedImageFolderIdList.length === 1
&&
isNotEmptyArray(allSelectedImageIdList)
)
{
// 文件夹有一个被选中,有图片被选中
// 将多张图片合并到选中的一个文件夹中
log(3, '文件夹有一个被选中,有图片被选中')
labelingApi.mergeMultipleImagesToOnePerson(
allSelectedImageIdList.toString(),
selectedImageFolderIdList.toString(),
packId,
currentPersonUnid
).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
else if (
isLeftImageFolderChecked.value === true
&&
selectedImageFolderIdList.length > 1
&&
isNotEmptyArray(rightSelectedImageIdList)
)
{
// 左侧文件夹被选中,右侧有文件夹和图片同时被选中
// 将多张图片合并到选中的一个文件夹中
log(4, '左侧文件夹被选中,右侧有文件夹和图片同时被选中')
labelingApi.mergeMultipleImagesToOnePerson(
allSelectedImageIdList.toString(),
currentPersonUnid,
packId,
currentPersonUnid
).then(
() => {
labelingApi.mergeMultiplePersonsAsNewPerson(
selectedImageFolderIdList.toString(),
packId,
currentPersonUnid
).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
)
}
else
{
log(5)
message.info('选择格式错误')
isMergeLoading.value = false
}
}
const confirmSearch = function() {
document.getElementById("right-anchor-button").focus()
isSearchLoading.value = true
labelingApi.getSimilarPeopleImageFolderList(
leftSelectedImageIdList.toString(),
folderNum.value,
packId,
minuteNum.value,
currentPersonUnid,
).then(
(r) => {
isFilterButtonShowed.value = true
isSearchLoading.value = false
cloneObject(displayedRightPeopleImageMap, r.data.display)
cloneObject(hiddenRightPeopleImageMap, r.data.hide)
// 更改数据
for (let key in displayedRightPeopleImageMap)
{
const list = displayedRightPeopleImageMap[key]
for (let item of list)
{
item.isSelected = false
}
const value = {
isSelected: false,
list: list
}
displayedRightPeopleImageMap[key] = value
}
for (let key in hiddenRightPeopleImageMap)
{
const list = hiddenRightPeopleImageMap[key]
for (let item of list)
{
item.isSelected = false
}
const value = {
isSelected: false,
list: list
}
hiddenRightPeopleImageMap[key] = value
}
// 合并数据
for (let key in displayedRightPeopleImageMap)
{
const value = displayedRightPeopleImageMap[key]
rightPeopleImageMap[key] = value
}
for (let key in hiddenRightPeopleImageMap)
{
const value = hiddenRightPeopleImageMap[key]
rightPeopleImageMap[key] = value
}
// 置空数据
if (isLeftImageFolderChecked.value === true)
{
selectedImageFolderIdList = [currentPersonUnid]
}
else
{
selectedImageFolderIdList = []
}
leftSelectedImageIdList = []
rightSelectedImageIdList = []
allSelectedImageIdList = []
for (const peopleImage of leftPeopleImageList.value)
{
peopleImage['isSelected'] = false
}
}
)
}
const changeSelectedImageIdList = function(item, position) {
item['isSelected'] = !item['isSelected']
if (item['isSelected'] === true)
{
if (position === 'left')
{
leftSelectedImageIdList.push(item.id)
}
else
{
rightSelectedImageIdList.push(item.id)
}
}
else
{
if (position === 'left')
{
leftSelectedImageIdList.splice(leftSelectedImageIdList.indexOf(item.id), 1)
}
else
{
rightSelectedImageIdList.splice(rightSelectedImageIdList.indexOf(item.id), 1)
}
}
allSelectedImageIdList = leftSelectedImageIdList.concat(rightSelectedImageIdList)
}
const selectImage = function(id) {
for (let row of leftPagedTableData.value)
{
for (let item of row)
{
if (item.id === id)
{
changeSelectedImageIdList(item, 'left')
}
}
}
for (let key in rightPeopleImageMap)
{
const list = rightPeopleImageMap[key].list
for (let item of list)
{
if (item.id === id)
{
changeSelectedImageIdList(item, 'right')
}
}
}
}
const getValueOfRightPeopleImageMap = function(personUnid) {
for (const pUnid in rightPeopleImageMap)
{
const value = rightPeopleImageMap[pUnid]
if (pUnid === personUnid)
{
return value
}
}
}
const selectImageFolder = function(personUnid) {
if (selectedImageFolderIdList.includes(personUnid))
{
selectedImageFolderIdList.splice(selectedImageFolderIdList.indexOf(personUnid), 1)
if (personUnid !== currentPersonUnid)
{
getValueOfRightPeopleImageMap(personUnid).isSelected = false
}
}
else
{
selectedImageFolderIdList.push(personUnid)
if (personUnid !== currentPersonUnid)
{
getValueOfRightPeopleImageMap(personUnid).isSelected = true
}
}
}
const completeLabel = function() {
labelingApi.completeLabel(currentPersonUnid, packId).then(
(r) => {
message.info(r.msg)
}
)
webSocket.send('success')
nextPerson()
}
const confirmDeleteImages = function() {
Modal.confirm({
title: '确认要删除这些图片?',
icon: createVNode(ExclamationCircleOutlined),
okText: '是',
okType: 'danger',
cancelText: '否',
onOk() {
labelingApi.deleteImages(allSelectedImageIdList.toString(), packId).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
},
})
}
const goBack = function() {
router.push(
{
path: '/DataLabel/PeopleLabel',
query: filterEmptyValueInObject(
{
packId: packId,
pageNum: localStorage.getItem('pageNum'),
}
)
}
)
}
onBeforeUnmount(
() => {
labelingApi.exitLabeling(currentPersonUnid, packId)
webSocket.close()
}
)
const previousPerson = function() {
const data = {
personUnid: currentPersonUnid,
packId: packId,
status: status,
}
labelingApi.getPreviousPerson(data).then(
(r) => {
if (r.msg === '没有数据了')
{
message.info('没有数据了')
}
else
{
router.push(
{
path: '/DataLabel/Labeling',
query: {
packId: packId,
personUnid: Object.keys(r.data)[0],
status: status,
}
}
)
}
}
)
}
const nextPerson = function() {
const data = {
personUnid: currentPersonUnid,
packId: packId,
status: status,
}
labelingApi.getNextPerson(data).then(
(r) => {
if (r.msg === '没有数据了')
{
message.info('没有数据了')
}
else
{
router.push(
{
path: '/DataLabel/Labeling',
query: {
packId: packId,
personUnid: Object.keys(r.data)[0],
status: status,
}
}
)
}
}
)
}
const recycle = function() {
if (selectedImageFolderIdList.length === 0 && allSelectedImageIdList.length !== 0)
{
labelingApi.recycle(selectedImageFolderIdList[0], allSelectedImageIdList.toString(), packId).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
else if (selectedImageFolderIdList.length === 1)
{
labelingApi.recycle(selectedImageFolderIdList[0], allSelectedImageIdList.toString(), packId).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
else
{
message.info('选择格式错误')
}
}
const onFolderNumChange = function(v) {
localStorage.setItem('folderNum', v)
}
const onMinuteNumChange = function(v) {
localStorage.setItem('minuteNum', v)
}
const highQualityExtract = function() {
if (selectedImageFolderIdList.length === 0 && allSelectedImageIdList.length === 0)
{
message.info('选择格式错误')
}
else
{
labelingApi.highQualityExtract(selectedImageFolderIdList.toString(), allSelectedImageIdList.toString(), packId, currentPersonUnid).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
}
const lowQualityExtract = function() {
if (selectedImageFolderIdList.length === 0 && allSelectedImageIdList.length === 0)
{
message.info('选择格式错误')
}
else
{
const data = {
personUnidArr: selectedImageFolderIdList.toString(),
subTaskIdArr: allSelectedImageIdList.toString(),
packId: packId,
currentPerson: currentPersonUnid,
}
labelingApi.lowQualityExtract(data).then(
(r) => {
message.info(r.msg)
resetAll()
}
)
}
}
const initializeWebSocket = function() {
webSocket = new WebSocket(`ws://${window._serverHost}/reid/websocket/${packId}/${currentPersonUnid}`)
// webSocket.onmessage = function(event) {
// const rawData = event.data
// log(rawData)
// }
}
const previewImage = function(imageUrl) {
window.open(imageUrl)
}
const addShortcutKey = function(event) {
if (event.code === 'KeyQ')
{
confirmMerge()
}
}
const getDirectionTitle = function(v) {
switch (v)
{
case 1:
{
return '进'
}
case -1:
{
return '出'
}
default:
{
break
}
}
}
onBeforeUnmount(
() => {
document.removeEventListener('keydown', addShortcutKey)
}
)
const initialize = function() {
initializeWebSocket()
getPeopleImageList()
document.addEventListener('keydown', addShortcutKey)
}
initialize()
return {
// scalar
folderNum,
minuteNum,
isSearchLoading,
isMergeLoading,
ref_rightMain,
isLeftImageFolderChecked,
currentPersonUnid,
isFilterButtonShowed,
isFilteredDataShowed,
// sequence
leftPagedTableData,
// mapping
rightPeopleImageMap,
displayedRightPeopleImageMap,
hiddenRightPeopleImageMap,
// function
goBack,
confirmMerge,
confirmSearch,
selectImage,
getPagedList,
getImageUrl,
selectImageFolder,
completeLabel,
confirmDeleteImages,
previousPerson,
nextPerson,
previewImage,
recycle,
highQualityExtract,
lowQualityExtract,
onFolderNumChange,
onMinuteNumChange,
getFolderColor,
getFolderTitle,
getDirectionTitle,
}
}
}
</script>
<style lang="less" scoped>
@import "./Labeling.less";
</style>
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
}
<template>
<a-layout class="PeopleLabel">
<div style="display: flex;justify-content: space-between">
标注
<a-button @click="goBack">返回上一页</a-button>
</div>
<div>
图片数量:
<el-input v-model.trim="countGTE" @input="onCountGteChange" size="mini" style="width: 150px"></el-input>
<el-input v-model.trim="countLTE" @input="onCountLteChange" size="mini" style="width: 150px"></el-input>
<a-button @click="getPeopleImageFolderList" type="primary">搜索</a-button>
</div>
<div>
文件夹ID:
<el-input v-model.trim="searchedFolderId" size="mini" style="width: 300px"></el-input>
<a-button @click="searchFolder" type="primary">搜索</a-button>
</div>
<el-row>
<el-col :span="18">
<el-menu mode="horizontal" @select="onMenuSelect" :default-active="'1'">
<el-menu-item :index="'1'">
待标注
</el-menu-item>
<el-menu-item :index="'2'">
标注中
</el-menu-item>
<el-menu-item :index="'3'">
完成标注
</el-menu-item>
<el-menu-item :index="'-1'">
被回收
</el-menu-item>
<el-menu-item :index="'4'">
优质
</el-menu-item>
<el-menu-item :index="'7'">
低质
</el-menu-item>
<el-menu-item :index="''">
全部
</el-menu-item>
<el-menu-item :index="'我的完成标注'">
我的完成标注
</el-menu-item>
</el-menu>
</el-col>
<el-col :span="6" v-if="isReviewAccessed">
<el-button @click="confirmSubmitReview(6)" type="success" size="small">审核通过</el-button>
<el-button @click="confirmSubmitReview(5)" type="danger" size="small">审核驳回</el-button>
</el-col>
</el-row>
<div style="height: 100%; overflow: scroll" v-loading="isLoading">
<el-row v-for="row in pagedTableData">
<el-col :span="6" v-for="item in row">
<el-checkbox @change="selectImageFolder(Object.keys(item)[0])" v-if="isReviewAccessed" :key="Object.keys(item)[0]">选择文件夹</el-checkbox>
<div @click="enterLabeling(Object.keys(item)[0])"
class="folder"
:style="'border: 1px solid ' + getFolderColor(Object.values(item)[0][0].status)"
>
<div class="folder-title"
:style="'background: ' + getFolderColor(Object.values(item)[0][0].status)"
>
{{ getFolderTitle(Object.values(item)[0][0].status) }}
</div>
<div class="folder-body ">
<div class="folder-cover-image">
<el-image :src="getImageUrl(Object.values(item)[0][0].picId)"
:fit="'contain'"
style="height: 300px;">
</el-image>
</div>
<el-row>
<el-col :span="6" class="column-title-font">文件夹ID:</el-col>
<el-col :span="18">{{ Object.keys(item)[0] }}</el-col>
</el-row>
<el-row>
<el-col :span="6" class="column-title-font">标注人:</el-col>
<el-col :span="18">{{ Object.values(item)[0][0].labelUserName }}</el-col>
</el-row>
<el-row>
<el-col :span="6" class="column-title-font">图片数量:</el-col>
<el-col :span="18">{{ Object.values(item)[0].length }}</el-col>
</el-row>
<!-- <el-row>-->
<!-- <el-col :span="10" class="column-title-font">创建时间:</el-col>-->
<!-- <el-col :span="14">{{ item.createTime }}</el-col>-->
<!-- </el-row>-->
<!-- <el-row>-->
<!-- <el-col :span="10" class="column-title-font">完成时间:</el-col>-->
<!-- <el-col :span="14">2020-2-3 23:23:43</el-col>-->
<!-- </el-row>-->
</div>
</div>
</el-col>
</el-row>
<el-pagination @current-change="handlePageNumChange"
@size-change="handlePageSizeChange"
: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>
</div>
</a-layout>
</template>
<script>
import {computed, defineComponent, reactive, ref, toRefs, watch} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import peopleLabelApi from '@/views/DataLabel/PeopleLabel/PeopleLabelApi'
import {
formatPaginatedTableData,
getCountGte,
getCountLte, getFolderColor,
getFolderTitle,
getImageUrl,
getPagedList,
} from '@/PublicUtil/PublicUtil'
import {message} from 'ant-design-vue'
import router from '@/router'
import {isEmptyValue, isNotEmptyValue} from '@/PublicUtil/Judgment'
import {ElMessage} from 'element-plus'
export default defineComponent(
{
setup() {
const getPageNum = function() {
const pageNum = useRoute().query.pageNum
if (isEmptyValue(pageNum))
{
return 1
}
else
{
return pageNum
}
}
const pageNum = ref(getPageNum())
const pageSize = ref(12)
const total = ref(Number.MAX_SAFE_INTEGER)
const isLoading = ref(false)
const packId = useRoute().query.packId
const isReviewAccessed = useRoute().query.isReviewAccessed === 'true'
const router = useRouter()
const imageData = ref()
const countGTE = ref(getCountGte())
const countLTE = ref(getCountLte())
const searchedFolderId = ref()
let selectedMenuIndex = '1'
const pagedTableData = computed(
() => {
return getPagedList(peopleFolderList.value, 4)
}
)
// sequence
const peopleFolderList = ref([])
let selectedImageFolderIdList = []
// function
const handlePageNumChange = function(num) {
pageNum.value = num
selectedImageFolderIdList = []
getPeopleImageFolderList()
if (isNotEmptyValue(pageNum.value))
{
localStorage.setItem('pageNum', pageNum.value)
}
}
const handlePageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
selectedImageFolderIdList = []
getPeopleImageFolderList()
if (isNotEmptyValue(pageNum.value))
{
localStorage.setItem('pageNum', pageNum.value)
}
}
const enterLabeling = function(personUnid) {
peopleLabelApi.enterLabeling(personUnid, packId).then(
(r) => {
if (r.msg === '正在被其他人标注')
{
message.info('正在被其他人标注')
}
else
{
router.push(
{
path: '/DataLabel/Labeling',
query: {
packId: packId,
personUnid: personUnid,
status: selectedMenuIndex,
}
}
)
}
}
)
}
const getPeopleImageFolderList = function() {
isLoading.value = true
const data = {
packId: packId,
status: selectedMenuIndex === '我的完成标注' ? undefined : selectedMenuIndex,
annotatorId: selectedMenuIndex === '我的完成标注' ? localStorage.getItem('currentUserId') : undefined,
pageNum: pageNum.value,
pageSize: pageSize.value,
countGTE: getCountGte(),
countLTE: getCountLte(),
}
peopleLabelApi.getPeopleImageFolderList(data).then(
({data}) => {
formatPaginatedTableData(
peopleFolderList,
data,
total,
)
isLoading.value = false
}
)
}
const searchFolder = function() {
isLoading.value = true
const data = {
personUnid_like: searchedFolderId.value,
packId: packId,
}
peopleLabelApi.searchFolder(data).then(
({data}) => {
isLoading.value = false
let l = []
for (let key in data)
{
const value = data[key]
l.push(
{
[key]: value
}
)
}
peopleFolderList.value = l
// total.value = data.length
}
)
}
const goBack = function() {
router.push(
{
path: '/DataLabel/ImagePackage',
}
)
}
const getFolderTitleBorderColor = function(status) {
switch (status)
{
case 1:
{
return 'folder-title-toBeLabeled'
}
case 2:
{
return 'folder-title-labeling'
}
case 3:
{
return 'folder-title-labeled'
}
case -1:
{
return 'folder-title-beRecycled'
}
case 4:
{
return 'folder-title-highQuality'
}
default:
{
return ''
}
}
}
const onMenuSelect = function(index) {
selectedMenuIndex = index
getPeopleImageFolderList()
}
const onCountGteChange = function(v) {
localStorage.setItem('countGTE', v)
}
const onCountLteChange = function(v) {
localStorage.setItem('countLTE', v)
}
const selectImageFolder = function(personUnid) {
if (selectedImageFolderIdList.includes(personUnid))
{
selectedImageFolderIdList.splice(selectedImageFolderIdList.indexOf(personUnid), 1)
}
else
{
selectedImageFolderIdList.push(personUnid)
}
}
const confirmSubmitReview = function(status) {
const data = {
personUnidArr: selectedImageFolderIdList,
status: status,
}
peopleLabelApi.submitReview(data).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
}
)
}
const initialize = function() {
getPeopleImageFolderList()
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
imageData,
countGTE,
countLTE,
searchedFolderId,
isReviewAccessed,
// sequence
peopleFolderList,
pagedTableData,
// mapping
// function
handlePageNumChange,
handlePageSizeChange,
getPeopleImageFolderList,
goBack,
getFolderTitle,
getFolderColor,
getFolderTitleBorderColor,
enterLabeling,
onMenuSelect,
getImageUrl,
onCountGteChange,
onCountLteChange,
searchFolder,
selectImageFolder,
confirmSubmitReview,
}
},
}
)
</script>
<style lang="less" scoped>
@import "./PeopleLabel.less";
</style>
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-header style="height: 100px">
<div style="display:flex; justify-content: flex-end ">
<el-button @click="goBack">返回上一页</el-button>
</div>
<div style="font-size: 20px">
是否是一个人:{{ same }}
</div>
<el-row>
<el-col :span="12">
<span style="font-size: 20px">ID:{{ leftPersonUnid }}</span>
</el-col>
<el-col :span="12">
<span style="font-size: 20px">ID:{{ rightPersonUnid }}</span>
</el-col>
</el-row>
</el-header>
<el-main>
<el-container>
<el-aside :width="'50%'" style="border-right: red 1px solid">
<!-- <VirtualList-->
<!-- :dataList="leftPagedTableData"-->
<!-- :key="leftPagedTableData"-->
<!-- @imageClick="selectImage"-->
<!-- >-->
<!-- </VirtualList>-->
<el-row v-for="row in leftPagedTableData">
<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">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image">
</el-image>
</div>
</el-col>
</el-row>
</el-aside>
<el-main>
<!-- <VirtualList-->
<!-- :dataList="rightPagedTableData"-->
<!-- :key="rightPagedTableData"-->
<!-- @imageClick="selectImage"-->
<!-- >-->
<!-- </VirtualList>-->
<el-row v-for="row in rightPagedTableData">
<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">
<el-image :src="getImageUrl(item.picId)"
:fit="'contain'"
class="single-image">
</el-image>
</div>
</el-col>
</el-row>
</el-main>
</el-container>
</el-main>
<el-footer>
<div style="display: flex; justify-content:flex-end;height: 100%" class="flex-vertical-center">
<el-button @click="splitImage">拆分图片(Q)</el-button>
<el-button type="danger" @click="notSamePerson">不是一个人(A)</el-button>
<el-button type="primary" @click="samePerson">是一个人(D)</el-button>
</div>
</el-footer>
</el-container>
</template>
<script>
import {useRoute, useRouter} from 'vue-router'
import {
getPagedList,
getImageUrl,
} from '@/PublicUtil/PublicUtil'
import {computed, onBeforeUnmount, reactive, ref} from 'vue'
import labelingApi from '@/views/DataLabel/Labeling/LabelingApi'
import judgePeopleApi from '@/views/JudgePeople/JudgePeople'
import {ElMessage} from 'element-plus'
import dataCleanApi from '@/views/ClassAmongClean/ClassAmongClean'
import VirtualList from '@/views/DataLabel/Labeling/VirtualList/VirtualList'
export default {
components: {
VirtualList,
},
setup() {
const id = useRoute().query.id
const packId = useRoute().query.packId
const name = useRoute().query.name
const packName = useRoute().query.packName
const same = useRoute().query.same
const leftPersonUnid = useRoute().query.leftPersonId
const rightPersonUnid = useRoute().query.rightPersonId
const personId = useRoute().query.personId
const leftPeopleImageList = ref([])
const rightPeopleImageList = ref([])
let leftSelectedImageIdList = []
let rightSelectedImageIdList = []
let allSelectedImageIdList = []
const router = useRouter()
const leftPagedTableData = computed(
() => {
return getPagedList(leftPeopleImageList.value, 3)
}
)
const rightPagedTableData = computed(
() => {
return getPagedList(rightPeopleImageList.value, 3)
}
)
const getLeftPeopleImageList = function() {
labelingApi.getPeopleImageList(packId, leftPersonUnid).then(
(r) => {
leftPeopleImageList.value = r.data
for (const peopleImage of leftPeopleImageList.value)
{
peopleImage['isSelected'] = false
}
}
)
}
const getRightPeopleImageList = function() {
labelingApi.getPeopleImageList(packId, rightPersonUnid).then(
(r) => {
rightPeopleImageList.value = r.data
for (const peopleImage of rightPeopleImageList.value)
{
peopleImage['isSelected'] = false
}
}
)
}
const nextJudge = function() {
const data = {
packId: packId
}
dataCleanApi.getCleanAmongResult(data).then(
(r) => {
const data = r.data
if (r.code === 200)
{
router.push(
{
path: '/JudgePeople',
query: {
id: data.id,
packId: packId,
leftPersonId: data.personId,
rightPersonId: data.simPersonId,
}
}
)
}
else
{
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
}
}
)
}
const notSamePerson = function() {
judgePeopleApi.notSamePerson(id).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
if (r.code === 200)
{
nextJudge()
}
}
)
}
const samePerson = function() {
judgePeopleApi.samePerson(id).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
if (r.code === 200)
{
nextJudge()
}
}
)
}
const goBack = function() {
router.push(
{
path: '/ClassAmongClean',
query: {
packId: packId,
name: name,
packName: packName,
}
}
)
}
const splitImage = function() {
labelingApi.mergeImagesAsNewPerson(
allSelectedImageIdList.toString(),
packId
).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
window.location.reload()
}
)
}
const changeSelectedImageIdList = function(item, position) {
item['isSelected'] = !item['isSelected']
if (item['isSelected'] === true)
{
if (position === 'left')
{
leftSelectedImageIdList.push(item.id)
}
else
{
rightSelectedImageIdList.push(item.id)
}
}
else
{
if (position === 'left')
{
leftSelectedImageIdList.splice(leftSelectedImageIdList.indexOf(item.id), 1)
}
else
{
rightSelectedImageIdList.splice(rightSelectedImageIdList.indexOf(item.id), 1)
}
}
allSelectedImageIdList = leftSelectedImageIdList.concat(rightSelectedImageIdList)
allSelectedImageIdList = [...new Set(allSelectedImageIdList)]
}
const selectImage = function(id) {
for (let row of leftPagedTableData.value)
{
for (let item of row)
{
if (item.id === id)
{
changeSelectedImageIdList(item, 'left')
}
}
}
for (let row of rightPagedTableData.value)
{
for (let item of row)
{
if (item.id === id)
{
changeSelectedImageIdList(item, 'right')
}
}
}
}
const addShortcutKey = function(event) {
if (event.code === 'KeyA')
{
notSamePerson()
}
if (event.code === 'KeyD')
{
samePerson()
}
if (event.code === 'KeyQ')
{
splitImage()
}
}
onBeforeUnmount(
() => {
document.removeEventListener('keydown', addShortcutKey)
}
)
const initialize = function() {
getLeftPeopleImageList()
getRightPeopleImageList()
document.addEventListener('keydown', addShortcutKey)
}
initialize()
return {
// scalar
same,
leftPersonUnid,
rightPersonUnid,
// sequence
leftPagedTableData,
rightPagedTableData,
// mapping
// function
notSamePerson,
samePerson,
getImageUrl,
goBack,
splitImage,
selectImage,
}
}
}
</script>
<style lang="less" scoped>
@import "./JudgePeople.less";
</style>
<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-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>
<template>
<el-container class="ProjectManagement">
<el-header height="50px">
<div>
<span class="title-text">项目管理</span>
</div>
</el-header>
<el-main>
<el-button type="primary" @click="addProject">新建</el-button>
<el-menu mode="horizontal" @select="handleMenuSelect" :default-active="'1'">
<el-menu-item :index="'1'">
待标注
</el-menu-item>
</el-menu>
<el-table :data="projectList" v-loading="isLoading">
<el-table-column prop="name" label="名称" align="center"></el-table-column>
<el-table-column prop="description" label="备注" align="center"></el-table-column>
<el-table-column prop="status" label="状态" align="center">
<template #default="scope">
{{ getStatusTitle(scope.row.status) }}
</template>
</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="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="operation" label="操作" align="center">
<template #default="scope">
<el-button @click="startProject(scope.row.id)" type="text">开启</el-button>
<el-button @click="finishProject(scope.row.id)" type="text">结束</el-button>
<el-button @click="distributeBatch(scope.row.id)" type="text">分配批次</el-button>
<el-button @click="editProject(scope.row)" type="text">编辑</el-button>
<el-button @click="distributeProject(scope.row)" type="text">分配公司</el-button>
</template>
</el-table-column>
</el-table>
<el-drawer title="新建项目" v-model="addProjectVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="project-form">
<el-form :model="addProjectForm" :rules="rules" ref="ref_addProjectForm">
<el-form-item label="名称:" prop="name" :label-width="'120px'">
<el-input v-model.trim="addProjectForm.name"></el-input>
</el-form-item>
<el-form-item label="备注:" prop="description" :label-width="'120px'">
<el-input v-model.trim="addProjectForm.description" style="width: 100%"></el-input>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="addProjectVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmAddProject">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<el-drawer title="编辑项目" v-model="editProjectVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="project-form">
<el-form :model="editProjectForm" :rules="rules" ref="ref_editProjectForm">
<el-form-item label="名称:" prop="name" :label-width="'120px'">
<el-input v-model.trim="editProjectForm.name"></el-input>
</el-form-item>
<el-form-item label="备注:" prop="description" :label-width="'120px'">
<el-input v-model.trim="editProjectForm.description" style="width: 100%"></el-input>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="editProjectVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmEditProject">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<el-drawer title="分配公司" v-model="distributeProjectVisible" :destroy-on-close="true" :direction="'rtl'">
<div class="project-form">
<el-form :model="distributeProjectForm">
<el-form-item label="公司:" :label-width="'120px'">
<el-select v-model="distributeProjectForm.accountId" style="width: 100%">
<el-option v-for="(name, value) in companyMap" :label="name" :value="parseInt(value)"></el-option>
</el-select>
</el-form-item>
<el-form-item style="text-align:center">
<el-button @click="distributeProjectVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmDistributeProject">确 定</el-button>
</el-form-item>
</el-form>
</div>
</el-drawer>
<el-drawer title="分配批次" v-model="distributeBatchVisible" :size="'35%'" :destroy-on-close="true" :direction="'rtl'">
<div class="project-form">
<el-transfer v-model="usedBatchList"
:data="allBatchList"
:titles="['未分配', '已分配']"
@change="onBatchListChange"
/>
</div>
</el-drawer>
</el-main>
</el-container>
</template>
<script>
import {reactive, ref, toRaw,} from "vue"
import {
emptyList,
filterEmptyValueInObject, getKeyByValueInObject,
resetForm
} from "@/PublicUtil/PublicUtil"
import projectApi from './ProjectManagementApi'
import {ElMessageBox} from 'element-plus'
import {ElMessage} from 'element-plus'
import {getCompanyMap} from '@/Request/DictionaryRequest'
export default {
setup() {
// scalar
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref()
const isLoading = ref(false)
const addProjectVisible = ref(false)
const editProjectVisible = ref(false)
const distributeProjectVisible = ref(false)
const distributeBatchVisible = ref(false)
let selectedMenuIndex = '1'
const ref_addProjectForm = ref()
const ref_editProjectForm = ref()
let currentTaskId = undefined
// sequence
const projectList = ref([])
const usedBatchList = ref([])
const allBatchList = ref([])
// mapping
const rules = reactive(
{
// projectName: [
// {
// required: true,
// message: '请输入项目名称',
// },
// ],
// projectYear: [
// {
// type: 'date',
// required: true,
// message: '请输入建成年份',
// trigger: 'change'
// }
// ],
// groupId: [
// {
// required: true,
// message: '请选择集团',
// },
// ],
}
)
const companyMap = reactive({})
const addProjectForm = reactive(
{
name: '',
description: '',
}
)
const editProjectForm = reactive(
{
name: '',
description: '',
id: '',
}
)
const distributeProjectForm = reactive(
{
accountId: '',
id: '',
}
)
// function
const handlePageNumChange = function(num) {
pageNum.value = num
getProjectList()
}
const handlePageSizeChange = function(size) {
pageNum.value = 1
pageSize.value = size
getProjectList()
}
const confirmAddProject = function() {
ref_addProjectForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(addProjectForm)
const data = filterEmptyValueInObject(rawData)
projectApi.addProject(data).then(
(r) => {
addProjectVisible.value = false
const message = r.msg
ElMessage(`${message}`)
getProjectList()
}
)
}
}
)
}
const confirmDistributeProject = function() {
const rawData = toRaw(distributeProjectForm)
const data = filterEmptyValueInObject(
{
accountId: rawData.accountId
}
)
projectApi.editProject(rawData.id, data).then(
(r) => {
distributeProjectVisible.value = false
const message = r.msg
ElMessage(`${message}`)
getProjectList()
}
)
}
const editProject = function(row) {
log(row)
editProjectVisible.value = true
editProjectForm.name = row.name
editProjectForm.description = row.description
editProjectForm.id = row.id
}
const confirmEditProject = function() {
ref_editProjectForm.value.validate(
(isValid) => {
if (isValid)
{
const rawData = toRaw(editProjectForm)
const data = filterEmptyValueInObject(
{
name: rawData.name,
description: rawData.description,
}
)
projectApi.editProject(rawData.id, data).then(
(r) => {
const message = r.msg
getProjectList()
ElMessage(`${message}`)
}
)
editProjectVisible.value = false
}
}
)
}
const distributeProject = function(row) {
distributeProjectVisible.value = true
distributeProjectForm.id = row.id
distributeProjectForm.accountId = row.accountId
}
const addProject = function() {
resetForm(addProjectForm)
addProjectVisible.value = true
}
const getProjectList = function() {
isLoading.value = true
projectApi.getProjectList().then(
({data}) => {
isLoading.value = false
projectList.value = data
// formatPaginatedTableData(
// projectList,
// data,
// total,
// )
}
)
}
const onBatchListChange = function(v, direction, changedList) {
const data = {
taskId: currentTaskId,
packIds: changedList.toString(),
}
if (direction === 'right') // add
{
projectApi.distributeBatch(data).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
}
)
}
else // delete
{
projectApi.cancelDistributeBatch(data).then(
(r) => {
const message = r.msg
ElMessage(
{
message: `${message}`,
}
)
}
)
}
}
const distributeBatch = function(id) {
distributeBatchVisible.value = true
currentTaskId = id
emptyList(allBatchList.value)
emptyList(usedBatchList.value)
projectApi.getUsedBatchList(id).then(
({data}) => {
for (const item of data)
{
usedBatchList.value.push(item.id)
allBatchList.value.push(
{
key: item.id,
label: item.name,
}
)
}
}
)
projectApi.getUnusedBatchList().then(
({data}) => {
for (const item of data)
{
allBatchList.value.push(
{
key: item.id,
label: item.name,
}
)
}
}
)
}
const handleMenuSelect = function(index) {
selectedMenuIndex = index
getProjectList()
}
const startProject = function(id) {
ElMessageBox.confirm(
"确定开始项目?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
projectApi.startProject(id).then(
(r) => {
const message = r.msg
getProjectList()
ElMessage(`${message}`)
}
)
}
)
}
const finishProject = function(id) {
ElMessageBox.confirm(
"确定结束项目?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}
).then(
() => {
projectApi.finishProject(id).then(
(r) => {
const message = r.msg
getProjectList()
ElMessage(`${message}`)
}
)
}
)
}
const getStatusTitle = function(status) {
switch (status)
{
case 0:
{
return '结束中'
}
case 1:
{
return '开始中'
}
default:
{
break
}
}
}
const initialize = function() {
getProjectList()
getCompanyMap(companyMap)
}
initialize()
return {
// scalar
pageNum,
pageSize,
total,
isLoading,
projectList,
ref_addProjectForm,
ref_editProjectForm,
addProjectVisible,
editProjectVisible,
distributeProjectVisible,
distributeBatchVisible,
// sequence
usedBatchList,
allBatchList,
// mapping
companyMap,
addProjectForm,
editProjectForm,
distributeProjectForm,
rules,
// function
handlePageNumChange,
handlePageSizeChange,
addProject,
editProject,
confirmEditProject,
confirmAddProject,
confirmDistributeProject,
distributeProject,
getKeyByValueInObject,
distributeBatch,
handleMenuSelect,
onBatchListChange,
startProject,
finishProject,
getStatusTitle,
}
},
}
</script>
<style lang="less" scoped>
@import "./ProjectManagement.less";
</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!