index.vue 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. <template>
  2. <div class="table-box">
  3. <ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listAlgorithmTaskTrackApi">
  4. <!-- 表格 header 按钮 -->
  5. <template #tableHeader="scope">
  6. <el-button type="primary" v-auth="['demo:algorithmTaskTrack:add']" icon="CirclePlus" @click="dialogVisibleAddTask = true"> 新增 </el-button>
  7. <!-- <el-button type="primary" v-auth="['demo:algorithmTaskTrack:import']" icon="Upload" plain @click="batchAdd"> 导入-->
  8. <!-- </el-button>-->
  9. <!-- <el-button type="primary" v-auth="['demo:algorithmTaskTrack:export']" icon="Download" plain @click="downloadFile"> 导出-->
  10. <!-- </el-button>-->
  11. <el-button
  12. type="danger"
  13. v-auth="['demo:algorithmTaskTrack:remove']"
  14. icon="Delete"
  15. plain
  16. :disabled="!scope.isSelected"
  17. @click="batchDelete(scope.selectedListIds)"
  18. >
  19. 批量删除
  20. </el-button>
  21. </template>
  22. <!-- 表格操作 -->
  23. <template #operation="scope">
  24. <el-button type="primary" link icon="View" v-auth="['demo:algorithmTaskTrack:query']" @click="openViewDialog(scope.row)"> 查看 </el-button>
  25. <!-- <el-button-->
  26. <!-- type="primary"-->
  27. <!-- link-->
  28. <!-- icon="EditPen"-->
  29. <!-- v-auth="['demo:algorithmTaskTrack:edit']"-->
  30. <!-- @click="openDialog(2, '可辨识性分析总任务编辑', scope.row)"-->
  31. <!-- >-->
  32. <!-- 编辑-->
  33. <!-- </el-button>-->
  34. <el-button type="primary" link icon="Delete" v-auth="['demo:algorithmTaskTrack:remove']" @click="deleteAlgorithmTaskTrack(scope.row)">
  35. 删除
  36. </el-button>
  37. </template>
  38. </ProTable>
  39. <FormDialog ref="formDialogRef" />
  40. <ImportExcel ref="dialogRef" />
  41. <el-dialog v-model="dialogVisibleAddTask" title="可辨识性分析总任务新增" width="700" @open="handleOpenAddTask()" :before-close="handleClose">
  42. <el-form ref="formAddTaskRef" :model="formAddTask" :rules="rulesAddTask" label-width="auto" style="max-width: 600px">
  43. <el-form-item label="任务名称" prop="name">
  44. <el-input v-model="formAddTask.name" placeholder="请输入任务名称" />
  45. </el-form-item>
  46. <el-form-item label="是否转红外" prop="ifToInfrared">
  47. <el-checkbox v-model="formAddTask.ifToInfrared" @click="setIfToInfrared()" />
  48. </el-form-item>
  49. <el-form-item label="选择转红外算法" v-show="formAddTask.ifToInfrared" prop="toInfraredAlgorithmId">
  50. <div class="form-item1">
  51. <el-select v-model="formAddTask.toInfraredAlgorithmId" placeholder="请选择转红外算法" clearable>
  52. <el-option v-for="item in enumsAlgorithmConfigTrack_toInfrared" :key="item.value" :label="item.label" :value="item.value" />
  53. </el-select>
  54. <el-button
  55. @click="setAlgorithmParams(formAddTask.toInfraredAlgorithmId, 'toInfraredAlgorithmParams')"
  56. style="margin-left: 10px"
  57. :disabled="formAddTask.toInfraredAlgorithmId == undefined || formAddTask.toInfraredAlgorithmId == ''"
  58. >
  59. <SvgIcon :name="'Setting'" style="margin-right: 5px" />
  60. 设置算法参数
  61. </el-button>
  62. </div>
  63. </el-form-item>
  64. <el-form-item label="选择可见光转红外模型" v-show="formAddTask.ifToInfrared" prop="toInfraredModelId">
  65. <el-select v-model="formAddTask.toInfraredModelId" placeholder="请选择可见光转红外模型" clearable>
  66. <el-option v-for="item in toInfraredModelList" :key="item.value" :label="item.label" :value="item.value" />
  67. </el-select>
  68. </el-form-item>
  69. <el-form-item label="选择数据集" prop="inputDatasetOssId">
  70. <el-select v-model="formAddTask.inputDatasetOssId" placeholder="请选择数据集" clearable>
  71. <el-option v-for="item in datasetList" :key="item.value" :label="item.label" :value="item.value" />
  72. </el-select>
  73. </el-form-item>
  74. <el-form-item label="上传数据集" prop="inputDatasetOssId">
  75. <File ref="fileUploadRef" :file-type="['zip']" :file-size="4096" @update:model-value="fileUploadDatasetChange" />
  76. </el-form-item>
  77. <el-form-item label="选择视觉算法" prop="trackSequenceAlgorithmId">
  78. <div class="form-item1">
  79. <el-select v-model="formAddTask.trackSequenceAlgorithmId" placeholder="请选择视觉算法" clearable>
  80. <el-option v-for="item in visionAlgorithmList" :key="item.value" :label="item.label" :value="item.value" />
  81. </el-select>
  82. <el-button
  83. @click="setAlgorithmParams(formAddTask.trackSequenceAlgorithmId, 'trackSequenceAlgorithmParams')"
  84. style="margin-left: 10px"
  85. :disabled="formAddTask.trackSequenceAlgorithmId == undefined || formAddTask.trackSequenceAlgorithmId == ''"
  86. >
  87. <SvgIcon :name="'Setting'" style="margin-right: 5px" />
  88. 设置算法参数
  89. </el-button>
  90. </div>
  91. </el-form-item>
  92. <el-form-item label="选择目标检测模型" prop="TD_modelId">
  93. <el-select v-model="formAddTask.TD_modelId" placeholder="请选择目标检测模型" clearable>
  94. <el-option v-for="item in targetDetectionModelList" :key="item.value" :label="item.label" :value="item.value" />
  95. </el-select>
  96. </el-form-item>
  97. <el-form-item label="选择视觉算法模型" prop="trackSequenceModelId">
  98. <el-select v-model="formAddTask.trackSequenceModelId" placeholder="请选择视觉算法模型" clearable>
  99. <el-option v-for="item in visionAlgorithmModelList" :key="item.value" :label="item.label" :value="item.value" />
  100. </el-select>
  101. </el-form-item>
  102. <el-form-item label="是否评估" prop="ifEvaluate">
  103. <el-checkbox v-model="formAddTask.ifEvaluate" />
  104. </el-form-item>
  105. <el-form-item label="上传真实标签" prop="inputEvaluateLabelOssId" v-show="formAddTask.ifEvaluate">
  106. <File ref="fileUploadEvaluateLabelRef" :file-type="['txt']" :file-size="4096" @update:model-value="fileUploadChangeEvaluateLabel" />
  107. </el-form-item>
  108. <el-form-item label="选择视觉评估算法" prop="trackSequenceEvaluateAlgorithmId" v-show="formAddTask.ifEvaluate">
  109. <div class="form-item1">
  110. <el-select v-model="formAddTask.trackSequenceEvaluateAlgorithmId" placeholder="请选择视觉评估算法" clearable>
  111. <el-option v-for="item in visionEvaluateAlgorithmList" :key="item.value" :label="item.label" :value="item.value" />
  112. </el-select>
  113. <el-button
  114. @click="setAlgorithmParams(formAddTask.trackSequenceEvaluateAlgorithmId, 'trackSequenceEvaluateAlgorithmParams')"
  115. style="margin-left: 10px"
  116. :disabled="formAddTask.trackSequenceEvaluateAlgorithmId == undefined || formAddTask.trackSequenceEvaluateAlgorithmId == ''"
  117. >
  118. <SvgIcon :name="'Setting'" style="margin-right: 5px" />
  119. 设置算法参数
  120. </el-button>
  121. </div>
  122. </el-form-item>
  123. <el-form-item label="备注" prop="remarks">
  124. <el-input v-model="formAddTask.remarks" placeholder="请输入备注" />
  125. </el-form-item>
  126. </el-form>
  127. <template #footer>
  128. <el-button @click="dialogVisibleAddTask = false">取消</el-button>
  129. <el-button type="primary" @click="addAlgorithmTaskTrack"> 确定</el-button>
  130. </template>
  131. </el-dialog>
  132. <el-dialog v-model="dialogVisibleView" @open="handleOpenView()" title="可辨识性分析总任务查看" width="90%">
  133. <div style="width: 100%; height: auto; overflow: auto">
  134. <el-table :data="viewData" border height="500px">
  135. <el-table-column prop="id" label="主键ID" width="180" />
  136. <el-table-column prop="name" label="任务名称" width="150">
  137. <template #default="scope">
  138. <el-tooltip :content="scope.row.name" raw-content placement="top-start" v-if="scope.row.name">
  139. <span>{{ scope.row.name && scope.row.name.length > 15 ? scope.row.name.substring(0, 15) + '...' : scope.row.name }} </span>
  140. </el-tooltip>
  141. </template>
  142. </el-table-column>
  143. <el-table-column prop="status" label="任务状态" width="150">
  144. <template #default="scope">
  145. <el-tag type="success">
  146. {{ Status__[scope.row.status] }}
  147. </el-tag>
  148. </template>
  149. </el-table-column>
  150. <el-table-column prop="type" label="类型" width="120">
  151. <template #default="scope">
  152. <el-tag type="success">
  153. {{ AlgorithmType[scope.row.type] }}
  154. </el-tag>
  155. </template>
  156. </el-table-column>
  157. <el-table-column prop="subsystem" label="分系统" width="200">
  158. <template #default="scope">
  159. <el-tag type="success">
  160. {{ SubSystem[scope.row.subsystem] }}
  161. </el-tag>
  162. </template>
  163. </el-table-column>
  164. <el-table-column prop="algorithmName" label="算法名称" width="200" />
  165. <el-table-column prop="modelName" label="模型名称" width="200" />
  166. <el-table-column prop="algorithmParameters" label="算法参数" width="150">
  167. <template #default="scope">
  168. <el-tooltip :content="scope.row.algorithmParameters" raw-content placement="top-start" v-if="scope.row.algorithmParameters">
  169. <span
  170. >{{
  171. scope.row.outputPath && scope.row.algorithmParameters.length > 15
  172. ? scope.row.algorithmParameters.substring(0, 15) + '...'
  173. : scope.row.algorithmParameters
  174. }}
  175. </span>
  176. </el-tooltip>
  177. </template>
  178. </el-table-column>
  179. <el-table-column prop="startTime" label="开始时间" width="180" />
  180. <el-table-column prop="endTime" label="结束时间" width="180" />
  181. <el-table-column prop="costSecond" label="耗时" width="120" />
  182. <el-table-column prop="log" label="日志" width="120">
  183. <template #default="scope">
  184. <el-tooltip :content="scope.row.log" raw-content placement="top-start" v-if="scope.row.log">
  185. <span>{{ scope.row.outputPath && scope.row.log.length > 15 ? scope.row.log.substring(0, 15) + '...' : scope.row.log }} </span>
  186. </el-tooltip>
  187. </template>
  188. </el-table-column>
  189. <el-table-column prop="outputPath" label="输出路径" width="120">
  190. <template #default="scope">
  191. <el-tooltip :content="scope.row.outputPath" raw-content placement="top-start" v-if="scope.row.outputPath">
  192. <span
  193. >{{
  194. scope.row.outputPath && scope.row.outputPath.length > 15 ? scope.row.outputPath.substring(0, 15) + '...' : scope.row.outputPath
  195. }}
  196. </span>
  197. </el-tooltip>
  198. </template>
  199. </el-table-column>
  200. <el-table-column prop="remarks" label="备注" width="120" />
  201. <el-table-column prop="operation" label="操作" width="300" fixed="right">
  202. <template #default="scope">
  203. <el-button
  204. type="primary"
  205. link
  206. icon="View"
  207. v-if="scope.row.status == '0' || scope.row.status == '3' || scope.row.status == '4'"
  208. @click="startSubTask(scope.row)"
  209. >
  210. 开始
  211. </el-button>
  212. <el-popconfirm title="确定终止此任务吗?" @confirm="stopSubTask(scope.row)" v-if="scope.row.status == '1'">
  213. <template #reference>
  214. <el-button type="primary" link icon="Delete"> 终止</el-button>
  215. </template>
  216. </el-popconfirm>
  217. <el-button type="primary" link icon="View" @click="openLogSubTask(scope.row)" v-if="scope.row.status != '0'"> 日志 </el-button>
  218. <el-button
  219. type="primary"
  220. link
  221. icon="View"
  222. v-if="scope.row.status == '2' && scope.row.type == AlgorithmType2['预测/推理']"
  223. @click="previewSubTask(scope.row)"
  224. >
  225. 预览
  226. </el-button>
  227. <el-button
  228. type="primary"
  229. link
  230. icon="View"
  231. v-if="scope.row.status == '2' && scope.row.type == AlgorithmType2['预测/推理']"
  232. @click="showStatisticResultSubTask(scope.row)"
  233. >
  234. 结果
  235. </el-button>
  236. <el-button
  237. type="primary"
  238. link
  239. icon="View"
  240. v-if="scope.row.status == '2' && scope.row.type == AlgorithmType2['测试']"
  241. @click="showEvaluateResultSubTask(scope.row.id)"
  242. >
  243. 结果
  244. </el-button>
  245. <el-button
  246. type="primary"
  247. link
  248. icon="View"
  249. v-if="scope.row.status == '2' && scope.row.type === AlgorithmType2['预测/推理']"
  250. @click="showEvaluateSubTask(scope.row)"
  251. >
  252. 评估
  253. </el-button>
  254. <el-button type="primary" link icon="View" @click="openSubTaskViewDialog(3, '子任务查看', scope.row)"> 查看 </el-button>
  255. <el-button type="primary" link icon="EditPen" @click="openSubTaskViewDialog(2, '子任务编辑', scope.row)"> 编辑 </el-button>
  256. <el-button type="danger" link icon="Delete" @click="deletSubTaskAlgorithmTaskTrack(scope.row)"> 删除</el-button>
  257. </template>
  258. </el-table-column>
  259. </el-table>
  260. </div>
  261. </el-dialog>
  262. </div>
  263. </template>
  264. <script setup lang="tsx" name="AlgorithmTaskTrack">
  265. import { ref, reactive } from 'vue'
  266. import { useHandleData } from '@/hooks/useHandleData'
  267. import { useDownload } from '@/hooks/useDownload'
  268. import { ElMessage, ElMessageBox } from 'element-plus'
  269. import ProTable from '@/components/ProTable/index.vue'
  270. import ImportExcel from '@/components/ImportExcel/index.vue'
  271. import FormDialog from '@/components/FormDialog/index.vue'
  272. import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
  273. import {
  274. listAlgorithmTaskTrackApi,
  275. delAlgorithmTaskTrackApi,
  276. addAlgorithmTaskTrackApi,
  277. updateAlgorithmTaskTrackApi,
  278. importTemplateApi,
  279. importAlgorithmTaskTrackDataApi,
  280. exportAlgorithmTaskTrackApi,
  281. getAlgorithmTaskTrackApi,
  282. listSubTaskAlgorithmTaskTrackApi
  283. } from '@/api/modules/demo/algorithmTaskTrack'
  284. import { AlgorithmType, AlgorithmType2, enumsAlgorithmType, enumsSubSystem, Status__, SubSystem, SubSystem__ } from '@/views/demo/utils'
  285. import { enumAlgorithmConfigTrackApi, getAlgorithmConfigTrackApi } from '@/api/modules/demo/AlgorithmConfigTrack'
  286. import SvgIcon from '@/components/SvgIcon/index.vue'
  287. import { listDataSeqApi } from '@/api/modules/demo/DataSeq'
  288. import File from '@/components/Upload/File.vue'
  289. import { enumAlgorithmModelTrackApi } from '@/api/modules/demo/AlgorithmModelTrack'
  290. import statusEnums from '@/utils/status'
  291. import {
  292. addTrackSequenceApi,
  293. delTrackSequenceApi,
  294. getTrackSequenceApi,
  295. startTrackSequenceApi,
  296. stopTrackSequenceApi,
  297. updateTrackSequenceApi
  298. } from '@/api/modules/demo/trackSequence'
  299. import { delToInfraredApi, getToInfraredApi, startToInfraredApi, stopToInfraredApi, updateToInfraredApi } from '@/api/modules/demo/toInfrared'
  300. import { getTargetDetectionApi, startTargetDetectionApi, stopTargetDetectionApi, updateTargetDetectionApi } from '@/api/modules/demo/TargetDetection'
  301. import { delDataAugmentationApi } from '@/api/modules/demo/dataAugmentation'
  302. const startSubTask = async (row: any) => {
  303. let res: any = null
  304. if (row.subsystem === SubSystem__['可见光转红外']) {
  305. res = await startToInfraredApi(row.id)
  306. } else if (row.subsystem === SubSystem__['目标检测']) {
  307. res = await startTargetDetectionApi(row.id)
  308. } else if (row.subsystem === SubSystem__['注释轨迹序列']) {
  309. res = await startTrackSequenceApi(row.id)
  310. } else {
  311. ElMessage.error('暂不支持该子任务类型')
  312. return
  313. }
  314. if (res.code === 200) {
  315. ElMessage.success('任务已开始,请等待完成!')
  316. } else {
  317. ElMessage.error('任务开始失败,请检查!')
  318. }
  319. handleOpenView()
  320. }
  321. const stopSubTask = async (row: any) => {
  322. let res: any = null
  323. if (row.subsystem === SubSystem__['可见光转红外']) {
  324. res = await stopToInfraredApi(row.id)
  325. } else if (row.subsystem === SubSystem__['目标检测']) {
  326. res = await stopTargetDetectionApi(row.id)
  327. } else if (row.subsystem === SubSystem__['注释轨迹序列']) {
  328. res = await stopTrackSequenceApi(row.id)
  329. } else {
  330. ElMessage.error('暂不支持该子任务类型')
  331. return
  332. }
  333. if (res.code === 200) {
  334. ElMessage.success('终止任务成功!')
  335. } else {
  336. ElMessage.error('终止任务失败,请检查!')
  337. }
  338. handleOpenView()
  339. }
  340. const openLogSubTask = async (row: any) => {}
  341. const previewSubTask = async (row: any) => {}
  342. const showStatisticResultSubTask = async (row: any) => {}
  343. const showEvaluateResultSubTask = async (row: any) => {}
  344. const showEvaluateSubTask = async (row: any) => {}
  345. const deletSubTask = async (row: any) => {
  346. if (row.subsystem === SubSystem__['可见光转红外']) {
  347. await useHandleData(delToInfraredApi, row.id, '删除【' + row.name + '】可见光转红外')
  348. } else if (row.subsystem === SubSystem__['目标检测']) {
  349. await useHandleData(delDataAugmentationApi, row.id, '删除任务【' + row.name + '】目标检测')
  350. } else if (row.subsystem === SubSystem__['注释轨迹序列']) {
  351. await useHandleData(delTrackSequenceApi, row.id, '删除【' + row.name + '】注视轨迹序列')
  352. } else {
  353. ElMessage.error('暂不支持该子任务类型')
  354. }
  355. handleOpenView()
  356. }
  357. const loadSomeData = async (row?: any) => {
  358. datasetList.value = await getDatasetList()
  359. if (row.subsystem === SubSystem__['可见光转红外']) {
  360. enumsAlgorithmConfigTrack_toInfrared.value = await getEnumsAlgorithmConfigTrack('可见光转红外', ['预测/推理'])
  361. await getToInfraredModelList()
  362. } else if (row.subsystem === SubSystem__['目标检测']) {
  363. } else if (row.subsystem === SubSystem__['注释轨迹序列']) {
  364. enumsAlgorithmConfigTrack_trackSequence.value = await getEnumsAlgorithmConfigTrack('注释轨迹序列', [AlgorithmType[row.type]])
  365. enumsAlgorithmModelTrack.value = await getEnumsAlgorithmModelTrack('注释轨迹序列')
  366. enumsAlgorithmModelTrack_TD.value = await getEnumsAlgorithmModelTrack('目标检测')
  367. }
  368. }
  369. const openSubTaskViewDialog = async (type: number, title: string, row?: any) => {
  370. let res = { data: {} }
  371. let api: any = null
  372. if (row?.id) {
  373. console.log(row)
  374. if (row.subsystem === SubSystem__['可见光转红外']) {
  375. console.log('可见光转红外')
  376. res = await getToInfraredApi(row.id || null)
  377. api = updateToInfraredApi
  378. // 重置表单
  379. setItemsOptions_ToInfrared()
  380. } else if (row.subsystem === SubSystem__['目标检测']) {
  381. console.log('目标检测')
  382. res = await getTargetDetectionApi(row.id || null)
  383. api = updateTargetDetectionApi
  384. } else if (row.subsystem === SubSystem__['注释轨迹序列']) {
  385. console.log('注释轨迹序列')
  386. res = await getTrackSequenceApi(row.id || null)
  387. api = updateTrackSequenceApi
  388. // 重置表单
  389. setItemsOptions_TrackSequence()
  390. } else {
  391. console.log('其他')
  392. ElMessage.error('暂不支持该子任务类型')
  393. return
  394. }
  395. const params = JSON.parse(res.data['algorithmParameters'])
  396. if (params.otherParams) {
  397. res.data = { ...res.data, ...params.otherParams }
  398. }
  399. }
  400. if (row?.id) {
  401. itemsOptions = await updateItemsOptions(row.algorithmId)
  402. }
  403. await loadSomeData(row)
  404. const params = {
  405. title: title,
  406. width: 600,
  407. isEdit: type !== 3,
  408. itemsOptions: itemsOptions,
  409. model: res.data,
  410. api: api,
  411. getTableList: handleOpenView
  412. }
  413. formDialogRef.value?.openDialog(params)
  414. }
  415. const remove_unnecessary_parameters = (itemsOptions: ProForm.ItemsOptions[]): ProForm.ItemsOptions[] => {
  416. try {
  417. const endIndex = itemsOptions.findIndex(option => option['label'] === '备注')
  418. if (endIndex !== -1) {
  419. itemsOptions = itemsOptions.slice(0, endIndex + 1)
  420. }
  421. return itemsOptions
  422. } catch (error) {
  423. console.error('移除不必要的参数时出错:', error)
  424. // ElMessage.error('移除不必要的参数时出错,请检查!');
  425. return itemsOptions // 返回原始选项,避免进一步的问题
  426. }
  427. }
  428. const updateItemsOptions = async (algorithmId: any) => {
  429. try {
  430. const result = await getAlgorithmConfigTrackApi(algorithmId)
  431. if (result.code === 200) {
  432. // 处理结果
  433. const parameters = JSON.parse(result.data['parameters'])
  434. // console.log('parameters: ', parameters)
  435. const itemsOptions_new = remove_unnecessary_parameters(itemsOptions)
  436. for (const item of parameters) {
  437. // 添加新的表单项选项
  438. itemsOptions_new.push({
  439. label: item['name'],
  440. prop: item['agName'],
  441. rules: [{ required: item['required'], message: item['agName'] + '不能为空', trigger: 'blur' }],
  442. tooltip: item['prompt'],
  443. compOptions: {
  444. elTagName: 'input',
  445. placeholder: item['defaultValue']
  446. // value: item['defaultValue']
  447. }
  448. })
  449. }
  450. formDialogRef.value?.updateItemOptions(itemsOptions_new)
  451. return itemsOptions_new
  452. } else {
  453. return itemsOptions // 返回原始选项,避免进一步的问题
  454. }
  455. } catch (err) {
  456. console.log(err)
  457. ElMessage.error('获取算法配置失败,请检查!')
  458. return itemsOptions // 返回原始选项,避免进一步的问题
  459. }
  460. }
  461. const setItemsOptions_ToInfrared = () => {
  462. itemsOptions = [
  463. {
  464. label: '任务名称',
  465. prop: 'name',
  466. rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
  467. compOptions: {
  468. elTagName: 'input',
  469. placeholder: '请输入任务名称'
  470. }
  471. },
  472. {
  473. label: '选择数据集',
  474. prop: 'inputOssId',
  475. rules: [{ required: false, message: '数据集不能为空', trigger: 'blur' }],
  476. compOptions: {
  477. elTagName: 'select',
  478. placeholder: '请选择或者上传数据集',
  479. enum: datasetList,
  480. clearable: true
  481. }
  482. },
  483. {
  484. label: '上传数据集',
  485. prop: 'inputOssId',
  486. rules: [{ required: false, message: '数据集不能为空', trigger: 'blur' }],
  487. compOptions: {
  488. elTagName: 'file-upload',
  489. fileSize: 4096,
  490. fileType: ['zip'],
  491. placeholder: '请上传数据集'
  492. }
  493. },
  494. {
  495. label: '选择算法',
  496. prop: 'algorithmId',
  497. rules: [{ required: true, message: '算法不能为空', trigger: 'blur' }],
  498. compOptions: {
  499. elTagName: 'select',
  500. placeholder: '请选择算法',
  501. enum: enumsAlgorithmConfigTrack_toInfrared,
  502. clearable: true,
  503. onChange: async (value: any) => {
  504. if (value != undefined && value != null && value != '') {
  505. await updateItemsOptions(value)
  506. }
  507. }
  508. }
  509. },
  510. {
  511. label: '任务类型',
  512. prop: 'type',
  513. rules: [{ required: true, message: '任务类型不能为空', trigger: 'blur' }],
  514. compOptions: {
  515. disabled: true,
  516. elTagName: 'select',
  517. placeholder: '请选择任务类型',
  518. enum: enumsAlgorithmType,
  519. clearable: true,
  520. value: ''
  521. },
  522. show: params => {
  523. if (params.value.algorithmId != undefined) {
  524. for (let i = 0; i < enumsAlgorithmConfigTrack_toInfrared.value.length; i++) {
  525. if (enumsAlgorithmConfigTrack_toInfrared.value[i]['value'] === params.value.algorithmId) {
  526. params.value.type = enumsAlgorithmConfigTrack_toInfrared.value[i]['type']
  527. return true
  528. }
  529. }
  530. }
  531. return false
  532. }
  533. },
  534. {
  535. label: '选择模型',
  536. prop: 'algorithmModelId',
  537. rules: [{ required: true, message: '模型不能为空', trigger: 'blur' }],
  538. show: params => {
  539. if (params.value.type == AlgorithmType2['预测/推理']) {
  540. return true
  541. }
  542. return false
  543. },
  544. compOptions: {
  545. elTagName: 'select',
  546. placeholder: '请选择模型',
  547. enum: toInfraredModelList,
  548. clearable: true
  549. }
  550. },
  551. {
  552. label: '备注',
  553. prop: 'remarks',
  554. rules: [],
  555. compOptions: {
  556. elTagName: 'input',
  557. placeholder: '请输入备注'
  558. }
  559. }
  560. ]
  561. }
  562. const enumsAlgorithmConfigTrack_trackSequence = ref<any[]>([])
  563. const enumsAlgorithmModelTrack = ref<any[]>([])
  564. const enumsAlgorithmModelTrack_TD = ref<any[]>([])
  565. const setItemsOptions_TrackSequence = () => {
  566. itemsOptions = [
  567. {
  568. label: '任务名称',
  569. prop: 'name',
  570. rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
  571. compOptions: {
  572. placeholder: '请输入任务名称'
  573. }
  574. },
  575. {
  576. label: '选择数据集',
  577. prop: 'inputOssId',
  578. rules: [{ required: false, message: '数据集不能为空', trigger: 'blur' }],
  579. compOptions: {
  580. elTagName: 'select',
  581. placeholder: '请选择或者上传数据集',
  582. enum: datasetList,
  583. clearable: true
  584. }
  585. },
  586. {
  587. label: '上传数据集',
  588. prop: 'inputOssId',
  589. rules: [{ required: false, message: '数据集不能为空', trigger: 'blur' }],
  590. compOptions: {
  591. elTagName: 'file-upload',
  592. fileSize: 4096,
  593. fileType: ['zip'],
  594. placeholder: '请上传数据集'
  595. }
  596. },
  597. {
  598. label: '选择算法',
  599. prop: 'algorithmId',
  600. rules: [{ required: true, message: '算法不能为空', trigger: 'blur' }],
  601. compOptions: {
  602. elTagName: 'select',
  603. placeholder: '请选择算法',
  604. enum: enumsAlgorithmConfigTrack_trackSequence,
  605. clearable: true,
  606. onChange: async (value: any) => {
  607. if (value != undefined && value != null && value != '') {
  608. await updateItemsOptions(value)
  609. }
  610. }
  611. }
  612. },
  613. {
  614. label: '任务类型',
  615. prop: 'type',
  616. rules: [{ required: true, message: '任务类型不能为空', trigger: 'blur' }],
  617. compOptions: {
  618. disabled: true,
  619. elTagName: 'select',
  620. placeholder: '请选择任务类型',
  621. enum: enumsAlgorithmType,
  622. clearable: true,
  623. value: ''
  624. },
  625. show: params => {
  626. if (params.value.algorithmId != undefined) {
  627. for (let i = 0; i < enumsAlgorithmConfigTrack_trackSequence.value.length; i++) {
  628. if (enumsAlgorithmConfigTrack_trackSequence.value[i]['value'] === params.value.algorithmId) {
  629. params.value.type = enumsAlgorithmConfigTrack_trackSequence.value[i]['type']
  630. return true
  631. }
  632. }
  633. }
  634. return false
  635. }
  636. },
  637. {
  638. label: '选择模型',
  639. prop: 'algorithmModelId',
  640. rules: [{ required: true, message: '模型不能为空', trigger: 'blur' }],
  641. show: params => {
  642. if (params.value.type == AlgorithmType2['预测/推理']) {
  643. return true
  644. }
  645. params.value.algorithmModelId = ''
  646. return false
  647. },
  648. compOptions: {
  649. elTagName: 'select',
  650. placeholder: '请选择模型',
  651. enum: enumsAlgorithmModelTrack,
  652. clearable: true
  653. }
  654. },
  655. {
  656. label: '选择目标检测模型',
  657. prop: 'algorithmModelTargetDetectionId',
  658. rules: [{ required: false, message: '目标检测模型不能为空', trigger: 'blur' }],
  659. show: params => {
  660. if (params.value.type == AlgorithmType2['预测/推理']) {
  661. return true
  662. }
  663. params.value.algorithmModelTargetDetectionId = ''
  664. return false
  665. },
  666. compOptions: {
  667. elTagName: 'select',
  668. placeholder: '请选择目标检测模型',
  669. enum: enumsAlgorithmModelTrack_TD,
  670. clearable: true
  671. }
  672. },
  673. {
  674. label: '上传标签',
  675. prop: 'inputLabelOssId',
  676. rules: [{ required: true, message: '标签不能为空', trigger: 'blur' }],
  677. show: params => {
  678. if (params.value.type == AlgorithmType2['测试']) {
  679. return true
  680. }
  681. return false
  682. },
  683. compOptions: {
  684. elTagName: 'file-upload',
  685. fileSize: 4096,
  686. fileType: ['txt'],
  687. placeholder: '请上传标签'
  688. }
  689. },
  690. {
  691. label: '备注',
  692. prop: 'remarks',
  693. rules: [],
  694. compOptions: {
  695. placeholder: '请输入备注'
  696. }
  697. }
  698. ]
  699. }
  700. const dialogVisibleView = ref(false)
  701. const viewData = ref<any[]>([])
  702. const subTaskAlgorithmTaskTrack_id = ref<any>(null)
  703. const openViewDialog = async (row: any) => {
  704. dialogVisibleView.value = true
  705. subTaskAlgorithmTaskTrack_id.value = row.id
  706. }
  707. const handleOpenView = async () => {
  708. const res = await listSubTaskAlgorithmTaskTrackApi(subTaskAlgorithmTaskTrack_id.value)
  709. if (res.code === 200) {
  710. viewData.value = res.data
  711. } else {
  712. ElMessage.error('获取子任务失败')
  713. }
  714. }
  715. const fileUploadRef = ref()
  716. const fileUploadDatasetChange = (value: any) => {
  717. console.log('fileUploadChange: ', value)
  718. formAddTask.value['inputDatasetOssId'] = value
  719. }
  720. const fileUploadEvaluateLabelRef = ref()
  721. const fileUploadChangeEvaluateLabel = (value: any) => {
  722. console.log('fileUploadChangeEvaluateLabel: ', value)
  723. formAddTask.value['inputEvaluateLabelOssId'] = value
  724. }
  725. const getEnumsAlgorithmModelTrack = async (subSystem: string) => {
  726. const result: any = await enumAlgorithmModelTrackApi()
  727. const res_list: any[] = []
  728. const tmp_data: any = result['data']
  729. for (const item of tmp_data) {
  730. if (SubSystem[item['subsystem']] === subSystem) {
  731. const tmp_item = { ...item }
  732. tmp_item['label'] = item['label'] + '-' + SubSystem[item['subsystem']] + '-' + AlgorithmType[item['type']] + '-' + item['algorithmName']
  733. res_list.push(tmp_item)
  734. }
  735. }
  736. return res_list
  737. }
  738. const getEnumsAlgorithmConfigTrack = async (subSystem: string, type_list_: string[]) => {
  739. const result = await enumAlgorithmConfigTrackApi()
  740. const res_list: any[] = []
  741. const tmp_data: any = result['data']
  742. const type_list: any[] = type_list_.map(item => parseInt(AlgorithmType2[item]))
  743. for (const item of tmp_data) {
  744. if (parseInt(item.subsystem) === parseInt(SubSystem__[subSystem])) {
  745. if (type_list !== undefined && type_list.length > 0) {
  746. if (type_list.includes(parseInt(item.type))) {
  747. const tmp_item = { ...item }
  748. tmp_item['label'] = item['label'] + '-' + SubSystem[item['subsystem']] + '-' + AlgorithmType[item['type']]
  749. res_list.push(tmp_item)
  750. }
  751. } else {
  752. const tmp_item = { ...item }
  753. tmp_item['label'] = item['label'] + '-' + SubSystem[item['subsystem']] + '-' + AlgorithmType[item['type']]
  754. res_list.push(tmp_item)
  755. }
  756. }
  757. }
  758. return res_list
  759. }
  760. const dialogVisibleAddTask = ref(false)
  761. const handleClose = (done: () => void) => {
  762. ElMessageBox.confirm('确定关闭吗?')
  763. .then(() => {
  764. done()
  765. })
  766. .catch(() => {
  767. // catch error
  768. })
  769. }
  770. const formAddTask = ref({ ifEvaluate: false, ifToInfrared: false })
  771. const formAddTaskRef = ref()
  772. const addAlgorithmTaskTrack = async () => {
  773. formAddTaskRef.value
  774. .validate()
  775. .then(async () => {
  776. console.log('formAddTask: ', formAddTask.value)
  777. console.log(fileUploadRef.value.uploadFileListExport)
  778. const res = await addAlgorithmTaskTrackApi(formAddTask.value)
  779. if (res.code === 200) {
  780. ElMessage.success('新增可辨识性分析总任务成功')
  781. dialogVisibleAddTask.value = false
  782. proTable.value?.getTableList()
  783. } else {
  784. ElMessage.error('新增可辨识性分析总任务失败')
  785. }
  786. })
  787. .catch(() => {
  788. console.log('error')
  789. ElMessage.error('请检查表单')
  790. })
  791. }
  792. const rulesAddTask = {
  793. // todo: 校验规则
  794. name: [{ required: true, message: '可见光转红外算法不能为空', trigger: 'blur' }],
  795. ifToInfrared: [{ required: false, message: '是否转红外不能为空', trigger: 'blur' }],
  796. toInfraredAlgorithmId: [{ required: false, message: '可见光转红外算法不能为空', trigger: 'blur' }],
  797. inputDatasetOssId: [{ required: true, message: '数据集不能为空', trigger: 'blur' }],
  798. targetDetectionModelList: [{ required: true, message: '目标模型不能为空', trigger: 'blur' }],
  799. inputEvaluateLabelOssId: [{ required: false, message: '评估标签不能为空', trigger: 'blur' }],
  800. remarks: [{ required: false, message: '备注不能为空', trigger: 'blur' }]
  801. }
  802. const enumsAlgorithmConfigTrack_toInfrared = ref<any[]>([])
  803. const setIfToInfrared = async () => {
  804. formAddTask.value.toInfraredAlgorithmId = ''
  805. if (formAddTask.value?.ifToInfrared === true) {
  806. enumsAlgorithmConfigTrack_toInfrared.value = await getEnumsAlgorithmConfigTrack('可见光转红外', ['预测/推理'])
  807. }
  808. }
  809. const getItemsOptions = async (algorithmId: any) => {
  810. try {
  811. const result = await getAlgorithmConfigTrackApi(algorithmId)
  812. if (result.code === 200) {
  813. // 处理结果
  814. const parameters = JSON.parse(result.data['parameters'])
  815. // console.log('parameters: ', parameters)
  816. let itemsOptions_new: any[] = []
  817. for (const item of parameters) {
  818. // 添加新的表单项选项
  819. itemsOptions_new.push({
  820. label: item['name'],
  821. prop: item['agName'],
  822. rules: [{ required: item['required'], message: item['agName'] + '不能为空', trigger: 'blur' }],
  823. tooltip: item['prompt'],
  824. compOptions: {
  825. elTagName: 'input',
  826. placeholder: item['defaultValue']
  827. // value: item['defaultValue']
  828. }
  829. })
  830. }
  831. return itemsOptions_new
  832. }
  833. } catch (err) {
  834. console.log(err)
  835. ElMessage.error('获取算法配置失败,请检查!')
  836. return []
  837. }
  838. }
  839. const setAlgorithmParams = async (id: string | number, paramsName: string) => {
  840. const itemsOptions__ = await getItemsOptions(id)
  841. const params = {
  842. title: '设置算法参数',
  843. width: 580,
  844. isEdit: true,
  845. itemsOptions: itemsOptions__,
  846. model: formAddTask,
  847. api: async params => {
  848. console.log('itemsOptions__: ', itemsOptions__)
  849. let params_new = {}
  850. if (itemsOptions__ && itemsOptions__.length > 0) {
  851. for (const item of itemsOptions__) {
  852. params_new[item['prop']] = params[item['prop']]
  853. }
  854. formAddTask.value[paramsName] = params_new
  855. console.log('params: ', params)
  856. console.log('params_new: ', params_new)
  857. console.log('formAddTask: ', formAddTask.value)
  858. }
  859. return { code: 200, message: 'success' }
  860. },
  861. getTableList: proTable.value?.getTableList
  862. }
  863. formDialogRef.value?.openDialog(params)
  864. }
  865. const datasetList = ref<any[]>([])
  866. const getDatasetList = async (subSystem: string) => {
  867. const qyery = {
  868. subsystem: subSystem ? SubSystem__[subSystem] : undefined,
  869. pageNum: 1,
  870. pageSize: 1000
  871. }
  872. const result: any = await listDataSeqApi(qyery)
  873. const data = result['data']['list']
  874. let res_list: any[] = []
  875. for (const item of data) {
  876. res_list.push({
  877. value: item['inputOssId'],
  878. label: item['name'] + '-' + SubSystem[item['subsystem']]
  879. })
  880. }
  881. return res_list
  882. }
  883. const getDatasetList__ = async () => {
  884. datasetList.value = await getDatasetList('')
  885. }
  886. const toInfraredModelList = ref<any[]>([])
  887. const getToInfraredModelList = async () => {
  888. toInfraredModelList.value = await getEnumsAlgorithmModelTrack('可见光转红外')
  889. }
  890. const visionAlgorithmList = ref<any[]>([])
  891. const getVisionAlgorithmList = async () => {
  892. visionAlgorithmList.value = await getEnumsAlgorithmConfigTrack('注释轨迹序列', ['预测/推理'])
  893. }
  894. const targetDetectionModelList = ref<any[]>([])
  895. const getTargetDetectionModelList = async () => {
  896. targetDetectionModelList.value = await getEnumsAlgorithmModelTrack('目标检测')
  897. }
  898. const visionAlgorithmModelList = ref<any[]>([])
  899. const getVisionAlgorithmModelList = async () => {
  900. visionAlgorithmModelList.value = await getEnumsAlgorithmModelTrack('注释轨迹序列')
  901. }
  902. const visionEvaluateAlgorithmList = ref<any[]>([])
  903. const getVisionEvaluateAlgorithmList = async () => {
  904. visionEvaluateAlgorithmList.value = await getEnumsAlgorithmConfigTrack('注释轨迹序列', ['测试'])
  905. }
  906. const handleOpenAddTask = async () => {
  907. formAddTask.value = { ifEvaluate: false, ifToInfrared: false }
  908. await getDatasetList__()
  909. await getToInfraredModelList()
  910. await getVisionAlgorithmList()
  911. await getTargetDetectionModelList()
  912. await getVisionAlgorithmModelList()
  913. await getVisionEvaluateAlgorithmList()
  914. }
  915. // ProTable 实例
  916. const proTable = ref<ProTableInstance>()
  917. // 删除可辨识性分析总任务信息
  918. const deleteAlgorithmTaskTrack = async (params: any) => {
  919. await useHandleData(delAlgorithmTaskTrackApi, params.id, '删除【' + params.id + '】可辨识性分析总任务')
  920. proTable.value?.getTableList()
  921. }
  922. // 批量删除可辨识性分析总任务信息
  923. const batchDelete = async (ids: string[]) => {
  924. await useHandleData(delAlgorithmTaskTrackApi, ids, '删除所选可辨识性分析总任务信息')
  925. proTable.value?.clearSelection()
  926. proTable.value?.getTableList()
  927. }
  928. // 导出可辨识性分析总任务列表
  929. const downloadFile = async () => {
  930. ElMessageBox.confirm('确认导出可辨识性分析总任务数据?', '温馨提示', { type: 'warning' }).then(() =>
  931. useDownload(exportAlgorithmTaskTrackApi, '可辨识性分析总任务列表', proTable.value?.searchParam)
  932. )
  933. }
  934. // 批量添加可辨识性分析总任务
  935. const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
  936. const batchAdd = () => {
  937. const params = {
  938. title: '可辨识性分析总任务',
  939. tempApi: importTemplateApi,
  940. importApi: importAlgorithmTaskTrackDataApi,
  941. getTableList: proTable.value?.getTableList
  942. }
  943. dialogRef.value?.acceptParams(params)
  944. }
  945. const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
  946. // 打开弹框的功能
  947. const openDialog = async (type: number, title: string, row?: any) => {
  948. let res = { data: {} }
  949. if (row?.id) {
  950. res = await getAlgorithmTaskTrackApi(row?.id || null)
  951. }
  952. // 重置表单
  953. setItemsOptions()
  954. const params = {
  955. title,
  956. width: 580,
  957. isEdit: type !== 3,
  958. itemsOptions: itemsOptions,
  959. model: type == 1 ? {} : res.data,
  960. api: type == 1 ? addAlgorithmTaskTrackApi : updateAlgorithmTaskTrackApi,
  961. getTableList: proTable.value?.getTableList
  962. }
  963. formDialogRef.value?.openDialog(params)
  964. }
  965. // 表格配置项
  966. const columns = reactive<ColumnProps<any>[]>([
  967. { type: 'selection', fixed: 'left', width: 70 },
  968. { prop: 'id', label: '主键ID' },
  969. {
  970. prop: 'name',
  971. label: '任务名称',
  972. search: {
  973. el: 'input'
  974. }
  975. },
  976. {
  977. prop: 'status',
  978. label: '任务状态',
  979. search: {
  980. el: 'select'
  981. },
  982. tag: true,
  983. enum: statusEnums,
  984. width: 150
  985. },
  986. {
  987. prop: 'startTime',
  988. label: '开始时间',
  989. search: {
  990. el: 'date-picker',
  991. props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
  992. },
  993. width: 120
  994. },
  995. {
  996. prop: 'endTime',
  997. label: '结束时间',
  998. search: {
  999. el: 'date-picker',
  1000. props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
  1001. },
  1002. width: 120
  1003. },
  1004. {
  1005. prop: 'costSecond',
  1006. label: '耗时',
  1007. search: {
  1008. el: 'input'
  1009. },
  1010. width: 120
  1011. },
  1012. {
  1013. prop: 'log',
  1014. label: '日志',
  1015. search: {
  1016. el: 'input'
  1017. }
  1018. },
  1019. {
  1020. prop: 'remarks',
  1021. label: '备注',
  1022. search: {
  1023. el: 'input'
  1024. }
  1025. },
  1026. // {
  1027. // prop: 'system',
  1028. // label: '系统',
  1029. // search: {
  1030. // el: 'input'
  1031. // },
  1032. // width: 120
  1033. // },
  1034. { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
  1035. ])
  1036. // 表单配置项
  1037. let itemsOptions: ProForm.ItemsOptions[] = []
  1038. const setItemsOptions = () => {
  1039. itemsOptions = [
  1040. {
  1041. label: '任务名称',
  1042. prop: 'name',
  1043. rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
  1044. compOptions: {
  1045. placeholder: '请输入任务名称'
  1046. }
  1047. }
  1048. ]
  1049. }
  1050. </script>
  1051. <style lang="scss" scoped>
  1052. .form-item1 {
  1053. display: flex;
  1054. flex-direction: row;
  1055. align-items: center;
  1056. width: 100%;
  1057. }
  1058. </style>