manualRunProjectDetail.vue 17 KB

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