vehicleModelCanvas.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. <template>
  2. <div class="vehicleModelPanel">
  3. <model-list
  4. ref="modelList"
  5. class="modelList"
  6. @showInfo="showInfo"
  7. @addOne="addOne"
  8. @delOne="delOne"
  9. :getListApi="getListApi"
  10. :showName="showName"
  11. :curOne="curOne"
  12. ></model-list>
  13. <div class="contentPanel">
  14. <el-form
  15. ref="form"
  16. :model="form"
  17. :rules="rules"
  18. label-width="160px"
  19. >
  20. <div class="inputBox flexBox">
  21. <span class="label">车辆ID</span>
  22. <div>{{ form.vehicleCode }}</div>
  23. </div>
  24. <div class="flexBox">
  25. <el-form-item label="车辆名称:" prop="vehicleName">
  26. <el-input
  27. placeholder="请输入"
  28. maxlength="60"
  29. v-autoTrim="{ obj: form, key: 'vehicleName' }"
  30. v-model="form.vehicleName"
  31. >
  32. </el-input>
  33. </el-form-item>
  34. <el-form-item label="车辆描述:" prop="description">
  35. <el-input
  36. v-autoTrim="{ obj: form, key: 'description' }"
  37. v-model="form.description"
  38. placeholder="请输入"
  39. maxlength="200"
  40. ></el-input>
  41. </el-form-item>
  42. <el-form-item label="车辆模型:" prop="vehicleType">
  43. <el-cascader
  44. ref="cascader"
  45. v-model="form.vehicleType"
  46. :options="modelLabelList"
  47. :props="props"
  48. @change="modelLabelChange"
  49. ></el-cascader>
  50. </el-form-item>
  51. <el-form-item label="车辆模型标识:" prop="modelLabel">
  52. <el-input
  53. placeholder="请输入"
  54. v-autoTrim="{ obj: form, key: 'modelLabel' }"
  55. v-model="form.modelLabel"
  56. disabled
  57. >
  58. </el-input>
  59. </el-form-item>
  60. </div>
  61. <div class="titlePanel">
  62. <div class="titlePanelBor">控制参数</div>
  63. </div>
  64. <div class="flexBox">
  65. <el-form-item label="最大速度(km/h):" prop="maxSpeed">
  66. <el-input
  67. placeholder="请输入"
  68. maxlength="12"
  69. v-autoTrim="{ obj: form, key: 'maxSpeed' }"
  70. v-model="form.maxSpeed"
  71. >
  72. </el-input>
  73. </el-form-item>
  74. <el-form-item label="发动机功率(kW):" prop="enginePower">
  75. <el-input
  76. placeholder="请输入"
  77. maxlength="12"
  78. v-autoTrim="{ obj: form, key: 'enginePower' }"
  79. v-model="form.enginePower"
  80. >
  81. </el-input>
  82. </el-form-item>
  83. <el-form-item
  84. label="最大减速度(m/s²):"
  85. prop="maxDeceleration"
  86. >
  87. <el-input
  88. placeholder="请输入"
  89. maxlength="12"
  90. v-autoTrim="{ obj: form, key: 'maxDeceleration' }"
  91. v-model="form.maxDeceleration"
  92. >
  93. </el-input>
  94. </el-form-item>
  95. <el-form-item
  96. label="最大转向角度(rad):"
  97. prop="maxSteeringAngle"
  98. >
  99. <el-input
  100. placeholder="请输入"
  101. maxlength="12"
  102. v-autoTrim="{ obj: form, key: 'maxSteeringAngle' }"
  103. v-model="form.maxSteeringAngle"
  104. >
  105. </el-input>
  106. </el-form-item>
  107. <el-form-item label="驱动方式:" prop="wheelDrive">
  108. <el-select v-model="form.wheelDrive">
  109. <el-option
  110. v-for="item in wheelDriveList"
  111. :label="item.caption"
  112. :value="item.code"
  113. :key="item.code"
  114. ></el-option>
  115. </el-select>
  116. </el-form-item>
  117. </div>
  118. <div class="titlePanel">
  119. <div class="titlePanelBor">效率参数</div>
  120. </div>
  121. <div class="flexBox">
  122. <el-form-item label="总效率:" prop="overallEfficiency">
  123. <el-input
  124. placeholder="请输入"
  125. maxlength="9"
  126. v-autoTrim="{ obj: form, key: 'overallEfficiency' }"
  127. v-model="form.overallEfficiency"
  128. >
  129. </el-input>
  130. </el-form-item>
  131. <el-form-item
  132. label="前表面有效面积(㎡):"
  133. prop="frontSurfaceEffective"
  134. >
  135. <el-input
  136. placeholder="请输入"
  137. maxlength="12"
  138. v-autoTrim="{
  139. obj: form,
  140. key: 'frontSurfaceEffective',
  141. }"
  142. v-model="form.frontSurfaceEffective"
  143. >
  144. </el-input>
  145. </el-form-item>
  146. <el-form-item
  147. label="空气阻力系数:"
  148. prop="airDragCoefficient"
  149. >
  150. <el-input
  151. placeholder="请输入"
  152. maxlength="9"
  153. v-autoTrim="{
  154. obj: form,
  155. key: 'airDragCoefficient',
  156. }"
  157. v-model="form.airDragCoefficient"
  158. >
  159. </el-input>
  160. </el-form-item>
  161. <el-form-item
  162. label="滚动阻力系数:"
  163. prop="rollingResistanceCoefficient"
  164. >
  165. <el-input
  166. placeholder="请输入"
  167. maxlength="9"
  168. v-autoTrim="{
  169. obj: form,
  170. key: 'rollingResistanceCoefficient',
  171. }"
  172. v-model="form.rollingResistanceCoefficient"
  173. >
  174. </el-input>
  175. </el-form-item>
  176. </div>
  177. <div class="titlePanel">
  178. <div class="titlePanelBor">几何参数</div>
  179. </div>
  180. <div class="flexBox">
  181. <el-form-item label="车轮直径(m):" prop="wheelDiameter">
  182. <el-input
  183. placeholder="请输入"
  184. maxlength="12"
  185. v-autoTrim="{ obj: form, key: 'wheelDiameter' }"
  186. v-model="form.wheelDiameter"
  187. >
  188. </el-input>
  189. </el-form-item>
  190. <el-form-item label="车前距(m):" prop="frontDistance">
  191. <el-input
  192. placeholder="请输入"
  193. maxlength="12"
  194. v-autoTrim="{ obj: form, key: 'frontDistance' }"
  195. v-model="form.frontDistance"
  196. >
  197. </el-input>
  198. </el-form-item>
  199. <el-form-item label="车后距(m):" prop="rearDistance">
  200. <el-input
  201. placeholder="请输入"
  202. maxlength="12"
  203. v-autoTrim="{ obj: form, key: 'rearDistance' }"
  204. v-model="form.rearDistance"
  205. >
  206. </el-input>
  207. </el-form-item>
  208. <el-form-item label="车左距(m):" prop="leftDistance">
  209. <el-input
  210. placeholder="请输入"
  211. maxlength="12"
  212. v-autoTrim="{ obj: form, key: 'leftDistance' }"
  213. v-model="form.leftDistance"
  214. >
  215. </el-input>
  216. </el-form-item>
  217. <el-form-item label="车右距(m):" prop="rightDistance">
  218. <el-input
  219. placeholder="请输入"
  220. maxlength="12"
  221. v-autoTrim="{ obj: form, key: 'rightDistance' }"
  222. v-model="form.rightDistance"
  223. >
  224. </el-input>
  225. </el-form-item>
  226. <el-form-item label="车高(m):" prop="heightDistance">
  227. <el-input
  228. placeholder="请输入"
  229. maxlength="12"
  230. v-autoTrim="{ obj: form, key: 'heightDistance' }"
  231. v-model="form.heightDistance"
  232. >
  233. </el-input>
  234. </el-form-item>
  235. <el-form-item label="轴距(m):" prop="wheelbase">
  236. <el-input
  237. placeholder="请输入"
  238. maxlength="12"
  239. v-autoTrim="{ obj: form, key: 'wheelbase' }"
  240. v-model="form.wheelbase"
  241. >
  242. </el-input>
  243. </el-form-item>
  244. <el-form-item label="质量(kg):" prop="mass">
  245. <el-input
  246. placeholder="请输入"
  247. maxlength="12"
  248. v-autoTrim="{ obj: form, key: 'mass' }"
  249. v-model="form.mass"
  250. >
  251. </el-input>
  252. </el-form-item>
  253. </div>
  254. <div class="titlePanel">
  255. <div class="titlePanelBor">视图</div>
  256. </div>
  257. <div class="modelBox">
  258. <img v-show="modelImgSrc" :src="modelImgSrc" width="100%" />
  259. </div>
  260. </el-form>
  261. <div class="btns">
  262. <!-- 新增和私有才能修改和保存 -->
  263. <!-- 私有才能分享 -->
  264. <!-- share有值 才能另存为 -->
  265. <el-button
  266. type="primary"
  267. v-show="form.share === '0' || form.share === ''"
  268. @click="save(false)"
  269. >保存</el-button
  270. >
  271. <el-button
  272. type="primary"
  273. v-if="roleCode === '0' || roleCode === '1'"
  274. v-show="form.share === '0'"
  275. @click="share"
  276. >分享</el-button
  277. >
  278. <el-button
  279. type="primary"
  280. v-show="form.share === '0' || form.share === '1'"
  281. @click="save(true)"
  282. >另存为</el-button
  283. >
  284. <el-button type="primary" plain @click="cancel">取消</el-button>
  285. </div>
  286. </div>
  287. </div>
  288. </template>
  289. <script>
  290. import modelList from "./components/modelList.vue";
  291. import { mapState } from "vuex";
  292. export default {
  293. name: "vehicleModel", // 车辆模型
  294. components: { modelList },
  295. data() {
  296. // 校验非负且最多4位小数
  297. let validateNum = (rule, value, callback) => {
  298. !/^(0|[1-9][0-9]*)(\.\d{1,4})?$/.test(value) &&
  299. callback(new Error(rule.message));
  300. callback();
  301. };
  302. // 校验不大于1
  303. let validateNoMore1 = (rule, value, callback) => {
  304. if (value > 1) {
  305. callback(new Error(rule.message));
  306. return;
  307. }
  308. callback();
  309. };
  310. return {
  311. getListApi: this.$api.modelLibrary.getVehicleList, // 获取列表api
  312. showName: "vehicleName",
  313. typeList: [],
  314. // imgSrc: require("@/assets/common/image/car.png"),
  315. form: {
  316. vehicleCode: "", // 车辆ID
  317. vehicleName: "", // 车辆名称
  318. description: "", // 车辆描述
  319. // vehicleType: "", // 车辆类型
  320. // vehicleModel: "", // 车辆型号
  321. // vehicleColour: "", // 车辆颜色
  322. vehicleType: [], // 车辆模型
  323. modelLabel: "", // 车辆模型标识
  324. maxSpeed: "", // 最大速度
  325. enginePower: "", // 发动机功率
  326. maxDeceleration: "", // 最大减速度
  327. maxSteeringAngle: "", // 最大转角
  328. wheelDrive: "", // 驱动方式
  329. overallEfficiency: "", // 总效率
  330. frontSurfaceEffective: "", // 前表面有效面积
  331. airDragCoefficient: "", // 空气阻力系数
  332. rollingResistanceCoefficient: "", // 滚动阻力系数
  333. wheelDiameter: "", // 车轮直径
  334. frontDistance: "", // 车前距
  335. rearDistance: "", // 车后距
  336. leftDistance: "", // 车左距
  337. rightDistance: "", // 车右距
  338. heightDistance: "", // 车高
  339. wheelbase: "", // 轴距
  340. mass: "", // 质量
  341. share: "", // 分享
  342. // vehicleImage: "", // 对应的图片相对地址
  343. id: "",
  344. vehicleFrontView: "", // 对应的图片相对地址
  345. vehicleTopView: "", // 对应的图片相对地址
  346. },
  347. vehicleTypeList: [],
  348. vehicleModelList: [],
  349. vehicleColourList: [],
  350. wheelDriveList: [],
  351. rules: {
  352. vehicleName: [
  353. { required: true, message: "请输入", trigger: "blur" },
  354. ],
  355. description: [
  356. { required: true, message: "请输入", trigger: "blur" },
  357. ],
  358. // vehicleModel: [
  359. // { required: true, message: "请输入", trigger: "blur" },
  360. // ],
  361. // vehicleColour: [
  362. // { required: true, message: "请输入", trigger: "blur" },
  363. // ],
  364. modelLabel: [
  365. { required: true, message: "请输入", trigger: "blur" },
  366. ],
  367. maxSpeed: [
  368. { required: true, message: "请输入", trigger: "blur" },
  369. {
  370. validator: validateNum,
  371. message: "请输入最多带有4位小数的非负数",
  372. trigger: ["blur"],
  373. },
  374. ],
  375. enginePower: [
  376. { required: true, message: "请输入", trigger: "blur" },
  377. {
  378. validator: validateNum,
  379. message: "请输入最多带有4位小数的非负数",
  380. trigger: ["blur"],
  381. },
  382. ],
  383. maxDeceleration: [
  384. { required: true, message: "请输入", trigger: "blur" },
  385. {
  386. validator: validateNum,
  387. message: "请输入最多带有4位小数的非负数",
  388. trigger: ["blur"],
  389. },
  390. ],
  391. maxSteeringAngle: [
  392. { required: true, message: "请输入", trigger: "blur" },
  393. {
  394. validator: validateNum,
  395. message: "请输入最多带有4位小数的非负数",
  396. trigger: ["blur"],
  397. },
  398. ],
  399. overallEfficiency: [
  400. { required: true, message: "请输入", trigger: "blur" },
  401. {
  402. validator: validateNoMore1,
  403. message: "请输入不大于1的非负数",
  404. trigger: ["blur"],
  405. },
  406. {
  407. validator: validateNum,
  408. message: "请输入最多带有4位小数的非负数",
  409. trigger: ["blur"],
  410. },
  411. ],
  412. frontSurfaceEffective: [
  413. { required: true, message: "请输入", trigger: "blur" },
  414. {
  415. validator: validateNum,
  416. message: "请输入最多带有4位小数的非负数",
  417. trigger: ["blur"],
  418. },
  419. ],
  420. airDragCoefficient: [
  421. { required: true, message: "请输入", trigger: "blur" },
  422. {
  423. validator: validateNoMore1,
  424. message: "请输入不大于1的非负数",
  425. trigger: ["blur"],
  426. },
  427. {
  428. validator: validateNum,
  429. message: "请输入最多带有4位小数的非负数",
  430. trigger: ["blur"],
  431. },
  432. ],
  433. rollingResistanceCoefficient: [
  434. { required: true, message: "请输入", trigger: "blur" },
  435. {
  436. validator: validateNoMore1,
  437. message: "请输入不大于1的非负数",
  438. trigger: ["blur"],
  439. },
  440. {
  441. validator: validateNum,
  442. message: "请输入最多带有4位小数的非负数",
  443. trigger: ["blur"],
  444. },
  445. ],
  446. wheelDiameter: [
  447. { required: true, message: "请输入", trigger: "blur" },
  448. {
  449. validator: validateNum,
  450. message: "请输入最多带有4位小数的非负数",
  451. trigger: ["blur"],
  452. },
  453. ],
  454. frontDistance: [
  455. { required: true, message: "请输入", trigger: "blur" },
  456. {
  457. validator: validateNum,
  458. message: "请输入最多带有4位小数的非负数",
  459. trigger: ["blur"],
  460. },
  461. ],
  462. rearDistance: [
  463. { required: true, message: "请输入", trigger: "blur" },
  464. {
  465. validator: validateNum,
  466. message: "请输入最多带有4位小数的非负数",
  467. trigger: ["blur"],
  468. },
  469. ],
  470. leftDistance: [
  471. { required: true, message: "请输入", trigger: "blur" },
  472. {
  473. validator: validateNum,
  474. message: "请输入最多带有4位小数的非负数",
  475. trigger: ["blur"],
  476. },
  477. ],
  478. rightDistance: [
  479. { required: true, message: "请输入", trigger: "blur" },
  480. {
  481. validator: validateNum,
  482. message: "请输入最多带有4位小数的非负数",
  483. trigger: ["blur"],
  484. },
  485. ],
  486. heightDistance: [
  487. { required: true, message: "请输入", trigger: "blur" },
  488. {
  489. validator: validateNum,
  490. message: "请输入最多带有4位小数的非负数",
  491. trigger: ["blur"],
  492. },
  493. ],
  494. wheelbase: [
  495. { required: true, message: "请输入", trigger: "blur" },
  496. {
  497. validator: validateNum,
  498. message: "请输入最多带有4位小数的非负数",
  499. trigger: ["blur"],
  500. },
  501. ],
  502. mass: [
  503. { required: true, message: "请输入", trigger: "blur" },
  504. {
  505. validator: validateNum,
  506. message: "请输入最多带有4位小数的非负数",
  507. trigger: ["blur"],
  508. },
  509. ],
  510. wheelDrive: [
  511. { required: true, message: "请选择", trigger: "change" },
  512. ],
  513. vehicleType: [
  514. { required: true, message: "请选择", trigger: "change" },
  515. ],
  516. },
  517. props: {
  518. multiple: false,
  519. label: "name",
  520. value: "code",
  521. },
  522. modelLabelList: [],
  523. modelImgSrc: "",
  524. // 用于当前选中项的展示
  525. curOne: {
  526. share: "",
  527. id: "",
  528. },
  529. };
  530. },
  531. computed: {
  532. ...mapState(["fileHost", "fileUrl", "roleCode"]),
  533. },
  534. methods: {
  535. showInfo(id) {
  536. this.$axios({
  537. method: "post",
  538. url: this.$api.modelLibrary.getVehicleInfo,
  539. data: {
  540. id,
  541. },
  542. }).then((res) => {
  543. if (res.code == 200 && res.info) {
  544. this.$refs.form.clearValidate();
  545. this.form = res.info;
  546. if (res.info.vehicleFrontView) {
  547. this.modelImgSrc = this.getImgUrl(
  548. res.info.vehicleFrontView
  549. );
  550. }
  551. this.curOne = {
  552. share: res.info.share,
  553. id: res.info.id,
  554. };
  555. } else {
  556. this.$message.error(res.message || "获取失败");
  557. }
  558. });
  559. },
  560. save(isAdd) {
  561. this.$refs.form.validate((valid) => {
  562. if (valid) {
  563. // 判断是否新增
  564. if (isAdd || this.form.share === "") {
  565. this.form.id = "";
  566. }
  567. this.$axios({
  568. method: "post",
  569. url: this.$api.modelLibrary.saveVehicle,
  570. data: {
  571. ...this.form,
  572. },
  573. }).then((res) => {
  574. if (res.code == 200 && res.info) {
  575. this.form.id = res.info.id;
  576. this.form.share = res.info.share;
  577. this.form.vehicleCode = res.info.vehicleCode;
  578. this.$message.success("保存成功");
  579. this.$refs.modelList.getList();
  580. this.curOne = {
  581. share: res.info.share,
  582. id: res.info.id,
  583. };
  584. } else {
  585. this.$message.error(res.message || "保存失败");
  586. }
  587. });
  588. }
  589. });
  590. },
  591. addOne() {
  592. this.$refs.form.resetFields();
  593. this.form.vehicleCode = "";
  594. this.form.vehicleFrontView = "";
  595. this.form.vehicleTopView = "";
  596. this.form.share = "";
  597. this.form.id = "";
  598. this.modelImgSrc = "";
  599. this.curOne = {
  600. share: "",
  601. id: "",
  602. };
  603. },
  604. delOne(id) {
  605. this.$axios({
  606. method: "post",
  607. url: this.$api.modelLibrary.delVehicleById,
  608. data: {
  609. id,
  610. },
  611. }).then((res) => {
  612. if (res.code == 200) {
  613. this.$message.success("删除成功");
  614. this.$refs.modelList.getList();
  615. if (this.form.id && id === this.form.id) {
  616. this.addOne();
  617. }
  618. if (id === this.curOne.id) {
  619. this.curOne = {
  620. share: "",
  621. id: "",
  622. };
  623. }
  624. } else {
  625. this.$message.error(res.message || "删除失败");
  626. }
  627. });
  628. },
  629. share() {
  630. this.$axios({
  631. method: "post",
  632. url: this.$api.modelLibrary.shareVehicle,
  633. data: {
  634. ...this.form,
  635. },
  636. }).then((res) => {
  637. if (res.code == 200) {
  638. this.$message.success("分享成功");
  639. this.$refs.modelList.getList();
  640. } else {
  641. this.$message.error(res.message || "分享失败");
  642. }
  643. });
  644. },
  645. cancel() {
  646. if (this.form.id) {
  647. // 取消时有id则重新请求表单
  648. this.showInfo(this.form.id);
  649. } else {
  650. // 清空
  651. this.addOne();
  652. }
  653. },
  654. getImgUrl(addr) {
  655. let url = "";
  656. if (process.env.VUE_APP_IS_DEV == "true") {
  657. url = this.fileHost + this.fileUrl;
  658. } else {
  659. url = this.fileUrl;
  660. }
  661. let token = localStorage.getItem("Authorization").split(" ")[1];
  662. let src = `${url}?objectName=${addr}&access_token=${token}`;
  663. return src;
  664. },
  665. modelLabelChange() {
  666. Object.assign(
  667. this.form,
  668. this.$refs.cascader.getCheckedNodes(true)[0].data.vo
  669. );
  670. this.modelImgSrc = this.getImgUrl(this.form.vehicleFrontView);
  671. },
  672. async getModelLabelList() {
  673. await this.$axios({
  674. method: "post",
  675. url: this.$api.modelLibrary.getVehicleTempTree,
  676. data: {},
  677. }).then((res) => {
  678. if (res.code == 200 && res.info) {
  679. this.modelLabelList = res.info;
  680. } else {
  681. this.$message.error(res.message || "获取车辆模型列表失败");
  682. }
  683. });
  684. },
  685. },
  686. async mounted() {
  687. await this.$dicsListsInit({
  688. vehicleTypeList: "vehicleType",
  689. wheelDriveList: "driveType",
  690. });
  691. this.getModelLabelList();
  692. },
  693. };
  694. </script>
  695. <style lang='less' scoped>
  696. .vehicleModelPanel {
  697. display: flex;
  698. flex: 1;
  699. padding: 15px 30px 30px;
  700. .modelList /deep/ .listPanel {
  701. min-height: 400px;
  702. height: calc(100vh - 120px);
  703. }
  704. .contentPanel {
  705. flex: 1;
  706. padding-left: 30px;
  707. }
  708. .inputBox.flexBox {
  709. margin-bottom: 22px;
  710. .label {
  711. width: 138px;
  712. }
  713. div {
  714. line-height: 32px;
  715. }
  716. }
  717. .titlePanel {
  718. padding: 22px 0;
  719. }
  720. .btns {
  721. padding-top: 30px;
  722. text-align: center;
  723. }
  724. .modelBox {
  725. width: 60%;
  726. min-width: 810px;
  727. }
  728. }
  729. </style>