panel.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. <template>
  2. <view>
  3. <view class="arrow-up">
  4. <u-icon class="icon" name="arrow-up" @click="isShow=true" color="#2979ff" size="26"></u-icon>
  5. </view>
  6. <u-popup :show="isShow" @close="close" :closeOnClickOverlay="true">
  7. <!-- <view class="popup-icon">
  8. <u-icon class="icon" name="arrow-up" @click="isShow=false" color="#2979ff" size="26"></u-icon>
  9. </view> -->
  10. <view class="munes">
  11. <view v-for="(item,index) in typeList" :key="index"
  12. class="munes-item"
  13. :class="{
  14. 'munes-item-active': item.value == tabStyle
  15. }"
  16. @click="handleActive(item)"
  17. >
  18. <text>{{item.label}}</text>
  19. </view>
  20. </view>
  21. <view class="container">
  22. <u--form label-width="auto" labelAlign="right"
  23. ref="uForm"
  24. :model="model"
  25. :rules="rules"
  26. :labelStyle="{
  27. fontSize: '28rpx',
  28. fontWeight: '500',
  29. }"
  30. >
  31. <u-cell-group :border="false">
  32. <view v-if="tabStyle == 'vehicle'" key="vehicle">
  33. <u-cell title="车辆" :border="true" :isLink="true"
  34. @click="$refs.carChooseRef.show()"
  35. >
  36. <view slot="value">
  37. <u-form-item label="" prop="form.vehicleId">
  38. {{renderItem(model.form,'plate','')}}
  39. </u-form-item>
  40. </view>
  41. </u-cell>
  42. <tq-car-user ref="carChooseRef"
  43. :isGetIcon="true"
  44. @confirm="(data) => {
  45. $store.dispatch('setMapImg',data.img)
  46. model.form.vehicleId = data.id
  47. model.form.plate = data.label
  48. $refs.uForm.validateField('form.vehicleId')
  49. }"
  50. @onDataLoad="handleDataLoad"
  51. >
  52. </tq-car-user>
  53. </view>
  54. <view v-else-if="tabStyle == 'personnel'" key="personnel">
  55. <u-cell title="人员" :border="true" :isLink="true"
  56. @click="$refs.userChooseRef.show()"
  57. >
  58. <view slot="value">
  59. <u-form-item label="" prop="form.userId">
  60. {{renderItem(model.form,'userName','')}}
  61. </u-form-item>
  62. </view>
  63. </u-cell>
  64. <tq-car-user ref="userChooseRef"
  65. :isGetIcon="true"
  66. :queryType="1"
  67. @confirm="(data) => {
  68. $store.dispatch('setMapImg',data.img)
  69. model.form.userId = data.id
  70. model.form.userName = data.label
  71. $refs.uForm.validateField('form.userId')
  72. }"
  73. @onDataLoad="handleDataLoad"
  74. >
  75. </tq-car-user>
  76. </view>
  77. <template>
  78. <u-cell title="开始时间" :border="true" :isLink="true"
  79. @click="$refs.startTimeRef.show()"
  80. >
  81. <view slot="value">
  82. <u-form-item label="" prop="form.startTime">
  83. {{renderItem(model.form,'startTime','')}}
  84. </u-form-item>
  85. </view>
  86. </u-cell>
  87. <tq-date-time ref="startTimeRef"
  88. :disEndDate="renderItem(model.form,'endTime','')"
  89. @confirm="(data) => {
  90. model.form.startTime = data
  91. $refs.uForm.validateField('form.startTime')
  92. computetimeArr()
  93. }"
  94. >
  95. </tq-date-time>
  96. </template>
  97. <template>
  98. <u-cell title="结束时间" :border="true" :isLink="true"
  99. @click="$refs.endTimeRef.show()"
  100. >
  101. <view slot="value">
  102. <u-form-item label="" prop="form.endTime">
  103. {{renderItem(model.form,'endTime','')}}
  104. </u-form-item>
  105. </view>
  106. </u-cell>
  107. <tq-date-time ref="endTimeRef"
  108. :disStartDate="renderItem(model.form,'startTime','')"
  109. @confirm="(data) => {
  110. model.form.endTime = data
  111. $refs.uForm.validateField('form.endTime')
  112. computetimeArr()
  113. }"
  114. >
  115. </tq-date-time>
  116. </template>
  117. <template>
  118. <u-cell title="播放速度" :border="true" :isLink="true"
  119. @click="$refs.selectRef.show()"
  120. >
  121. <view slot="value">
  122. <u-form-item prop="form.playSpeed">
  123. {{renderItem(model.form,'playSpeedName','')}}
  124. </u-form-item>
  125. </view>
  126. </u-cell>
  127. <tq-select ref="selectRef"
  128. :columns = "speedList"
  129. @confirm="(data) => {
  130. model.form.playSpeed = data.value
  131. model.form.playSpeedName = data.label
  132. $refs.uForm.validateField('form.playSpeed')
  133. }"
  134. >
  135. </tq-select>
  136. </template>
  137. </u-cell-group>
  138. <u-row style="margin-top: 20rpx;">
  139. <u-col :span="12" style="padding: 20rpx 30rpx;">
  140. <u-checkbox-group v-model="filterList" placement="column">
  141. <u-checkbox name="position" label="过滤未定位"></u-checkbox>
  142. <u-checkbox name="speed" label="过滤速度为0" v-if="tabStyle == 'vehicle'"></u-checkbox>
  143. <u-checkbox name="parkRecord" label="停车记录" v-if="tabStyle == 'vehicle'"></u-checkbox>
  144. <u-checkbox name="warning" label="车辆报警" v-if="tabStyle == 'vehicle'"></u-checkbox>
  145. </u-checkbox-group>
  146. </u-col>
  147. </u-row>
  148. <u-row style="margin-top: 20rpx;">
  149. <u-col :span="12" style="padding: 0 30rpx;">
  150. <u-button type="primary" shape="" v-if="timeArr.length" :custom-style="{
  151. width: '100%',
  152. }" @click="handleSubmit" :disabled="getMoreDataText==='全部加载完成'">{{getMoreDataText}}
  153. </u-button>
  154. <u-button type="primary" v-else shape="" :custom-style="{
  155. width: '100%',
  156. }" @click="handleSubmit">查询
  157. </u-button>
  158. </u-col>
  159. </u-row>
  160. <u-row style="margin-top: 20rpx;">
  161. <u-col :span="12" style="padding: 0 30rpx;">
  162. <u-button shape="" :custom-style="{
  163. width: '100%',
  164. }" @click="handleReset">重置
  165. </u-button>
  166. </u-col>
  167. </u-row>
  168. </u--form>
  169. </view>
  170. </u-popup>
  171. </view>
  172. </template>
  173. <script>
  174. import {isArray,clone,isObject } from 'lodash'
  175. import {getImages} from '@/plugins/images'
  176. import { trackRecord, monthHistory,userTrackRecord,userMonthHistory,getAlarmVehicleHisList,vehStopQueryList } from "@/api/pastRoute";
  177. import {copyProps,clearProps} from '@/utils/gdtq.js'
  178. export default {
  179. data() {
  180. return {
  181. isShow: false,
  182. model: {
  183. form: {
  184. vehicleId: "",
  185. plate: "",
  186. userId: "",
  187. userName: "",
  188. startTime: "",
  189. endTime: "",
  190. playSpeed: 500,
  191. playSpeedName: '正常',
  192. }
  193. },
  194. filterList: ['position','speed'],
  195. rules: {
  196. 'form.vehicleId': {
  197. type: 'string',
  198. required: true,
  199. message: '请选择车辆',
  200. trigger: ['blur', 'change']
  201. },
  202. 'form.userId': {
  203. type: 'string',
  204. required: true,
  205. message: '请选择人员',
  206. trigger: ['blur', 'change']
  207. },
  208. 'form.startTime': {
  209. type: 'string',
  210. required: true,
  211. message: '请选择开始时间',
  212. trigger: ['blur', 'change']
  213. },
  214. 'form.endTime': {
  215. type: 'string',
  216. required: true,
  217. message: '请选择结束时间',
  218. trigger: ['blur', 'change']
  219. },
  220. 'form.playSpeed': {
  221. type: 'number',
  222. required: true,
  223. message: '请选择播放速度',
  224. trigger: ['blur', 'change']
  225. },
  226. },
  227. speedList: [
  228. {label: '极速',value: 100},
  229. {label: '较快',value: 300},
  230. {label: '正常',value: 500},
  231. {label: '较慢',value: 700},
  232. ],
  233. trackRecordList: [], //
  234. playState: 0, //0未开始 1开始播放中 2暂停播放中 3继续播放中
  235. tabStyle: 'vehicle',
  236. typeList: [
  237. {label: '车辆',value: 'vehicle'},
  238. {label: '人员',value: 'personnel'},
  239. ],
  240. pageIdx:0,
  241. timeArr:[],
  242. trackRecordListMoreData:[]
  243. }
  244. },
  245. computed:{
  246. getMoreDataText(){
  247. if(this.pageIdx===0){
  248. return '查询前7天数据'
  249. }else if(this.pageIdx===this.timeArr.length) {
  250. return '全部加载完成'
  251. }else{
  252. return '加载更多'
  253. }
  254. }
  255. },
  256. mounted() {
  257. let { tabStyleType } = this.$store.state.pastRoute.params
  258. if(tabStyleType) {
  259. this.tabStyle = tabStyleType
  260. this.$store.dispatch('setTabStyle',tabStyleType)
  261. this.show()
  262. uni.showLoading({
  263. title: '加载中...',
  264. mask: true, // 使用 mask 参数来禁用用户交互
  265. });
  266. }
  267. },
  268. onReady() {
  269. this.$refs.uForm.setRules(this.rules)
  270. },
  271. methods: {
  272. computetimeArr(){
  273. this.timeArr = []
  274. this.pageIdx = 0
  275. this.trackRecordListMoreData = []
  276. //超过7天后按七天分段
  277. // 解析日期字符串
  278. const startDate = this.dayjs(this.model.form.startTime + ':00');
  279. const endDate = this.dayjs(this.model.form.endTime + ':59');
  280. // 计算天数差
  281. const daysDiff = endDate.diff(startDate, 'day');
  282. // 超过7天后按七天分段
  283. if (daysDiff > 7) {
  284. const numSegments = Math.ceil(daysDiff / 7);
  285. for (let i = 0; i < numSegments; i++) {
  286. const start = startDate.add(i * 7, 'day');
  287. const end = i === numSegments - 1 ? endDate : start.add(6, 'day').endOf('day');
  288. this.timeArr.push([start.format('YYYY-MM-DD HH:mm:ss'), end.format('YYYY-MM-DD HH:mm:ss')]);
  289. }
  290. }
  291. console.log('分段是', this.timeArr)
  292. },
  293. handleActive(item) {
  294. if(this.tabStyle == item.value) return
  295. this.$store.dispatch('setTabStyle',item.value)
  296. this.handleReset()
  297. this.tabStyle = item.value
  298. },
  299. show() {
  300. this.isShow= true;
  301. },
  302. close() {
  303. this.isShow = false
  304. },
  305. getParams(allTreeList) {
  306. let { tabStyleType, vehicleId, userId, time } = this.$store.state.pastRoute.params
  307. // console.log( this.$store.state.pastRoute.params,' this.$store.state.pastRoute.params')
  308. if (!tabStyleType) return
  309. this.$nextTick(e => {
  310. if (tabStyleType == 'vehicle') {
  311. this.model.form.vehicleId = vehicleId
  312. if(allTreeList.length>0) {
  313. let res = allTreeList.filter((e) => vehicleId == e.id)
  314. if(res.length>0) {
  315. this.model.form.plate = res[0].label
  316. this.$store.dispatch('setMapImg',res[0].img)
  317. }
  318. }
  319. } else if (tabStyleType == 'personnel') {
  320. this.model.form.userId = userId
  321. if(allTreeList.length>0) {
  322. let res = allTreeList.filter((e) => userId == e.id)
  323. if(res.length>0) {
  324. this.model.form.userName = res[0].label
  325. this.$store.dispatch('setMapImg',res[0].img)
  326. }
  327. }
  328. }
  329. this.model.form.startTime = time[0]
  330. this.model.form.endTime = time[1]
  331. this.$store.dispatch('setParams',{})
  332. uni.hideLoading();
  333. })
  334. },
  335. handleDataLoad(allTreeList) {
  336. this.getParams(allTreeList)
  337. },
  338. resetAll() {
  339. this.playState = 0;
  340. this.trackRecordList = []
  341. this.$store.dispatch('setTrackRecordArr',[])
  342. },
  343. // 提交
  344. async handleSubmit() {
  345. this.$refs.uForm.validate().then(async res => {
  346. if (this.tabStyle === 'vehicle') {
  347. let ajaxData = {
  348. ...this.model.form,
  349. position: this.filterList.includes('position')?1:0,
  350. speed: this.filterList.includes('speed')?1:0,
  351. startTime:this.timeArr.length ? this.timeArr[this.pageIdx][0] : this.model.form.startTime + ':00',
  352. endTime:this.timeArr.length ? this.timeArr[this.pageIdx][1] : this.model.form.endTime + ':59',
  353. }
  354. let { data, code } = await trackRecord(ajaxData)
  355. if (code == 0) {
  356. this.resetAll()
  357. let list = data.map(e => {
  358. return {
  359. ...e,
  360. engineStatusName: e.engineStatus === '1' ? '开' : '关',
  361. positionName: Number(e.position) === 1 ? '已定位' : '未定位'
  362. }
  363. })
  364. if (this.timeArr.length) { // 分段
  365. this.pageIdx++
  366. this.trackRecordListMoreData = this.trackRecordListMoreData.concat(list)
  367. this.trackRecordList = this.trackRecordListMoreData
  368. } else {
  369. if (list.length > 0) { //有数据
  370. this.trackRecordList = list
  371. } else {
  372. this.$modal.msg("没有轨迹信息!")
  373. }
  374. }
  375. //赋值轨迹数据
  376. if (this.trackRecordList.length) {
  377. this.trackRecordList[0].duration = this.model.form.playSpeed
  378. this.trackRecordList[0].tabStyle = this.tabStyle
  379. this.$store.dispatch('setTrackRecordArr', this.trackRecordList)
  380. this.close()
  381. }
  382. console.log('轨迹数据',this.trackRecordList)
  383. } else {
  384. this.$modal.msg("获取失败!")
  385. }
  386. //查询停车记录
  387. if(this.filterList.includes('parkRecord')){
  388. let ajaxData = {
  389. ...this.model.form,
  390. startTime: this.model.form.startTime + ':00',
  391. endTime: this.model.form.endTime + ':59',
  392. }
  393. delete ajaxData.time
  394. let { data: vedata, code: vecode } = await vehStopQueryList(ajaxData)
  395. if (vecode === 0) {
  396. // pastRoute.setVehStopArr(vedata)
  397. this.$store.dispatch('setVehStopArr',vedata)
  398. }
  399. }
  400. //查询车辆报警明细
  401. if(this.filterList.includes('warning')){
  402. let { data: avData, code: avCode } = await getAlarmVehicleHisList({
  403. startTime: this.model.form.startTime + ':00',
  404. endTime: this.model.form.endTime + ':59',
  405. objId: this.model.form.vehicleId
  406. })
  407. if (avCode === 0) {
  408. // pastRoute.setVeAlarm(avData)
  409. this.$store.dispatch('setVeAlarm',avData)
  410. }
  411. }
  412. //人员轨迹
  413. } else if (this.tabStyle === 'personnel') {
  414. let ajaxData = {
  415. ...this.model.form,
  416. position: this.filterList.includes('position')?1:0,
  417. startTime:this.timeArr.length ? this.timeArr[this.pageIdx][0] : this.model.form.startTime + ':00',
  418. endTime:this.timeArr.length ? this.timeArr[this.pageIdx][1] : this.model.form.endTime + ':59',
  419. }
  420. let { data, code } = await userTrackRecord(ajaxData)
  421. if (code == 0) {
  422. this.resetAll()
  423. let list = data.map(e => {
  424. return {
  425. ...e,
  426. engineStatusName: e.engineStatus === '1' ? '开' : '关',
  427. positionName: Number(e.position) === 1 ? '已定位' : '未定位'
  428. }
  429. })
  430. if (this.timeArr.length) { // 分段
  431. this.pageIdx++
  432. this.trackRecordListMoreData = this.trackRecordListMoreData.concat(list)
  433. this.trackRecordList = this.trackRecordListMoreData
  434. } else {
  435. if (data.length > 0) { //有数据
  436. this.trackRecordList = list
  437. } else {
  438. this.$modal.msg("没有轨迹信息!")
  439. }
  440. }
  441. //赋值轨迹数据
  442. if (this.trackRecordList.length) {
  443. this.trackRecordList[0].duration = this.model.form.playSpeed
  444. this.trackRecordList[0].tabStyle = this.tabStyle
  445. this.$store.dispatch('setTrackRecordArr', this.trackRecordList)
  446. this.close()
  447. }
  448. console.log('轨迹数据',this.trackRecordList)
  449. } else {
  450. this.$modal.msg("获取失败!")
  451. }
  452. }
  453. //同步更新查询信息
  454. this.$store.dispatch('setPastRouteParams', {
  455. ...this.model.form,
  456. startTime: this.model.form.startTime + ':00',
  457. endTime: this.model.form.endTime + ':59',
  458. })
  459. }).catch(errors => {
  460. console.log('校验失败',errors)
  461. })
  462. },
  463. // 播放
  464. play() {
  465. switch (this.playState) {
  466. case 0:
  467. this.$emit('startAnimation') //开始播放
  468. this.playState = 1
  469. break;
  470. case 1:
  471. this.$emit('pauseAnimation') //暂停
  472. this.playState = 2
  473. break;
  474. case 2:
  475. this.$emit('resumeAnimation') //继续
  476. this.playState = 3
  477. break;
  478. case 3:
  479. this.$emit('pauseAnimation') //暂停
  480. this.playState = 2
  481. break;
  482. }
  483. },
  484. handleReset () {
  485. clearProps(this.model.form)
  486. this.model.form.playSpeed = 500
  487. this.model.form.playSpeedName = '正常'
  488. this.filterList = ['position','speed']
  489. this.resetAll()
  490. this.computetimeArr()
  491. }
  492. }
  493. }
  494. </script>
  495. <style lang="scss" scoped>
  496. .arrow-up{
  497. // height: 40px;
  498. // line-height: 40px;
  499. width: 100%;
  500. display: flex;
  501. justify-content: center;
  502. // background: rgba($color: #fff, $alpha: 0.6);
  503. // padding:0 20px;
  504. position: absolute;
  505. bottom:0;
  506. .icon{
  507. background: rgba($color: #fff, $alpha: 0.68);
  508. padding:0 14px;
  509. }
  510. }
  511. .popup-icon{
  512. width: 100%;
  513. display: flex;
  514. justify-content: center;
  515. position: absolute;
  516. // background: rgba($color: #fff, $alpha: 1);
  517. top:-25px;
  518. height: 26px;
  519. .icon{
  520. background: rgba($color: #fff, $alpha: 0.68);
  521. padding:0 6px;
  522. //旋转180度
  523. transform: rotate(180deg);
  524. }
  525. }
  526. .munes {
  527. height: 80rpx;
  528. display: flex;
  529. justify-content: center;
  530. align-items: center;
  531. .munes-item {
  532. flex: 1;
  533. height: 100%;
  534. background: #F2f2f2;
  535. display: flex;
  536. justify-content: center;
  537. align-items: center;
  538. font-size: 30rpx;
  539. font-weight: bold;
  540. }
  541. .munes-item-active {
  542. background: #fff;
  543. color: #3c9cff;
  544. }
  545. }
  546. .container {
  547. background: #fff;
  548. padding: 0rpx 0 20rpx 0;
  549. font-size: 28rpx;
  550. min-height: 700rpx;
  551. }
  552. ::v-deep {
  553. .container {
  554. .u-form-item__body {
  555. padding: 0;
  556. }
  557. .u-checkbox-group--column {
  558. .u-checkbox {
  559. &+.u-checkbox {
  560. margin-top: 20rpx;
  561. }
  562. }
  563. }
  564. }
  565. }
  566. </style>