CarRecord.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. <template>
  2. <div class="peoplerecord">
  3. <!-- 头部区域 -->
  4. <div class="head">
  5. <div class="head-msg">
  6. <img src="@/assets/car.svg" />
  7. </div>
  8. <div class="head-info">车辆记录</div>
  9. </div>
  10. <!-- 左侧车辆记录区域 -->
  11. <div class="left">
  12. <div class="left-watch">
  13. <!-- 车辆记录标题区域 -->
  14. <div class="watch-title">
  15. <div class="watch-img">
  16. <img src="@/assets/jiantou.png" />
  17. </div>
  18. <div class="watch-info">车辆记录</div>
  19. </div>
  20. <!-- 车辆记录筛选区域 -->
  21. <div class="watch_search">
  22. <div class="search_type">
  23. 类型:
  24. <el-select
  25. style="width: 150px"
  26. size="small"
  27. v-model="value_type"
  28. placeholder="请选择驶入方向"
  29. @change="handleChange"
  30. >
  31. <el-option
  32. v-for="(item, index) in options_type"
  33. :key="index"
  34. :label="item"
  35. :value="item"
  36. >
  37. </el-option>
  38. </el-select>
  39. </div>
  40. <div class="search_time">
  41. 时间:
  42. <el-date-picker
  43. style="width: 150px"
  44. type="date"
  45. size="small"
  46. placeholder="选择日期"
  47. v-model="value_time"
  48. @change="handleChange"
  49. value-format="yyyy-MM-dd"
  50. >
  51. </el-date-picker>
  52. </div>
  53. <div class="search_place">
  54. 来源地:
  55. <el-select
  56. style="width: 150px"
  57. size="small"
  58. clearable
  59. v-model="value_place"
  60. placeholder="请选择来源地"
  61. @change="handleChange"
  62. >
  63. <el-option
  64. v-for="(item, index) in options_place"
  65. :key="index"
  66. :label="item"
  67. :value="item"
  68. >
  69. </el-option>
  70. </el-select>
  71. </div>
  72. </div>
  73. <!-- 车辆记录表格区域 -->
  74. <div class="watch-form" v-if="tableData.length">
  75. <el-table
  76. v-loading="loading"
  77. element-loading-text="加载中"
  78. element-loading-spinner="el-icon-loading"
  79. element-loading-background="rgba(0, 0, 0, 0.8)"
  80. stripe
  81. :data="tableData"
  82. style="width: 100%"
  83. height="467"
  84. v-moretable="moretable"
  85. >
  86. <el-table-column prop="id" label="识别ID" align="center" width="93">
  87. </el-table-column>
  88. <el-table-column prop="fx" label="类型" align="center" width="100">
  89. </el-table-column>
  90. <el-table-column
  91. prop="user_name"
  92. label="姓名"
  93. align="center"
  94. width="100"
  95. >
  96. </el-table-column>
  97. <el-table-column
  98. prop="time"
  99. label="时间"
  100. align="center"
  101. width="160"
  102. >
  103. </el-table-column>
  104. <el-table-column
  105. label="位置"
  106. align="center"
  107. width="186"
  108. show-overflow-tooltip
  109. >
  110. <template slot-scope="{ row }">
  111. {{ row.channel_id }}号通道
  112. </template>
  113. </el-table-column>
  114. <el-table-column
  115. prop="car_number"
  116. label="车牌"
  117. align="center"
  118. width="117"
  119. show-overflow-tooltip
  120. >
  121. </el-table-column>
  122. </el-table>
  123. </div>
  124. </div>
  125. </div>
  126. <!-- 右侧区域 -->
  127. <div class="right">
  128. <!-- 折线图区域 -->
  129. <div class="right-line">
  130. <!-- 折线图标题 -->
  131. <div class="right-line-title">
  132. <div class="line-img">
  133. <img src="@/assets/jiantou.png" />
  134. </div>
  135. <div class="line-info">6小时车流量</div>
  136. </div>
  137. <!-- 折线图 -->
  138. <div class="right-line-body" id="line"></div>
  139. </div>
  140. <!-- 柱状图区域 -->
  141. <div class="right-column">
  142. <!-- 柱状图标题 -->
  143. <div class="right-column-title">
  144. <div class="column-img">
  145. <img src="@/assets/jiantou.png" />
  146. </div>
  147. <div class="column-info">24小时车辆来源地</div>
  148. </div>
  149. <!-- 柱状图 -->
  150. <div class="right-column-body" id="column"></div>
  151. </div>
  152. </div>
  153. </div>
  154. </template>
  155. <script>
  156. // 引入echarts
  157. import * as echarts from "echarts";
  158. export default {
  159. name: "CarRecord",
  160. data() {
  161. return {
  162. // 类型筛选框绑定值
  163. value_type: "驶入",
  164. // 时间筛选框绑定值
  165. value_time: "",
  166. // 来源地筛选框绑定值
  167. value_place: "",
  168. // 类型筛选框数组
  169. options_type: ["全部", "驶入", "驶出"],
  170. //来源地筛选框数组
  171. options_place: [],
  172. // 车辆记录列表数据
  173. tableData: [],
  174. // 车辆记录列表总条数
  175. total: "",
  176. // 车辆记录列表当前页
  177. page: 1,
  178. // 车辆记录表格加载中效果
  179. loading: false,
  180. // 折线图数据
  181. timeList: [], // 时间数组
  182. freeList: [], // 免费车数组
  183. monthlyList: [], // 月租车数组
  184. visitorList: [], // 访客车数组
  185. temporaryList: [], // 临时车数组
  186. // 柱状图数据
  187. topPlace: [], // 车辆来源地排行地点
  188. topValue: [], // 车辆来源地排行数值
  189. };
  190. },
  191. created() {
  192. this.getData();
  193. this.getCarFromData();
  194. this.getCarFromTopData();
  195. this.carMonitorData();
  196. },
  197. watch: {
  198. // 监听数据变化重新渲染图表
  199. topPlace() {
  200. this.getColumnChart();
  201. },
  202. timeList() {
  203. this.getLineChart();
  204. },
  205. },
  206. methods: {
  207. // 获取车辆记录表格数据
  208. async getData() {
  209. this.loading = true;
  210. let res = await this.$axios({
  211. url: "/carstop/carMonitor/ioqueryRecord.action",
  212. method: "post",
  213. params: {
  214. time: this.value_time,
  215. from: this.value_place,
  216. io: this.value_type,
  217. page: this.page,
  218. rows: 20,
  219. },
  220. });
  221. // console.log(res.data);
  222. if (res.data.code && res.data.code == 200) {
  223. this.tableData = [...this.tableData, ...res.data.rows];
  224. this.total = res.data.total;
  225. } else {
  226. this.$message.error(res.data.message || "暂无数据");
  227. }
  228. this.loading = false;
  229. },
  230. // 获取车辆来源地数据
  231. async getCarFromData() {
  232. let res = await this.$axios({
  233. url: "/carstop/carMonitor/iocar_from.action",
  234. method: "post",
  235. });
  236. // console.log(res.data);
  237. if (res.data.code == 200) {
  238. let temList = [];
  239. res.data.data.forEach((element) => {
  240. temList.push(element.car_no);
  241. });
  242. this.options_place = temList;
  243. } else {
  244. this.$message.error(res.data.message);
  245. }
  246. },
  247. // 获取车辆来源地排名数据
  248. async getCarFromTopData() {
  249. let res = await this.$axios({
  250. url: "/carstop/carMonitor/iocarTj.action",
  251. method: "post",
  252. });
  253. // console.log(res.data);
  254. if (res.data.code == 200) {
  255. let temList = res.data.data;
  256. // 将需要排序的 key, 按照 "从大到小" 进行排列
  257. let sortKeys = Object.keys(temList).sort((a, b) => {
  258. return temList[b] - temList[a];
  259. });
  260. // 循环排列好的 key, 重新组成一个新的数组
  261. let arr = [];
  262. for (let sortIndex in sortKeys) {
  263. arr.push(temList[sortKeys[sortIndex]]);
  264. }
  265. this.topPlace = sortKeys.splice(0, 5);
  266. this.topValue = arr.splice(0, 5);
  267. } else {
  268. this.$message.error(res.data.message);
  269. }
  270. },
  271. // 获取6小时车流量数据
  272. async carMonitorData() {
  273. let res = await this.$axios({
  274. url: "/carstop/carMonitor/ioioTj.action",
  275. method: "post",
  276. });
  277. // console.log(res.data);
  278. if (res.data.code == 200) {
  279. this.timeList = [];
  280. this.freeList = [];
  281. this.monthlyList = [];
  282. this.visitorList = [];
  283. this.temporaryList = [];
  284. res.data.data.forEach((element) => {
  285. this.timeList.push(element.duration);
  286. this.freeList.push(element.typeTj[0].num);
  287. this.monthlyList.push(element.typeTj[1].num);
  288. this.visitorList.push(element.typeTj[2].num);
  289. this.temporaryList.push(element.typeTj[3].num);
  290. });
  291. } else {
  292. this.$message.error(res.data.message);
  293. }
  294. },
  295. // 车辆记录表格滑动到底部加载更多回调
  296. moretable() {
  297. if (this.tableData.length < this.total) {
  298. this.page += 1;
  299. this.getData();
  300. }
  301. },
  302. // 筛选回调
  303. handleChange() {
  304. this.tableData = [];
  305. this.page = 1;
  306. this.getData();
  307. },
  308. // 创建折线图
  309. getLineChart() {
  310. let chartLineDom = document.getElementById("line");
  311. let myLineChart = echarts.init(chartLineDom);
  312. // 折线图表配置
  313. let lineOption = {
  314. tooltip: {
  315. trigger: "axis",
  316. },
  317. legend: {
  318. data: ["免费车", "月租车", "访客车", "临时车"],
  319. textStyle: {
  320. color: "#fff",
  321. },
  322. },
  323. grid: {
  324. left: "3%",
  325. right: "4%",
  326. bottom: "3%",
  327. containLabel: true,
  328. },
  329. xAxis: {
  330. type: "category",
  331. boundaryGap: false,
  332. data: this.timeList,
  333. axisLine: {
  334. lineStyle: {
  335. color: "#0febff",
  336. },
  337. },
  338. axisLabel: {
  339. color: "#fff",
  340. },
  341. splitLine: {
  342. show: true,
  343. lineStyle: {
  344. width: 1,
  345. color: "#0febff",
  346. },
  347. },
  348. },
  349. yAxis: {
  350. type: "value",
  351. axisLabel: {
  352. formatter: "{value}",
  353. color: "#fff",
  354. },
  355. splitLine: {
  356. show: true,
  357. lineStyle: {
  358. width: 1,
  359. color: "#0febff",
  360. },
  361. },
  362. },
  363. series: [
  364. {
  365. name: "免费车",
  366. type: "line",
  367. data: this.freeList,
  368. //设定为实心点
  369. symbol: "circle",
  370. //设定实心点的大小
  371. symbolSize: 10,
  372. //是否显示数值
  373. // label: { show: true },
  374. },
  375. {
  376. name: "月租车",
  377. type: "line",
  378. data: this.monthlyList,
  379. symbol: "circle",
  380. symbolSize: 10,
  381. },
  382. {
  383. name: "访客车",
  384. type: "line",
  385. data: this.visitorList,
  386. symbol: "circle",
  387. symbolSize: 10,
  388. },
  389. {
  390. name: "临时车",
  391. type: "line",
  392. data: this.temporaryList,
  393. symbol: "circle",
  394. symbolSize: 10,
  395. },
  396. ],
  397. };
  398. myLineChart.setOption(lineOption);
  399. },
  400. // 创建柱状图
  401. getColumnChart() {
  402. let chartColumnDom = document.getElementById("column");
  403. let myColumnChart = echarts.init(chartColumnDom);
  404. // 饼形图表配置
  405. let columnOption = {
  406. tooltip: {
  407. trigger: "axis",
  408. axisPointer: {
  409. type: "shadow",
  410. },
  411. },
  412. grid: {
  413. left: "3%",
  414. right: "4%",
  415. bottom: "3%",
  416. top: "13%",
  417. containLabel: true,
  418. },
  419. xAxis: [
  420. {
  421. type: "category",
  422. data: this.topPlace,
  423. axisTick: {
  424. alignWithLabel: true,
  425. },
  426. axisLine: {
  427. lineStyle: {
  428. color: "#0febff",
  429. },
  430. },
  431. axisLabel: {
  432. color: "#fff",
  433. },
  434. // splitLine: {
  435. // show: true,
  436. // lineStyle: {
  437. // width: 1,
  438. // color: "#0febff",
  439. // },
  440. // },
  441. },
  442. ],
  443. yAxis: {
  444. type: "value",
  445. axisLabel: {
  446. formatter: "{value}",
  447. color: "#fff",
  448. },
  449. splitLine: {
  450. show: true,
  451. lineStyle: {
  452. width: 1,
  453. color: "transparent",
  454. },
  455. },
  456. },
  457. series: [
  458. {
  459. name: "数量",
  460. type: "bar",
  461. barWidth: "60%",
  462. data: this.topValue,
  463. itemStyle: {
  464. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  465. {
  466. offset: 0,
  467. color: "#0FEBFE",
  468. },
  469. {
  470. offset: 1,
  471. color: "#276691",
  472. },
  473. ]),
  474. },
  475. label: {
  476. show: true, //开启显示
  477. position: "top", //在上方显示
  478. textStyle: {
  479. //数值样式
  480. color: "#fff",
  481. },
  482. },
  483. },
  484. ],
  485. };
  486. myColumnChart.setOption(columnOption);
  487. },
  488. },
  489. };
  490. </script>
  491. <style lang="scss" scoped>
  492. .peoplerecord {
  493. box-sizing: border-box;
  494. margin: auto;
  495. width: 1161px;
  496. height: 642px;
  497. background-image: url(../assets/backImg.png);
  498. background-size: 100% 100%;
  499. background-color: #24578c;
  500. .head {
  501. display: flex;
  502. width: 1161px;
  503. height: 60px;
  504. .head-msg {
  505. display: flex;
  506. justify-content: center;
  507. align-items: center;
  508. margin-top: 5px;
  509. width: 58px;
  510. height: 55px;
  511. img {
  512. height: 35px;
  513. }
  514. }
  515. .head-info {
  516. margin-top: 5px;
  517. line-height: 55px;
  518. font-size: 25px;
  519. font-weight: bold;
  520. color: #fff;
  521. }
  522. }
  523. .left {
  524. display: flex;
  525. flex-wrap: wrap;
  526. float: left;
  527. width: 800px;
  528. height: 586px;
  529. .left-watch {
  530. margin: 0 11px 0 17px;
  531. width: 756px;
  532. height: 571px;
  533. .watch-title {
  534. display: flex;
  535. align-items: center;
  536. width: 756px;
  537. height: 54px;
  538. .watch-img {
  539. width: 26px;
  540. height: 16px;
  541. img {
  542. width: 100%;
  543. }
  544. }
  545. .watch-info {
  546. margin-left: 10px;
  547. width: 79px;
  548. height: 25px;
  549. font-size: 19px;
  550. font-weight: bold;
  551. color: #0febff;
  552. }
  553. }
  554. .watch_search {
  555. display: flex;
  556. margin-top: -10px;
  557. width: 756px;
  558. height: 60px;
  559. color: #fff;
  560. .search_type {
  561. flex: 1;
  562. display: flex;
  563. align-items: center;
  564. }
  565. .search_time {
  566. flex: 1;
  567. display: flex;
  568. align-items: center;
  569. }
  570. .search_place {
  571. flex: 1;
  572. display: flex;
  573. align-items: center;
  574. }
  575. }
  576. .watch-form {
  577. width: 756px;
  578. height: 467px;
  579. }
  580. }
  581. }
  582. .right {
  583. float: left;
  584. width: 350px;
  585. height: 586px;
  586. .right-line {
  587. width: 350px;
  588. height: 50%;
  589. .right-line-title {
  590. display: flex;
  591. align-items: center;
  592. width: 350px;
  593. height: 56px;
  594. .line-img {
  595. width: 26px;
  596. height: 16px;
  597. img {
  598. width: 100%;
  599. }
  600. }
  601. .line-info {
  602. margin-left: 10px;
  603. width: 126px;
  604. height: 25px;
  605. font-size: 19px;
  606. font-weight: bold;
  607. color: #0febff;
  608. }
  609. }
  610. .right-line-body {
  611. width: 350px;
  612. height: 237px;
  613. }
  614. }
  615. .right-column {
  616. width: 350px;
  617. height: 50%;
  618. margin-top: -6px;
  619. .right-column-title {
  620. display: flex;
  621. align-items: center;
  622. width: 350px;
  623. height: 56px;
  624. .column-img {
  625. width: 26px;
  626. height: 16px;
  627. img {
  628. width: 100%;
  629. }
  630. }
  631. .column-info {
  632. margin-left: 10px;
  633. width: 180px;
  634. height: 25px;
  635. font-size: 19px;
  636. font-weight: bold;
  637. color: #0febff;
  638. }
  639. }
  640. .right-column-body {
  641. width: 350px;
  642. height: 237px;
  643. }
  644. }
  645. }
  646. ::v-deep .el-table,
  647. ::v-deep .el-table__expanded-cell {
  648. background-color: transparent;
  649. background-color: #0e3779;
  650. }
  651. ::v-deep .el-table th,
  652. ::v-deep .el-table tr,
  653. ::v-deep .el-table td {
  654. color: #fff;
  655. background-color: transparent;
  656. }
  657. // 鼠标悬停时背景颜色设置
  658. ::v-deep .el-table tbody tr:hover > td {
  659. background-color: #0e3779;
  660. }
  661. ::v-deep .el-table__header-wrapper {
  662. background-color: transparent;
  663. background-color: #25608f;
  664. }
  665. // 滚动条隐藏
  666. ::-webkit-scrollbar {
  667. height: 0;
  668. width: 0;
  669. color: transparent;
  670. }
  671. // 输入框 筛选框 圆角设置
  672. ::v-deep .el-input__inner {
  673. border-radius: 20px;
  674. color: #fff;
  675. background-color: rgba($color: #fff, $alpha: 0.3);
  676. }
  677. // 斑马线隔行换色设置颜色
  678. ::v-deep
  679. .el-table--striped
  680. .el-table__body
  681. tr.el-table__row--striped.el-table__row--striped.el-table__row--striped
  682. td {
  683. background-color: rgba($color: #58beff, $alpha: 0.3);
  684. }
  685. // 清除表格默认下边框
  686. ::v-deep .el-table__cell,
  687. ::v-deep .el-table th.el-table__cell.is-leaf {
  688. border-bottom: none;
  689. }
  690. ::v-deep .el-table::before {
  691. width: 0;
  692. }
  693. }
  694. </style>