projectInfo.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. <template>
  2. <div class="projectInfoPanel">
  3. <div
  4. v-if="
  5. !$route.path.includes('taskInfo') &&
  6. !$route.path.includes('evaluationReport')
  7. "
  8. >
  9. <div class="headPanel panel">
  10. <div class="titlePanel">
  11. <div class="titlePanelBor">基本信息</div>
  12. </div>
  13. <div class="boxContent">
  14. <div class="info">
  15. <span>项目ID:</span>
  16. <b>{{ info.projectId }}</b>
  17. </div>
  18. <div class="info">
  19. <span>项目名称:</span>
  20. <b>{{ info.projectName }}</b>
  21. </div>
  22. <div class="info">
  23. <span>并行度:</span>
  24. <b>{{ info.parallelism }}</b>
  25. </div>
  26. <div class="info">
  27. <span>最大仿真时间:</span>
  28. <b>{{ info.maxSimulationTime }}</b>
  29. </div>
  30. <div class="info">
  31. <span>是否选择GPU:</span>
  32. <b>{{ info.isChoiceGpu }}</b>
  33. </div>
  34. <div class="info">
  35. <span>创建时间:</span>
  36. <b>{{ info.startTime }}</b>
  37. </div>
  38. <div class="info">
  39. <span>完成时间:</span>
  40. <b>{{ info.finishTime }}</b>
  41. </div>
  42. <div class="info">
  43. <span>完成进度:</span>
  44. <b>{{ info.nowRunStateName }}</b>
  45. </div>
  46. <div class="info">
  47. <span>结果等级:</span>
  48. <b>{{ info.evaluationLevel }}</b>
  49. </div>
  50. <div class="info">
  51. <span>场景测试包:</span>
  52. <b>{{ info.packageName }}</b>
  53. </div>
  54. <div class="info">
  55. <span>项目描述:</span>
  56. <b>{{ info.projectDescribe }}</b>
  57. </div>
  58. </div>
  59. </div>
  60. <div class="scorePanel panel">
  61. <div class="titlePanel">
  62. <div class="titlePanelBor">测评得分</div>
  63. </div>
  64. <div class="box">
  65. <tableList
  66. style="margin: 30px 0"
  67. :columns="columnsA"
  68. :getDataWay="getDataWayA"
  69. >
  70. </tableList>
  71. </div>
  72. </div>
  73. <div class="flexBox topPanel">
  74. <div class="box panel boxB">
  75. <div class="titlePanel">
  76. <div class="titlePanelBor">算法配置</div>
  77. </div>
  78. <div class="boxContent">
  79. <div class="info">
  80. <span>算法名称:</span>
  81. <b>{{ info.algorithmName }}</b>
  82. </div>
  83. <div class="info">
  84. <span>算法描述:</span>
  85. <b>{{ info.algorithmDescribe }}</b>
  86. </div>
  87. </div>
  88. </div>
  89. <div class="box panel">
  90. <div class="titlePanel">
  91. <div class="titlePanelBor">测试报告</div>
  92. <i
  93. class="el-icon-download download"
  94. v-bind:class="{ cursor: info.nowRunState === '30' }"
  95. @click="downReport"
  96. ></i>
  97. </div>
  98. <div class="boxContent boxContentC">
  99. <div class="cbox" @click="toReport">
  100. <img
  101. :src="downImgSrc"
  102. width="100%"
  103. v-bind:class="{
  104. cursor: info.nowRunState === '30',
  105. }"
  106. />
  107. <div
  108. v-bind:class="{
  109. cursor: info.nowRunState === '30',
  110. }"
  111. >
  112. 仿真云测试报告
  113. </div>
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. <div class="centerPanel panel">
  119. <div class="titlePanel">
  120. <div class="titlePanelBor">车辆配置</div>
  121. </div>
  122. <div class="box">
  123. <div class="boxContentA">
  124. <div class="info">
  125. <span>车辆名称:</span>
  126. <b>{{ info.vehicleName }}</b>
  127. </div>
  128. <div class="info">
  129. <span>车辆描述:</span>
  130. <b>{{ info.vehicleDescribe }}</b>
  131. </div>
  132. </div>
  133. <div class="boxContentB">
  134. <div class="list">
  135. <handle-config-list
  136. :showBtns="false"
  137. :curOne="curOne"
  138. :configList="configList"
  139. @curItem="curItem"
  140. :needHighline="false"
  141. ></handle-config-list>
  142. </div>
  143. <div class="canvasBox">
  144. <canvas-sensor
  145. v-if="modelImgSrc"
  146. :modelImgSrc="modelImgSrc"
  147. :configList="configList"
  148. ></canvas-sensor>
  149. </div>
  150. </div>
  151. </div>
  152. </div>
  153. <div class="bottomPanel panel">
  154. <div class="titlePanel">
  155. <div class="titlePanelBor">任务信息</div>
  156. </div>
  157. <div class="box">
  158. <div class="boxContentA">
  159. <div class="chart">
  160. <div class="pieTitle">任务运行状态统计:</div>
  161. <div class="pie">
  162. <pie-chart-project-info
  163. id="projectInfoPieA"
  164. :stateList="stateList"
  165. stateName="stateName"
  166. seriesName="任务运行状态统计"
  167. ></pie-chart-project-info>
  168. </div>
  169. </div>
  170. <div class="chart">
  171. <div class="pieTitle">得分统计:</div>
  172. <div class="pie">
  173. <pie-chart-project-info
  174. id="projectInfoPieB"
  175. :stateList="resultList"
  176. stateName="resultName"
  177. seriesName="得分统计"
  178. ></pie-chart-project-info>
  179. </div>
  180. </div>
  181. </div>
  182. <div>
  183. <tableList
  184. ref="table"
  185. :columns="columns"
  186. :getDataWay="getDataWay"
  187. :pagination="pagination"
  188. >
  189. <el-table-column
  190. label="操作"
  191. slot="cgInfos"
  192. align="center"
  193. >
  194. <template v-slot="scope">
  195. <i
  196. @click="viewRow(scope.row)"
  197. class="el-icon-view elIcon"
  198. title="查看"
  199. ></i>
  200. </template>
  201. </el-table-column>
  202. </tableList>
  203. </div>
  204. </div>
  205. </div>
  206. </div>
  207. <router-view v-else></router-view>
  208. </div>
  209. </template>
  210. <script>
  211. import handleConfigList from "../modelLibrary/components/handleConfigList.vue";
  212. import tableList from "@/components/grid/TableList";
  213. import pieChartProjectInfo from "@/components/echarts/pieChartProjectInfo";
  214. import canvasSensor from "./components/canvasProjectInfo.vue";
  215. import { mapState } from "vuex";
  216. export default {
  217. name: "projectInfo", // 项目详情
  218. components: {
  219. handleConfigList,
  220. tableList,
  221. pieChartProjectInfo,
  222. canvasSensor,
  223. },
  224. data() {
  225. return {
  226. id: "",
  227. projectType: "", // 1手动 2自动
  228. info: {},
  229. columns: [
  230. {
  231. label: "ID",
  232. prop: "id",
  233. },
  234. {
  235. label: "场景名称",
  236. prop: "sceneName",
  237. },
  238. {
  239. label: "运行开始时间",
  240. prop: "runStartTimeFmt",
  241. },
  242. {
  243. label: "运行结束时间",
  244. prop: "runEndTimeFmt",
  245. },
  246. {
  247. label: "运行状态",
  248. prop: "runState",
  249. },
  250. {
  251. label: "运行结果",
  252. prop: "runResult",
  253. },
  254. {
  255. label: "得分",
  256. prop: "score",
  257. },
  258. {
  259. label: "操作",
  260. prop: "cgInfos",
  261. template: true,
  262. },
  263. ],
  264. columnsA: [
  265. {
  266. label: "测试项目",
  267. prop: "projectName",
  268. },
  269. {
  270. label: "场景数量",
  271. prop: "sceneNum",
  272. },
  273. {
  274. label: "测试权重%",
  275. prop: "weight",
  276. },
  277. {
  278. label: "测试得分",
  279. prop: "score",
  280. },
  281. {
  282. label: "得分率%",
  283. prop: "scoreRatio",
  284. },
  285. ],
  286. pagination: {
  287. //分页使用
  288. currentPage: 1,
  289. pageSize: 10,
  290. position: "right",
  291. pageSizes: [10, 30, 50, 100, 200],
  292. layout: "sizes, total, prev, pager, next, jumper",
  293. },
  294. getDataWay: {
  295. //加载表格数据
  296. dataType: "url",
  297. type: "post",
  298. // firstRequest: false,
  299. data: this.$api.workManagement.selectProjectTaskList,
  300. param: {
  301. id: this.$route.query.id,
  302. projectType: this.$route.query.projectType,
  303. },
  304. },
  305. getDataWayA: {
  306. //加载表格数据
  307. dataType: "data",
  308. type: "post",
  309. firstRequest: false,
  310. data: [],
  311. param: {},
  312. },
  313. // 传感器对象集合
  314. configList: {
  315. camera: [],
  316. ogt: [],
  317. lidar: [],
  318. gps: [],
  319. },
  320. // 用于当前选中项的展示
  321. curOne: {
  322. name: "",
  323. index: -1,
  324. },
  325. downImgSrc: require("@/assets/common/image/others/noDoc.png"),
  326. // modelImgSrc: require("@/assets/common/image/others/carTopView.png"), // 车辆图片地址
  327. modelImgSrc: "", // 车辆图片地址
  328. stateList: [], // 任务运行状态统计数据
  329. resultList: [],
  330. };
  331. },
  332. computed: {
  333. ...mapState(["fileHost", "fileUrl"]),
  334. },
  335. methods: {
  336. viewRow(row) {
  337. this.$router.push({
  338. path: "/manualRunProjectList/projectInfo/taskInfo",
  339. query: {
  340. taskId: row.id,
  341. id: row.pid,
  342. projectType: this.projectType,
  343. },
  344. });
  345. },
  346. toReport() {
  347. if (this.info.nowRunState === "30") {
  348. this.$router.push({
  349. path: "/manualRunProjectList/projectInfo/evaluationReport",
  350. query: { id: this.id, projectType: this.projectType },
  351. });
  352. }
  353. },
  354. downReport() {
  355. if (this.info.nowRunState != "30") return;
  356. this.$axios({
  357. method: "post",
  358. url: this.$api.workManagement.exportProjectReportById,
  359. responseType: "blob",
  360. data: { id: this.id, projectType: this.projectType },
  361. }).then((res) => {
  362. let blob = new Blob([res]);
  363. let fileName = "测试报告.pdf";
  364. if ("download" in document.createElement("a")) {
  365. // 非IE下载
  366. let emlink = document.createElement("a");
  367. emlink.download = fileName;
  368. emlink.style.display = "none";
  369. emlink.href = URL.createObjectURL(blob);
  370. document.body.appendChild(emlink);
  371. emlink.click();
  372. URL.revokeObjectURL(emlink.href);
  373. document.body.removeChild(emlink);
  374. } else {
  375. // IE下载
  376. navigator.msSaveBlob(blob, fileName);
  377. }
  378. });
  379. },
  380. curItem(item) {
  381. this.curOne = item;
  382. },
  383. getImgUrl(addr) {
  384. let url = "";
  385. if (process.env.VUE_APP_IS_DEV == "true") {
  386. url = this.fileHost + this.fileUrl;
  387. } else {
  388. url = this.fileUrl;
  389. }
  390. let token = localStorage.getItem("Authorization").split(" ")[1];
  391. let src = `${url}?objectName=${addr}&access_token=${token}`;
  392. return src;
  393. },
  394. },
  395. mounted() {
  396. // console.log(this.$route);
  397. if (this.$route.query.id) {
  398. this.id = this.$route.query.id;
  399. this.projectType = this.$route.query.projectType || "1";
  400. this.$axios({
  401. method: "post",
  402. url: this.$api.workManagement.selectProjectDetailsById,
  403. data: {
  404. id: this.id,
  405. projectType: this.projectType,
  406. },
  407. }).then((res) => {
  408. if (res.code == 200 && res.info) {
  409. this.info = res.info;
  410. this.configList.camera = res.info.sensorCameraList || [];
  411. this.configList.ogt = res.info.sensorOgtList || [];
  412. this.configList.lidar = res.info.sensorLidarList || [];
  413. this.configList.gps = res.info.sensorGpsList || [];
  414. this.modelImgSrc = this.getImgUrl(res.info.vehicleTopView);
  415. if (this.info.nowRunState === "30") {
  416. this.downImgSrc = require("@/assets/common/image/others/hasDoc.png");
  417. } else {
  418. this.downImgSrc = require("@/assets/common/image/others/noDoc.png");
  419. }
  420. this.stateList = res.info.stateList || [];
  421. this.resultList = res.info.resultScoreList || [];
  422. this.getDataWayA.data = res.info.algorithmScoreList;
  423. } else {
  424. this.$message.error(res.message || "获取信息失败");
  425. }
  426. });
  427. }
  428. },
  429. };
  430. </script>
  431. <style lang='less' scoped>
  432. .projectInfoPanel {
  433. padding: 18px;
  434. .panel {
  435. border: 1px solid #dfdfdf;
  436. padding: 12px 24px;
  437. box-shadow: 0 4px 9px #dcdcdc;
  438. border-radius: 3px;
  439. }
  440. .titlePanel {
  441. padding-bottom: 6px;
  442. border-bottom: 1px dotted @gray;
  443. }
  444. .headPanel {
  445. margin-bottom: 25px;
  446. .box {
  447. flex: 1;
  448. }
  449. .boxContent {
  450. display: flex;
  451. flex-wrap: wrap;
  452. padding: 18px 15px;
  453. }
  454. .info {
  455. display: flex;
  456. width: 345px;
  457. margin: 0 12px 22px 0;
  458. word-break: break-all;
  459. span {
  460. display: block;
  461. width: 105px;
  462. color: @gray;
  463. }
  464. b {
  465. flex: 1;
  466. font-weight: normal;
  467. }
  468. }
  469. }
  470. .scorePanel {
  471. margin-bottom: 25px;
  472. }
  473. .topPanel {
  474. .box {
  475. flex: 1;
  476. }
  477. .boxB {
  478. margin-right: 18px;
  479. }
  480. .titlePanel {
  481. position: relative;
  482. .download {
  483. position: absolute;
  484. top: 0;
  485. right: 0;
  486. color: @themeColor;
  487. font-size: 18px;
  488. // cursor: pointer;
  489. }
  490. }
  491. .boxContent {
  492. padding: 18px 15px;
  493. }
  494. .info {
  495. display: flex;
  496. margin-bottom: 22px;
  497. word-break: break-all;
  498. span {
  499. display: block;
  500. width: 75px;
  501. color: @gray;
  502. }
  503. b {
  504. flex: 1;
  505. font-weight: normal;
  506. }
  507. }
  508. .boxContentC {
  509. display: flex;
  510. justify-content: center;
  511. align-items: center;
  512. height: 100%;
  513. .cbox {
  514. text-align: center;
  515. color: @themeColor;
  516. // cursor: pointer;
  517. > div {
  518. margin-top: 18px;
  519. }
  520. }
  521. }
  522. }
  523. .centerPanel {
  524. margin: 25px 0;
  525. .boxContentA {
  526. padding: 18px 15px;
  527. .info {
  528. display: flex;
  529. margin-bottom: 22px;
  530. word-break: break-all;
  531. span {
  532. display: block;
  533. width: 75px;
  534. color: @gray;
  535. }
  536. b {
  537. flex: 1;
  538. font-weight: normal;
  539. }
  540. }
  541. }
  542. .boxContentB {
  543. display: flex;
  544. justify-content: space-around;
  545. padding-top: 30px;
  546. .canvasBox {
  547. flex: 1;
  548. }
  549. }
  550. }
  551. .bottomPanel {
  552. .boxContentA {
  553. display: flex;
  554. justify-content: space-around;
  555. padding: 45px 0;
  556. }
  557. .chart {
  558. width: 50%;
  559. .pieTitle {
  560. padding: 0 0 30px;
  561. text-align: center;
  562. font-size: 16px;
  563. font-weight: bold;
  564. }
  565. .pie {
  566. height: calc(40vh);
  567. }
  568. }
  569. }
  570. }
  571. </style>