projectInfo.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  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="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. info: {},
  228. columns: [
  229. {
  230. label: "ID",
  231. prop: "id",
  232. },
  233. {
  234. label: "场景名称",
  235. prop: "sceneName",
  236. },
  237. {
  238. label: "运行开始时间",
  239. prop: "runStartTimeFmt",
  240. },
  241. {
  242. label: "运行结束时间",
  243. prop: "runEndTimeFmt",
  244. },
  245. {
  246. label: "运行状态",
  247. prop: "runState",
  248. },
  249. {
  250. label: "运行结果",
  251. prop: "runResult",
  252. },
  253. {
  254. label: "得分",
  255. prop: "score",
  256. },
  257. {
  258. label: "操作",
  259. prop: "cgInfos",
  260. template: true,
  261. },
  262. ],
  263. columnsA: [
  264. {
  265. label: "测试项目",
  266. prop: "projectName",
  267. },
  268. {
  269. label: "场景数量",
  270. prop: "sceneNum",
  271. },
  272. {
  273. label: "测试权重%",
  274. prop: "weight",
  275. },
  276. {
  277. label: "测试得分",
  278. prop: "score",
  279. },
  280. {
  281. label: "得分率%",
  282. prop: "scoreRatio",
  283. },
  284. ],
  285. pagination: {
  286. //分页使用
  287. currentPage: 1,
  288. pageSize: 10,
  289. position: "right",
  290. pageSizes: [10, 30, 50, 100, 200],
  291. layout: "sizes, total, prev, pager, next, jumper",
  292. },
  293. getDataWay: {
  294. //加载表格数据
  295. dataType: "url",
  296. type: "post",
  297. // firstRequest: false,
  298. data: this.$api.workManagement.selectProjectTaskList,
  299. param: {
  300. id: this.$route.query.id,
  301. },
  302. },
  303. getDataWayA: {
  304. //加载表格数据
  305. dataType: "data",
  306. type: "post",
  307. firstRequest: false,
  308. data: [],
  309. param: {},
  310. },
  311. // 传感器对象集合
  312. configList: {
  313. camera: [],
  314. ogt: [],
  315. lidar: [],
  316. gps: [],
  317. },
  318. // 用于当前选中项的展示
  319. curOne: {
  320. name: "",
  321. index: -1,
  322. },
  323. downImgSrc: require("@/assets/common/image/others/noDoc.png"),
  324. // modelImgSrc: require("@/assets/common/image/others/carTopView.png"), // 车辆图片地址
  325. modelImgSrc: "", // 车辆图片地址
  326. stateList: [], // 任务运行状态统计数据
  327. resultList: [],
  328. };
  329. },
  330. computed: {
  331. ...mapState(["fileHost", "fileUrl"]),
  332. },
  333. methods: {
  334. viewRow(row) {
  335. this.$router.push({
  336. path: "/manualRunProjectList/projectInfo/taskInfo",
  337. query: {
  338. taskId: row.id,
  339. id: row.pid,
  340. },
  341. });
  342. },
  343. toReport() {
  344. if (this.info.nowRunState === "30") {
  345. this.$router.push({
  346. path: "/manualRunProjectList/projectInfo/evaluationReport",
  347. query: { id: this.id },
  348. });
  349. }
  350. },
  351. downReport() {
  352. if (this.info.nowRunState != "30") return;
  353. this.$axios({
  354. method: "post",
  355. url: this.$api.workManagement.exportProjectReportById,
  356. responseType: "blob",
  357. data: { id: this.id },
  358. }).then((res) => {
  359. let blob = new Blob([res]);
  360. let fileName = "测试报告.pdf";
  361. if ("download" in document.createElement("a")) {
  362. // 非IE下载
  363. let emlink = document.createElement("a");
  364. emlink.download = fileName;
  365. emlink.style.display = "none";
  366. emlink.href = URL.createObjectURL(blob);
  367. document.body.appendChild(emlink);
  368. emlink.click();
  369. URL.revokeObjectURL(emlink.href);
  370. document.body.removeChild(emlink);
  371. } else {
  372. // IE下载
  373. navigator.msSaveBlob(blob, fileName);
  374. }
  375. });
  376. },
  377. curItem(item) {
  378. this.curOne = item;
  379. },
  380. getImgUrl(addr) {
  381. let url = "";
  382. if (process.env.VUE_APP_IS_DEV == "true") {
  383. url = this.fileHost + this.fileUrl;
  384. } else {
  385. url = this.fileUrl;
  386. }
  387. let token = localStorage.getItem("Authorization").split(" ")[1];
  388. let src = `${url}?objectName=${addr}&access_token=${token}`;
  389. return src;
  390. },
  391. },
  392. mounted() {
  393. // console.log(this.$route);
  394. if (this.$route.query.id) {
  395. this.id = this.$route.query.id;
  396. if (this.id) {
  397. this.$axios({
  398. method: "post",
  399. url: this.$api.workManagement.selectProjectDetailsById,
  400. data: {
  401. id: this.id,
  402. },
  403. }).then((res) => {
  404. if (res.code == 200 && res.info) {
  405. this.info = res.info;
  406. this.configList.camera =
  407. res.info.sensorCameraList || [];
  408. this.configList.ogt = res.info.sensorOgtList || [];
  409. this.configList.lidar = res.info.sensorLidarList || [];
  410. this.configList.gps = res.info.sensorGpsList || [];
  411. this.modelImgSrc = this.getImgUrl(
  412. res.info.vehicleTopView
  413. );
  414. if (this.info.nowRunState === "30") {
  415. this.downImgSrc = require("@/assets/common/image/others/hasDoc.png");
  416. } else {
  417. this.downImgSrc = require("@/assets/common/image/others/noDoc.png");
  418. }
  419. this.stateList = res.info.stateList || [];
  420. this.resultList = res.info.resultScoreList || [];
  421. // this.resultList = res.info.resultList || [];
  422. this.getDataWayA.data = res.info.algorithmScoreList;
  423. } else {
  424. this.$message.error(res.message || "获取信息失败");
  425. }
  426. });
  427. }
  428. }
  429. },
  430. };
  431. </script>
  432. <style lang='less' scoped>
  433. .projectInfoPanel {
  434. padding: 18px;
  435. .panel {
  436. border: 1px solid #dfdfdf;
  437. padding: 12px 24px;
  438. box-shadow: 0 4px 9px #dcdcdc;
  439. border-radius: 3px;
  440. }
  441. .titlePanel {
  442. padding-bottom: 6px;
  443. border-bottom: 1px dotted @gray;
  444. }
  445. .headPanel {
  446. margin-bottom: 25px;
  447. .box {
  448. flex: 1;
  449. }
  450. .boxContent {
  451. display: flex;
  452. flex-wrap: wrap;
  453. padding: 18px 15px;
  454. }
  455. .info {
  456. display: flex;
  457. width: 345px;
  458. margin: 0 12px 22px 0;
  459. word-break: break-all;
  460. span {
  461. display: block;
  462. width: 105px;
  463. color: @gray;
  464. }
  465. b {
  466. flex: 1;
  467. font-weight: normal;
  468. }
  469. }
  470. }
  471. .topPanel {
  472. .box {
  473. flex: 1;
  474. }
  475. .boxB {
  476. margin-right: 18px;
  477. }
  478. .titlePanel {
  479. position: relative;
  480. .download {
  481. position: absolute;
  482. top: 0;
  483. right: 0;
  484. color: @themeColor;
  485. font-size: 18px;
  486. // cursor: pointer;
  487. }
  488. }
  489. .boxContent {
  490. padding: 18px 15px;
  491. }
  492. .info {
  493. display: flex;
  494. margin-bottom: 22px;
  495. word-break: break-all;
  496. span {
  497. display: block;
  498. width: 75px;
  499. color: @gray;
  500. }
  501. b {
  502. flex: 1;
  503. font-weight: normal;
  504. }
  505. }
  506. .boxContentC {
  507. display: flex;
  508. justify-content: center;
  509. align-items: center;
  510. height: 100%;
  511. .cbox {
  512. text-align: center;
  513. color: @themeColor;
  514. // cursor: pointer;
  515. > div {
  516. margin-top: 18px;
  517. }
  518. }
  519. }
  520. }
  521. .centerPanel {
  522. margin: 25px 0;
  523. .boxContentA {
  524. padding: 18px 15px;
  525. .info {
  526. display: flex;
  527. margin-bottom: 22px;
  528. word-break: break-all;
  529. span {
  530. display: block;
  531. width: 75px;
  532. color: @gray;
  533. }
  534. b {
  535. flex: 1;
  536. font-weight: normal;
  537. }
  538. }
  539. }
  540. .boxContentB {
  541. display: flex;
  542. justify-content: space-around;
  543. padding-top: 30px;
  544. .canvasBox {
  545. flex: 1;
  546. }
  547. }
  548. }
  549. .bottomPanel {
  550. .boxContentA {
  551. display: flex;
  552. justify-content: space-around;
  553. padding: 45px 0;
  554. }
  555. .chart {
  556. width: 50%;
  557. .pieTitle {
  558. padding: 0 0 30px;
  559. text-align: center;
  560. font-size: 16px;
  561. font-weight: bold;
  562. }
  563. .pie {
  564. height: calc(40vh);
  565. }
  566. }
  567. }
  568. }
  569. </style>