|
@@ -2,8 +2,7 @@
|
|
|
<div class="table-box">
|
|
|
<ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listDataApi" :init-param="initParam">
|
|
|
<template #yuan="scope">
|
|
|
- <uploadImg :is-show-data="true" :disabled="true" :image-url="scope.row.url" />
|
|
|
- <!-- <el-image style="width: 100px" :src="'/api' + scope.row.url" @click="markImg(scope.row)" />-->
|
|
|
+ <el-image style="width: 100px" :src="'/api' + scope.row.url" @click="markImg(scope.row)" />
|
|
|
</template>
|
|
|
<!-- 表格 header 按钮 -->
|
|
|
<template #tableHeader="scope">
|
|
@@ -25,7 +24,6 @@
|
|
|
<!-- 表格操作 -->
|
|
|
<template #operation="scope">
|
|
|
<!-- <el-button type="primary" link :icon="EditPen" v-auth="['demo:data:edit']" @click="openDialog(2, '数据标注', scope.row)"> 标注 </el-button> -->
|
|
|
- <el-button type="primary" link :icon="EditPen" v-auth="['demo:data:edit']" @click="markImg(scope.row)"> 标注 </el-button>
|
|
|
<el-button type="primary" link :icon="EditPen" v-auth="['demo:data:edit']" @click="openDialog(2, '数据编辑', scope.row)"> 编辑 </el-button>
|
|
|
<el-button type="primary" link :icon="View" v-auth="['demo:data:query']" @click="openDialog(3, '数据查看', scope.row)"> 查看 </el-button>
|
|
|
<el-button type="primary" link :icon="Delete" v-auth="['demo:data:remove']" @click="deleteData(scope.row)"> 删除 </el-button>
|
|
@@ -34,22 +32,12 @@
|
|
|
|
|
|
<FormDialog ref="formDialogRef" />
|
|
|
<ImportPicDataset ref="dialogRef" />
|
|
|
- <ImgDetect
|
|
|
- ref="imgDetect"
|
|
|
- :img="cover"
|
|
|
- :area="area"
|
|
|
- :width="width"
|
|
|
- :height="height"
|
|
|
- @success="handleImgSuccess"
|
|
|
- :classes="classes"
|
|
|
- :json-data="jsonData"
|
|
|
- >
|
|
|
- </ImgDetect>
|
|
|
+ <ImgDetect ref="imgDetect" :img="cover" :area="area" :width="width" :height="height" @success="handleImgSuccess"></ImgDetect>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="tsx" name="Data">
|
|
|
-import { ref, reactive, toRefs, onMounted } from 'vue'
|
|
|
+import { ref, reactive, toRefs } from 'vue'
|
|
|
import { useHandleData } from '@/hooks/useHandleData'
|
|
|
import { useDownload } from '@/hooks/useDownload'
|
|
|
import { useRouter } from 'vue-router'
|
|
@@ -61,9 +49,7 @@ import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
|
|
|
import { Delete, EditPen, Download, Upload, View, CirclePlus } from '@element-plus/icons-vue'
|
|
|
// import { fabric } from 'fabric'
|
|
|
import { useDrawArea } from '@/utils/fabric'
|
|
|
-import { getDictsApi } from '@/api/modules/system/dictData'
|
|
|
import ImgDetect from '../components/img-detect.vue'
|
|
|
-import uploadImg from '@/components/Upload/Img.vue'
|
|
|
import {
|
|
|
listDataApi,
|
|
|
getFormSelectsApi,
|
|
@@ -75,43 +61,15 @@ import {
|
|
|
exportDataApi,
|
|
|
getDataApi
|
|
|
} from '@/api/modules/demo/data'
|
|
|
-import { listDataApi as listDictDataApi } from '@/api/modules/system/dictData'
|
|
|
-import { uploadPure } from '@/api/modules/upload'
|
|
|
-import http from '@/api'
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- state.cacheData.url = 'http://localhost:9090/profile/upload/2024/08/08/144745610/test.png'
|
|
|
- // handleImgSuccess({
|
|
|
- // data: 'test change data',
|
|
|
- // jsonData: 'jsonData12345 test change',
|
|
|
- // url: 'testurl'
|
|
|
- // })
|
|
|
-})
|
|
|
|
|
|
const imgDetect = ref()
|
|
|
const state = reactive({
|
|
|
area: '' as string,
|
|
|
width: 1920 as number,
|
|
|
height: 1080 as number,
|
|
|
- cover: '',
|
|
|
- classes: [],
|
|
|
- // [
|
|
|
- // {
|
|
|
- // name: '飞机',
|
|
|
- // color: '#ea5413',
|
|
|
- // label: 'plane'
|
|
|
- // },
|
|
|
- // {
|
|
|
- // name: '汽车',
|
|
|
- // color: '#ff00ff',
|
|
|
- // label: 'car'
|
|
|
- // }
|
|
|
- // ],
|
|
|
- jsonData: [],
|
|
|
- cacheData: {}
|
|
|
- // '{"version":"5.3.0","objects":[{"type":"image","version":"5.3.0","originX":"left","originY":"top","left":0,"top":0,"width":918,"height":789,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":0.68,"scaleY":0.68,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"cropX":0,"cropY":0,"src":"http://localhost:8848/api/profile/upload/2024/08/08/144745610/3-3.jpg","crossOrigin":null,"filters":[]},{"type":"rect","version":"5.3.0","originX":"left","originY":"top","left":181.38,"top":251.38,"width":244,"height":162,"fill":"rgba(255, 255, 255, 0)","stroke":"#E34F51","strokeWidth":5,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":-25,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"rx":0,"ry":0}]}'
|
|
|
+ cover: ''
|
|
|
})
|
|
|
-const { area, width, height, cover, classes, jsonData } = toRefs(state)
|
|
|
+const { area, width, height, cover } = toRefs(state)
|
|
|
|
|
|
// ProTable 实例
|
|
|
const proTable = ref<ProTableInstance>()
|
|
@@ -127,107 +85,17 @@ const deleteData = async (params: any) => {
|
|
|
|
|
|
// 标注图片
|
|
|
const markImg = data => {
|
|
|
- // console.log(data)
|
|
|
- state.cacheData = data
|
|
|
- state.jsonData = []
|
|
|
- if (!data.url || data.url.length === 0) {
|
|
|
- ElMessage.warning('缺失图像,暂时不能进行区域添加!')
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- listDictDataApi({
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 10,
|
|
|
- dictType: 'class_definition'
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- // console.log(res)
|
|
|
- state.classes = []
|
|
|
- for (let i = 0; i < res.data.list.length; i++) {
|
|
|
- state.classes.push({
|
|
|
- name: res.data.list[i].dictLabel,
|
|
|
- color: res.data.list[i].cssClass,
|
|
|
- label: res.data.list[i].dictValue
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- if (state.cacheData.labelurl && state.cacheData.labelurl.length > 0) {
|
|
|
- // console.log('get label jsonData')
|
|
|
- http
|
|
|
- .get<any>(state.cacheData.labelurl)
|
|
|
- .then(res => {
|
|
|
- state.jsonData = []
|
|
|
- console.log(res)
|
|
|
- let arr = res.split('\r\n')
|
|
|
- console.log(arr)
|
|
|
- for (let i = 0; i < arr.length; i++) {
|
|
|
- let subArr = arr[i].split(' ')
|
|
|
- // console.log(subArr)
|
|
|
- let cssVal = '#000000'
|
|
|
- let label = '-1'
|
|
|
- for (let j = 0; j < state.classes.length; j++) {
|
|
|
- if (state.classes[j].label === subArr[0]) {
|
|
|
- cssVal = state.classes[j].color
|
|
|
- label = state.classes[j].label
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- state.jsonData.push({
|
|
|
- pathString:
|
|
|
- 'M ' +
|
|
|
- subArr[1] * 1920 +
|
|
|
- ' ' +
|
|
|
- subArr[2] * 1080 +
|
|
|
- ' L ' +
|
|
|
- subArr[3] * 1920 +
|
|
|
- ' ' +
|
|
|
- subArr[4] * 1080 +
|
|
|
- ' L ' +
|
|
|
- subArr[5] * 1920 +
|
|
|
- ' ' +
|
|
|
- subArr[6] * 1080 +
|
|
|
- ' L ' +
|
|
|
- subArr[7] * 1920 +
|
|
|
- ' ' +
|
|
|
- subArr[8] * 1080 +
|
|
|
- ' z',
|
|
|
- // left: 0,
|
|
|
- // top: 0,
|
|
|
- fill: '',
|
|
|
- stroke: cssVal,
|
|
|
- strokeWidth: 5,
|
|
|
- label: label
|
|
|
- })
|
|
|
- }
|
|
|
- // console.log(state.jsonData)
|
|
|
- imgDetect.value.visible = true
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.log(err)
|
|
|
- })
|
|
|
- } else {
|
|
|
- imgDetect.value.visible = true
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.log(err)
|
|
|
- })
|
|
|
-
|
|
|
state.cover = '/api' + data.url
|
|
|
-
|
|
|
// area 代表后端的传来的标注数据
|
|
|
- // console.log(state.cover)
|
|
|
-
|
|
|
- // const area = []
|
|
|
- // if (state.cover != '') {
|
|
|
- // if (area.length != 0) {
|
|
|
- // handleImgSuccess(area)
|
|
|
- // }
|
|
|
- //
|
|
|
- // console.log("true???")
|
|
|
- // } else {
|
|
|
- // ElMessage.warning('缺失图像,暂时不能进行区域添加!')
|
|
|
- // }
|
|
|
+ const area = []
|
|
|
+ if (state.cover != '') {
|
|
|
+ if (area.length != 0) {
|
|
|
+ handleImgSuccess(area)
|
|
|
+ }
|
|
|
+ imgDetect.value.visible = true
|
|
|
+ } else {
|
|
|
+ ElMessage.warning('缺失图像,暂时不能进行区域添加!')
|
|
|
+ }
|
|
|
}
|
|
|
const initParam = reactive({ type: 1 })
|
|
|
|
|
@@ -246,72 +114,18 @@ const getList = () => {
|
|
|
})
|
|
|
}
|
|
|
const handleImgSuccess = data => {
|
|
|
- // console.log(data)
|
|
|
- state.jsonData = data['jsonData']
|
|
|
- state.cover = data['url']
|
|
|
-
|
|
|
- state.cacheData.labelurl = data['data']
|
|
|
-
|
|
|
- state.cacheData.increment = 'NONE'
|
|
|
-
|
|
|
- let arr = state.cacheData.url.split('upload')
|
|
|
- // console.log(arr)
|
|
|
- let filenames = arr[arr.length - 1].split('.')
|
|
|
- filenames[filenames.length - 1] = 'txt'
|
|
|
- // console.log(filenames.join('.'))
|
|
|
- let filename = filenames.join('.')
|
|
|
- filename = filename.replace(/\\/g, '/')
|
|
|
- if (filename.startsWith('/')) {
|
|
|
- filename = filename.substring(1)
|
|
|
- }
|
|
|
- // console.log(filename)
|
|
|
-
|
|
|
- labelFile(data['data'], filename).then(res => {
|
|
|
- // console.log(res)
|
|
|
- if (res.code === 200) {
|
|
|
- state.cacheData.labelurl = res.data.url
|
|
|
- updateDataApi(state.cacheData)
|
|
|
- .then(res => {
|
|
|
- // console.log(res)
|
|
|
- if (res.data) {
|
|
|
- ElMessage.success('操作成功')
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.log(err)
|
|
|
- })
|
|
|
- }
|
|
|
+ data.forEach(item => {
|
|
|
+ const area = item.split(';')
|
|
|
+ // try=tly blx=tlx brx=trx bry=bly
|
|
|
+ const tlx = Math.round(Number(area[0]) * 1920)
|
|
|
+ const tly = Math.round(Number(area[1]) * 1080)
|
|
|
+ const trx = tlx + Math.round(Number(area[2]) * 1920)
|
|
|
+ const bly = tly + Math.round(Number(area[3]) * 1080)
|
|
|
+ state.area += `${tlx};${tly};${trx};${tly};${trx};${bly};${tlx};${bly},`
|
|
|
})
|
|
|
-
|
|
|
- // data.forEach(item => {
|
|
|
- // if (item.startsWith('{')) {
|
|
|
- // return
|
|
|
- // }
|
|
|
- // const area = item.split(';')
|
|
|
- // // try=tly blx=tlx brx=trx bry=bly
|
|
|
- // // mark: 当前用的应该是左上角定点位置和长宽,应该替换为存储点
|
|
|
- // const tlx = Math.round(Number(area[0]) * 1920)
|
|
|
- // const tly = Math.round(Number(area[1]) * 1080)
|
|
|
- // const trx = tlx + Math.round(Number(area[2]) * 1920)
|
|
|
- // const bly = tly + Math.round(Number(area[3]) * 1080)
|
|
|
- // state.area += `${tlx};${tly};${trx};${tly};${trx};${bly};${tlx};${bly},`
|
|
|
- // })
|
|
|
- // // console.log('state.area', state.area)
|
|
|
- // state.area.slice(0, -1)
|
|
|
- // getList()
|
|
|
-}
|
|
|
-
|
|
|
-// 创建并提交标注txt文件
|
|
|
-const labelFile = (data, filename) => {
|
|
|
- // 创建Blob对象
|
|
|
- const blob = new Blob([data], { type: 'text/plain' })
|
|
|
-
|
|
|
- // 创建表单数据并添加文件
|
|
|
- const formData = new FormData()
|
|
|
-
|
|
|
- formData.append('file', blob, filename)
|
|
|
-
|
|
|
- return uploadPure(formData)
|
|
|
+ // console.log('state.area', state.area)
|
|
|
+ state.area.slice(0, -1)
|
|
|
+ getList()
|
|
|
}
|
|
|
|
|
|
// 批量删除数据管理信息
|