manualRunProjectDetail.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. <template>
  2. <div>
  3. <el-form
  4. ref="form"
  5. :model="form"
  6. :rules="rules"
  7. label-width="140px"
  8. class="flexBox"
  9. >
  10. <div class="formItemBox">
  11. <el-form-item label="项目名称:" prop="projectName">
  12. <el-input
  13. placeholder="请输入"
  14. maxlength="120"
  15. v-autoTrim="{ obj: form, key: 'projectName' }"
  16. v-model="form.projectName"
  17. >
  18. </el-input>
  19. </el-form-item>
  20. <el-form-item label="项目描述:" prop="projectDescribe">
  21. <el-input
  22. type="textarea"
  23. :autosize="{ minRows: 4, maxRows: 4 }"
  24. placeholder="请输入"
  25. maxlength="300"
  26. v-autoTrim="{ obj: form, key: 'projectDescribe' }"
  27. v-model="form.projectDescribe"
  28. >
  29. </el-input>
  30. </el-form-item>
  31. <el-form-item label="算法来源:" prop="algorithmType">
  32. <el-radio v-model="form.algorithmType" label="1" @change="typeChange"
  33. >私有导入</el-radio
  34. >
  35. <el-radio v-model="form.algorithmType" label="3" @change="typeChange"
  36. >算法平台</el-radio
  37. >
  38. </el-form-item>
  39. <el-form-item label="选择算法:" prop="algorithmArrayS">
  40. <el-cascader
  41. ref="cascaderA"
  42. v-model="form.algorithmArrayS"
  43. :options="algorithmList"
  44. :props="props"
  45. @change="algorithmSelChange"
  46. ></el-cascader>
  47. <!-- <el-select v-model="form.algorithm">
  48. <el-option
  49. v-for="item in algorithmList"
  50. :label="item.name"
  51. :value="item.id"
  52. :key="item.id"
  53. :title="item.description"
  54. ></el-option>
  55. </el-select> -->
  56. </el-form-item>
  57. <el-form-item label="选择车辆:" prop="vehicleArrayS">
  58. <el-cascader
  59. ref="cascaderB"
  60. v-model="form.vehicleArrayS"
  61. :options="vehicleList"
  62. :props="props"
  63. @change="vehicleSelChange"
  64. ></el-cascader>
  65. <!-- <el-select
  66. v-model="form.vehicle"
  67. @change="vehicleSelChange"
  68. >
  69. <el-option
  70. v-for="item in vehicleList"
  71. :label="item.name"
  72. :value="item.id"
  73. :key="item.id"
  74. :title="item.description"
  75. ></el-option>
  76. </el-select> -->
  77. </el-form-item>
  78. <el-form-item label="选择场景:" prop="sceneArrayS">
  79. <el-cascader
  80. ref="cascaderC"
  81. v-model="form.sceneArrayS"
  82. :options="sceneList"
  83. :props="props"
  84. @change="sceneSelChange"
  85. ></el-cascader>
  86. <!-- <el-select v-model="form.scene" @change="sceneSelChange">
  87. <el-option
  88. v-for="item in sceneList"
  89. :label="item.name"
  90. :value="item.id"
  91. :key="item.id"
  92. ></el-option>
  93. </el-select> -->
  94. </el-form-item>
  95. <el-form-item label="并行度:" prop="parallelism">
  96. <el-input
  97. :disabled="runDisabled"
  98. placeholder="请输入"
  99. maxlength="10"
  100. v-autoTrim="{ obj: form, key: 'parallelism' }"
  101. v-model="form.parallelism"
  102. >
  103. </el-input>
  104. </el-form-item>
  105. <el-form-item label="场景评价规则:"></el-form-item>
  106. <el-form-item label="危险度" class="rule-item" prop="riskEvaluationRuleId">
  107. <el-select placeholder="暂不评价" v-model="form.riskEvaluationRuleId">
  108. <el-option
  109. v-for="(item, idx) in scriptList['2']"
  110. :key="idx"
  111. :label="item.ruleName"
  112. :value="item.ruleId"
  113. ></el-option>
  114. </el-select>
  115. </el-form-item>
  116. <el-form-item label="复杂度" class="rule-item" prop="complexityEvaluationRuleId">
  117. <el-select placeholder="暂不评价" v-model="form.complexityEvaluationRuleId">
  118. <el-option
  119. v-for="(item, idx) in scriptList['1']"
  120. :key="idx"
  121. :label="item.ruleName"
  122. :value="item.ruleId"
  123. ></el-option>
  124. </el-select>
  125. </el-form-item>
  126. <el-form-item label="暴露率" class="rule-item" prop="exposureRateEvaluationRuleId">
  127. <el-select placeholder="暂不评价" v-model="form.exposureRateEvaluationRuleId">
  128. <el-option
  129. v-for="(item, idx) in scriptList['3']"
  130. :key="idx"
  131. :label="item.ruleName"
  132. :value="item.ruleId"
  133. ></el-option>
  134. </el-select>
  135. </el-form-item>
  136. <el-form-item label="覆盖率" class="rule-item" prop="coverageRateEvaluationRuleId">
  137. <el-select placeholder="暂不评价" v-model="form.coverageRateEvaluationRuleId">
  138. <el-option
  139. v-for="(item, idx) in scriptList['4']"
  140. :key="idx"
  141. :label="item.ruleName"
  142. :value="item.ruleId"
  143. ></el-option>
  144. </el-select>
  145. </el-form-item>
  146. <el-form-item label="最大仿真时间(s):" prop="maxSimulationTime">
  147. <div style="position: relative;">
  148. <el-input
  149. placeholder="请输入"
  150. maxlength="10"
  151. v-autoTrim="{ obj: form, key: 'maxSimulationTime' }"
  152. v-model="form.maxSimulationTime"
  153. >
  154. </el-input>
  155. <span style="position: absolute; right: -160px;">(最小是5,最大是10000)</span>
  156. </div>
  157. </el-form-item>
  158. <el-form-item label="是否选择GPU:" prop="isChoiceGpu">
  159. <el-radio v-model="form.isChoiceGpu" label="0">是</el-radio>
  160. <el-radio v-model="form.isChoiceGpu" label="1">否</el-radio>
  161. </el-form-item>
  162. </div>
  163. <div class="tipBox">
  164. <div class="tip tipA">
  165. <!-- (传感器1:根据车辆自动带出;传感器2:根据车辆自动带出) -->
  166. <span v-for="item in sensors" :key="item" v-bind:class="{
  167. iconA: item === 'camera',
  168. iconB: item === 'ogt',
  169. iconC: item === 'lidar',
  170. iconE: item === 'gps',
  171. }"></span>
  172. </div>
  173. <div class="tip">(场景数量:{{ sceneCount }})</div>
  174. <!-- <div class="tip flexBox">
  175. <div>(下次运行时间:XX时XX分XX秒)</div>
  176. <div class="tipBtnBox">
  177. <el-button type="primary">规则查看</el-button>
  178. </div>
  179. </div> -->
  180. <div class="tip">(最多可用资源:{{ maxCount }})</div>
  181. <!-- <div class="tip">(最小是5,最大是10000)</div> -->
  182. </div>
  183. </el-form>
  184. <div class="btns">
  185. <el-button type="primary" @click="save(false)">保存</el-button>
  186. <el-button type="primary" @click="save(true)" v-if="this.$route.query.id">另存为</el-button>
  187. <el-button type="primary" @click="save(false, true)" :disabled="runDisabled">提交</el-button>
  188. <el-button type="primary" plain @click="cancel">取消</el-button>
  189. </div>
  190. </div>
  191. </template>
  192. <script>
  193. //import from '';
  194. let maxCount = 0 // 用于校验
  195. let validateNum = (rule, value, callback) => {
  196. !/^(\d+)$/.test(value) && callback(new Error(rule.message))
  197. if (+value <= 0 || +value > +maxCount) callback(new Error(rule.message))
  198. callback()
  199. }
  200. let validateNumA = (rule, value, callback) => {
  201. !/^(\d+)$/.test(value) && callback(new Error(rule.message));
  202. if (+value < 5 || +value > 10000) callback(new Error(rule.message));
  203. callback();
  204. };
  205. let validateNumB = (rule, value, callback) => {
  206. !/^(\d+)$/.test(value) && callback(new Error(rule.message))
  207. if (+value <= 0) callback(new Error(rule.message))
  208. callback()
  209. }
  210. export default {
  211. name: 'manualRunProjectDetail', // 标准化测试详情
  212. components: {},
  213. data() {
  214. return {
  215. form: {
  216. id: '',
  217. projectName: '', // 项目名称
  218. projectDescribe: '', // 项目描述
  219. algorithmType: '1', // 算法来源
  220. algorithm: '', // 选择算法
  221. algorithmArrayS: '', // 选择算法
  222. vehicle: '', // 选择车辆
  223. vehicleArrayS: '', // 选择车辆
  224. scene: '', // 选择场景
  225. sceneArrayS: '', // 选择场景
  226. parallelism: '', // 并行度
  227. maxSimulationTime: '', // 最大仿真时间
  228. isChoiceGpu: '0', // 是否选择GPU
  229. nowRunState: '10', // 运行状态
  230. complexityEvaluationRuleId: '', // 复杂度
  231. riskEvaluationRuleId: '', // 危险度
  232. exposureRateEvaluationRuleId: '', // 暴露率
  233. coverageRateEvaluationRuleId: '', // 覆盖率
  234. },
  235. algorithmList: [], // 算法对应列表
  236. vehicleList: [], // 车辆对应列表
  237. sceneList: [], // 场景对应列表
  238. maxCount: 0, // 最多可用资源
  239. sceneCount: 0, // 场景数量
  240. scriptList: {}, // 评价脚本列表
  241. rules: {
  242. projectName: [{ required: true, message: '请输入', trigger: 'blur' }],
  243. projectDescribe: [
  244. { required: true, message: '请输入', trigger: 'blur' },
  245. ],
  246. algorithmType: [
  247. { required: true, message: '请选择', trigger: 'change' },
  248. ],
  249. algorithmArrayS: [
  250. { required: true, message: '请选择', trigger: 'change' },
  251. ],
  252. vehicleArrayS: [
  253. { required: true, message: '请选择', trigger: 'change' },
  254. ],
  255. sceneArrayS: [{ required: true, message: '请选择', trigger: 'change' }],
  256. parallelism: [
  257. { required: true, message: '请输入', trigger: 'blur' },
  258. // {
  259. // validator: validateNum,
  260. // message: "请输入不大于最多可用资源的正整数",
  261. // trigger: ["blur"],
  262. // },
  263. ],
  264. maxSimulationTime: [
  265. { required: true, message: '请输入', trigger: 'blur' },
  266. {
  267. validator: validateNumA,
  268. message: '请输入不小于5且不大于10000的正整数',
  269. trigger: ['blur'],
  270. },
  271. ],
  272. isChoiceGpu: [{ required: true, message: '请选择', trigger: 'change' }],
  273. },
  274. sensors: [], // 选中车辆后对应的传感器数组
  275. runDisabled: false, // 若最多可用资源为0,则不可点击"提交"
  276. props: {
  277. multiple: false,
  278. label: 'name',
  279. value: 'code',
  280. },
  281. }
  282. },
  283. computed: {},
  284. methods: {
  285. async getLists(dropDownType = '') {
  286. await this.$axios({
  287. method: 'post',
  288. url: this.$api.workManagement.selectDropDownByTypeNew,
  289. data: {
  290. dropDownType,
  291. algorithmType: this.form.algorithmType,
  292. },
  293. }).then((res) => {
  294. if (res.code == 200 && res.info) {
  295. res.info.forEach((item) => {
  296. if (item.type === '1') {
  297. // item.dropDownList.forEach((i) => {
  298. // if (i.share === "1") i.name = i.name + "(公有)";
  299. // });
  300. this.algorithmList = item.dropDownList
  301. } else if (item.type === '2') {
  302. // item.dropDownList.forEach((i) => {
  303. // if (i.share === "1") i.name = i.name + "(公有)";
  304. // });
  305. this.vehicleList = item.dropDownList
  306. } else if (item.type === '3') {
  307. // item.dropDownList.forEach((i) => {
  308. // if (i.share === "1") i.name = i.name + "(公有)";
  309. // });
  310. this.sceneList = item.dropDownList
  311. }
  312. // 空表示第一次进,有值表示在切换算法来源,需要清空选择算法的值
  313. if (dropDownType) {
  314. this.form.algorithm = ''
  315. this.form.algorithmArrayS = []
  316. this.$nextTick(() => {
  317. // this.$refs.form.clearValidate("algorithm");
  318. this.$refs.form.clearValidate('algorithmArrayS')
  319. })
  320. }
  321. })
  322. } else {
  323. this.$message.error(res.message || '获取信息失败')
  324. }
  325. })
  326. },
  327. typeChange() {
  328. this.getLists('1')
  329. },
  330. async getMaxSimulationTime() {
  331. await this.$axios({
  332. method: 'post',
  333. url: this.$api.workManagement.selectMaxParallelism,
  334. data: {},
  335. }).then((res) => {
  336. if (res.code == 200 && res.info && res.info != 0) {
  337. this.maxCount = maxCount = res.info
  338. if (res.info == -1) {
  339. this.rules.parallelism.push({
  340. validator: validateNumB,
  341. message: '请输入正整数',
  342. trigger: ['blur'],
  343. })
  344. } else {
  345. this.rules.parallelism.push({
  346. validator: validateNum,
  347. message: '请输入不大于最多可用资源的正整数',
  348. trigger: ['blur'],
  349. })
  350. }
  351. } else if (res.code == 200 && res.info == 0) {
  352. this.maxCount = maxCount = 0
  353. this.runDisabled = true
  354. this.form.parallelism = 0
  355. } else {
  356. this.$message.error(res.message || '获取信息失败')
  357. }
  358. })
  359. },
  360. algorithmSelChange(v) {
  361. // console.log(v);
  362. // console.log(this.$refs.cascaderA.getCheckedNodes(true)[0].data.vo);
  363. let item = this.$refs.cascaderA.getCheckedNodes(true)[0].data.vo
  364. this.form.algorithm = item.id
  365. },
  366. vehicleSelChange(v) {
  367. let item = this.$refs.cascaderB.getCheckedNodes(true)[0].data.vo
  368. this.form.vehicle = item.id
  369. let sensor = item.sensor
  370. if (!sensor) {
  371. this.sensors = []
  372. } else {
  373. this.sensors = sensor.split(',')
  374. }
  375. // let sensor = this.vehicleList.find((i) => i.id === item).sensor;
  376. // if (!sensor) {
  377. // this.sensors = [];
  378. // } else {
  379. // this.sensors = sensor.split(",");
  380. // }
  381. },
  382. sceneSelChange(v) {
  383. let item = this.$refs.cascaderC.getCheckedNodes(true)[0].data.vo
  384. this.form.scene = item.id
  385. this.sceneCount = item.sceneNum
  386. // this.sceneCount = this.sceneList.find(
  387. // (i) => i.id === item
  388. // ).sceneNum;
  389. },
  390. getScriptList() {
  391. this.$axios({
  392. method: 'post',
  393. url: this.$api.sceneLibrary.getScriptListByType,
  394. data: {
  395. sceneEvaluationType: ['1', '2', '3', '4'],
  396. },
  397. }).then((res) => {
  398. this.scriptList = res.info
  399. })
  400. },
  401. save(isAdd = false, needChange = false) {
  402. // isAdd是否强制新增,needChange是否需要改变状态
  403. this.$refs.form.validate((valid) => {
  404. if (valid) {
  405. if (isAdd) {
  406. // 另存为
  407. this.form.id = ''
  408. }
  409. this.form.nowRunState = '10'
  410. this.$axios({
  411. method: 'post',
  412. url: this.$api.workManagement.addOrUpdateProject,
  413. data: {
  414. ...this.form,
  415. },
  416. }).then((res) => {
  417. if (res.code == 200) {
  418. this.$message.success('保存成功')
  419. if (needChange) {
  420. this.form.id = res.info
  421. this.stateChange()
  422. } else {
  423. this.cancel()
  424. }
  425. } else {
  426. this.$message.error(res.message || '保存失败')
  427. }
  428. })
  429. }
  430. })
  431. },
  432. cancel() {
  433. this.$router.replace({ path: '/manualRunProjectList' })
  434. },
  435. stateChange() {
  436. this.$axios({
  437. method: 'post',
  438. url: this.$api.workManagement.updateProjectNowRunState,
  439. data: {
  440. id: this.form.id,
  441. nowRunState: '20',
  442. },
  443. }).then((res) => {
  444. if (res.code == 200) {
  445. this.$message.success('提交成功')
  446. this.cancel()
  447. } else {
  448. this.$message.error(res.message || '提交失败')
  449. }
  450. })
  451. },
  452. },
  453. mounted() {
  454. if (this.$route.query.id) {
  455. let id = ''
  456. this.form.id = id = this.$route.query.id
  457. if (id) {
  458. this.$axios({
  459. method: 'post',
  460. url: this.$api.workManagement.selectProjectById,
  461. data: {
  462. id,
  463. },
  464. }).then(async (res) => {
  465. if (res.code == 200 && res.info) {
  466. this.form = res.info
  467. await this.getLists()
  468. await this.getMaxSimulationTime()
  469. this.vehicleSelChange(res.info.vehicle)
  470. this.sceneSelChange(res.info.scene)
  471. } else {
  472. this.$message.error(res.message || '获取信息失败')
  473. }
  474. })
  475. }
  476. this.getScriptList()
  477. } else {
  478. this.getLists()
  479. this.getMaxSimulationTime()
  480. this.getScriptList()
  481. }
  482. },
  483. }
  484. </script>
  485. <style lang='less' scoped>
  486. .el-form {
  487. width: 60%;
  488. min-width: 900px;
  489. padding-top: 60px;
  490. margin: 0 auto;
  491. .formItemBox {
  492. flex: 1;
  493. /deep/ .el-input,
  494. .el-select,
  495. .el-cascader {
  496. width: 100%;
  497. }
  498. .el-cascader {
  499. height: 32px;
  500. line-height: 32px;
  501. }
  502. }
  503. .el-textarea {
  504. height: 96px;
  505. }
  506. .tipBox {
  507. min-width: 270px;
  508. margin-left: 20px;
  509. .tip {
  510. margin-bottom: 22px;
  511. line-height: 32px;
  512. }
  513. .tip1{
  514. margin-bottom: -100px;
  515. border: 1px solid black;
  516. }
  517. .tipA {
  518. height: 32px;
  519. // 按54往上加
  520. margin-top: 280px;
  521. .iconA {
  522. background: url('../../assets/common/image/sensor/001.png') center
  523. no-repeat;
  524. background-size: contain;
  525. }
  526. .iconB {
  527. background: url('../../assets/common/image/sensor/002.png') center
  528. no-repeat;
  529. background-size: contain;
  530. }
  531. .iconC {
  532. background: url('../../assets/common/image/sensor/003.png') center
  533. no-repeat;
  534. background-size: contain;
  535. }
  536. .iconD {
  537. background: url('../../assets/common/image/sensor/004.png') center
  538. no-repeat;
  539. background-size: contain;
  540. }
  541. .iconE {
  542. background: url('../../assets/common/image/sensor/005.png') center
  543. no-repeat;
  544. background-size: contain;
  545. }
  546. span {
  547. display: inline-block;
  548. width: 18px;
  549. height: 18px;
  550. margin-top: 7px;
  551. margin-right: 6px;
  552. }
  553. }
  554. .tipB {
  555. padding-top: 54px;
  556. }
  557. .tipBtnBox {
  558. margin-left: 20px;
  559. }
  560. }
  561. }
  562. .rule-item {
  563. margin-left: 60px;
  564. }
  565. .btns {
  566. padding-top: 30px;
  567. text-align: center;
  568. }
  569. </style>