Newer
Older
KaiFengH5 / src / views / xuncha / components / inspection.vue
@jimengfei jimengfei on 23 Jul 14 KB updata
  1. <template>
  2. <div class="inspectionRiver">
  3. <!-- 地图组件 -->
  4. <div style="width: 100%; height: 100%; position: absolute; top: 0; left: 0">
  5. <newFiberMapBox :PostionValue="AllData.PostionValue"></newFiberMapBox>
  6. </div>
  7. <!-- 底部按钮 -->
  8. <div class="BottomBtn">
  9. <div class="Btn Btn1" @click="patrolFilling(false)">问题填报</div>
  10. <div class="Btn Btn3" @click="EndPatrolClick">结束巡查</div>
  11. </div>
  12.  
  13. <!-- 巡查填报表单弹窗 -->
  14. <van-popup v-model:show="AllData.showForm" position="bottom" closeable :style="{ width: '100%', height: '90%' }">
  15. <div class="TaskTItle" v-if="AllData.showForm">问题填报</div>
  16. <TaskForm
  17. class="DakaPropID"
  18. v-if="AllData.showForm"
  19. @closeFormTransition="closeFormTransition"
  20. :numberNum="AllData.numberNum"
  21. :projectName="AllData.projectName"
  22. :projectCode="AllData.projectCode"
  23. :isDisable="AllData.isDisable"
  24. />
  25. </van-popup>
  26. <!-- 结束巡查 -->
  27. <van-popup v-model:show="AllData.showCancel" position="bottom" closeable :style="{ width: '100%', height: '30%' }">
  28. <div class="QxBox">
  29. <div class="Titlediv">确认结束巡查吗?</div>
  30. <!-- <div class="Contentdiv"></div> -->
  31. <div class="QxBoxBtn">
  32. <van-button round @click="TaskCancelPatrol"> 结束巡查 </van-button>
  33. </div>
  34. </div>
  35. </van-popup>
  36. </div>
  37. </template>
  38.  
  39. <script setup>
  40. import { reactive, ref, getCurrentInstance, watch, onMounted, onBeforeUnmount } from 'vue';
  41. import { timestampToTime, checkUserSystem, getCurrentPositon } from '@/utils/common.js';
  42. import { patrolTaskFinishPatrol, PatrolTaskID } from '@/api/xuncha';
  43. import CoordTransform from '@/utils/gis/CoorTransform.js';
  44. import WKT from 'terraformer-wkt-parser';
  45. import * as turf from '@turf/turf';
  46. import { useRouter, useRoute } from 'vue-router';
  47. import { useStore } from '@/pinia/store.js';
  48. import TaskForm from './TaskForm'; // 表单组件
  49. import newFiberMapBox from '@/views/xuncha/gisCommonPage/newFiberMapBox.vue';
  50. import user from '@/assets/images/patroLog/user.png';
  51. const router = useRouter();
  52. const route = useRoute();
  53. const pinias = useStore();
  54.  
  55. const props = defineProps({
  56. patrolLogId: String,
  57. MarkForData: Object,
  58. });
  59. const { proxy } = getCurrentInstance();
  60. const AllData = reactive({
  61. taskID: '', //当前巡检任务ID
  62. longitudeNow: '',
  63. latitudeNow: '',
  64. numberNum: '',
  65. projectName: '',
  66. projectCode: '',
  67. IntervalKry: '', //定时器ID--获取经纬度信息
  68. TimerArray: [], //记录定时器数据
  69. num: 0,
  70. videoSrc: '',
  71. status: false,
  72. showForm: false, //表单弹窗显隐状态
  73. modeClass: ['slide-bottom'],
  74. countDown: 3, //倒计时时间长度
  75. timeOutID: null,
  76. NoticeFont: null, //顶部标题内容
  77. ScopeValue: false, //当前是否在可以打卡范围内
  78. patrolSectionId: null, //当前的巡查段编号
  79. patrolLogId: null, //当前的日志编号
  80. DaKaPopupShow: false, //打卡弹窗组件的加载状态
  81. EndPatrolShow: false, //结束巡查组件的加载状态
  82. socketOpen: false, //判断socket 的在线情况
  83. socketMsgQueue: [],
  84. PostionValue: {
  85. userName: null,
  86. lonLat: null,
  87. refType: null,
  88. refid: null,
  89. patrolDatetime: null,
  90. },
  91. option: {
  92. type: null,
  93. num: null,
  94. id: null,
  95. sectionType: null,
  96. }, //父页面传过来的按钮信息
  97. patrolPathLngLat: [], //当前巡检详情中已经巡检的路径
  98. MarkForData: {}, //点击图标获取到的数据
  99. isDisable: false, //弹窗内容是否为只读
  100. isOne: true, //第一次进入页面
  101. websock: null,
  102. showCancel: false, //取消的弹窗组件
  103. DaKaPopup: false, // 打卡的弹窗组件
  104. oldLonLat: {
  105. lon: null,
  106. lat: null,
  107. }, //储存的旧数据
  108. currentPath: [],
  109. });
  110.  
  111. /**
  112. * 问题填报
  113. */
  114. const patrolFilling = (val) => {
  115. // console.log(val, 'valvalval');
  116. AllData.isDisable = val;
  117. AllData.showForm = !AllData.showForm;
  118. };
  119.  
  120. // 结束巡查点击弹框
  121. const EndPatrolClick = () => {
  122. AllData.showCancel = true;
  123. };
  124.  
  125. // 关闭
  126. const closeFormTransition = (msg) => {
  127. AllData.showForm = false;
  128. // console.log(`案件弹窗关闭事件`, msg);
  129. if (msg == 'AnJianUpdatas') {
  130. // 通知地图刷新
  131. // TaskMapRef.value.MaskUpdata(2);
  132. }
  133. };
  134.  
  135. // 结束巡查关闭
  136. const TaskCancelPatrol = () => {
  137. getCurrentPositon((lng, lat, address) => {
  138. // console.log('获取安卓定位参数--', address);
  139. // 获取当前巡检任务的所有轨迹信息
  140. // patrolTaskId(route.query.id).then((res) => {
  141. // if (res && res.code == 200) {
  142. // let lengthKm = 0;
  143. // if (!!res.data.patrolPath) {
  144. // lengthKm = turf.length(WKT.parse(res.data.patrolPath));
  145. // } else {
  146. // lengthKm = 0;
  147. // }
  148. let param = {
  149. endPlace: address,
  150. // patrolTaskId: props.taskID,
  151. patrolLogId: route.query.id,
  152. patrolTaskId: route.query.id,
  153. // patrolName: AllData.formData.NoticeFont,
  154. // fileSaveRequestList: AllData.PicListData.concat(AllData.PicListData2),
  155. // logContent: AllData.formData.caseContent,
  156. // patrolLength: Number(lengthKm).toFixed(1),
  157. };
  158. patrolTaskFinishPatrol(param).then((res) => {
  159. if (res?.code == 200) {
  160. proxy.showSuccessToast('结束成功');
  161. router.go(-1);
  162. stopAndIosLocation(); // 原生安卓、ios结束websocket推送
  163. clearInterval(AllData.IntervalKry);
  164. }
  165. });
  166. // }
  167. // });
  168. });
  169. };
  170.  
  171. // 原生安卓、ios结束websocket推送
  172. function stopAndIosLocation() {
  173. console.log('结束websocket---');
  174. let systems = checkUserSystem();
  175. if (systems == 'Android') {
  176. console.log('安卓结束websocket---');
  177. window.android.disconnect(String(route.query.id));
  178. } else if (systems == 'IOS') {
  179. console.log('ios结束websocket---');
  180. window.webkit.messageHandlers.stopLocation.postMessage({ data: { refid: route.query.id } });
  181. }
  182. }
  183. // 开始巡检--阶段性获取经纬度变化信息
  184. const startGetPosition = () => {
  185. getPostionNow();
  186. newfiberMap.map.setCenter(AllData.PostionValue.lonLat.split(',').map(Number));
  187. AllData.IntervalKry = setInterval(() => {
  188. getPostionNow();
  189. console.log('AllData.PostionValue.lonLat--', AllData.PostionValue.lonLat);
  190. AllData.currentPath.push(AllData.PostionValue.lonLat.split(',').map(Number));
  191. // console.log('AllData.currentPath--', AllData.currentPath);
  192. if (!newfiberMap || !newfiberMap.map) return;
  193. //渲染当前位置
  194. let currentPositionGeojson = {
  195. type: 'FeatureCollection',
  196. features: [turf.point(AllData.PostionValue.lonLat.split(',').map(Number))],
  197. };
  198. if (!newfiberMap.map.getLayer('currentPosition')) {
  199. addCurrentPoint(currentPositionGeojson, 'currentPosition', user);
  200. } else {
  201. newfiberMap.map.getSource('currentPosition').setData(currentPositionGeojson);
  202. }
  203. if (AllData.currentPath.length > 1) {
  204. let currentPathGeojson = {
  205. type: 'FeatureCollection',
  206. features: [turf.lineString(AllData.currentPath)],
  207. };
  208. if (!newfiberMap.map.getLayer('currentLine')) {
  209. addCurrentLine(currentPathGeojson, 'currentLine');
  210. } else {
  211. newfiberMap.map.getSource('currentLine').setData(currentPathGeojson);
  212. }
  213. }
  214. }, 1000);
  215. };
  216. //添加轨迹线
  217. const addCurrentLine = (geojson, layerId) => {
  218. newfiberMap.map.addSource(layerId, {
  219. type: 'geojson',
  220. data: geojson,
  221. });
  222. newfiberMap.map.addLayer({
  223. id: layerId,
  224. type: 'line',
  225. source: layerId,
  226. paint: {
  227. 'line-color': 'rgba(35, 217, 110,1)',
  228. 'line-width': 3,
  229. },
  230. });
  231. };
  232. //绘制当前坐标点
  233. const addCurrentPoint = (geojson, layerId, Icon) => {
  234. newfiberMap.map.loadImage(Icon, (error, image) => {
  235. if (error) throw error;
  236. newfiberMap.map.addImage(layerId + 'icon', image);
  237. });
  238. newfiberMap.map.addSource(layerId, {
  239. type: 'geojson',
  240. data: geojson,
  241. });
  242. newfiberMap.map.addLayer({
  243. id: layerId,
  244. type: 'symbol',
  245. source: layerId,
  246. layout: {
  247. 'icon-image': layerId + 'icon',
  248. 'icon-size': 0.2,
  249. 'icon-offset': [0, 0],
  250. 'icon-allow-overlap': true,
  251. },
  252. });
  253. };
  254. /**
  255. * 获取当前定位
  256. */
  257. const getPostionNow = () => {
  258. AllData.PostionValue = {
  259. patrolDatetime: null,
  260. lonLat: null,
  261. refType: null,
  262. refid: null,
  263. userName: null,
  264. };
  265. getCurrentPositon((lng, lat, address) => {
  266. // console.log('获取安卓定位参数--', address);
  267. let timer = timestampToTime(Date.now());
  268. let NewLonLat = CoordTransform.gcj02towgs84(Number(lng), Number(lat));
  269. AllData.PostionValue = {
  270. patrolDatetime: timer,
  271. lonLat: NewLonLat[0] + ',' + NewLonLat[1],
  272. refType: 'patrolLog',
  273. refid: AllData.patrolLogId,
  274. userName: pinias.userName,
  275. };
  276. // console.log(AllData.PostionValue, 'AllData.PostionValue');
  277. });
  278. };
  279. /**
  280. * 获取当前巡检任务详情
  281. */
  282. const getInspectionInfo = (id) => {
  283. PatrolTaskID(id).then((res) => {
  284. if (res && res.code == 200) {
  285. AllData.numberNum = res.data.number;
  286. AllData.projectName = res.data.projectName;
  287. AllData.projectCode = res.data.projectCodes;
  288. AllData.gujiData = res.data.patrolPathLngLat;
  289. console.log(AllData.gujiData, 'AllData.gujiData');
  290. // 保存当前巡检ID
  291. AllData.taskID = res.data.id;
  292. // 保存当前巡查段编号
  293. // AllData.patrolSectionId = res.data.patrolSectionId;
  294. // console.log(AllData.patrolSectionId, '2 ');
  295. // 保存日志编号
  296. AllData.patrolLogId = res.data.patrolLogId;
  297. // 保存巡检记录
  298. AllData.patrolPathLngLat = res.data.patrolPathLngLat;
  299. // AllData.patrolLogId = '1630380590036803588'
  300. startGetPosition(); //开始获取原生定位
  301. sendSocketMessage(); //安卓、ios原生发送websocket
  302. //clearInterval(AllData.IntervalKry);
  303. }
  304. });
  305. };
  306.  
  307. // 通过socket 发送数据
  308. const sendSocketMessage = (msg) => {
  309. let systems = checkUserSystem();
  310. if (systems == 'Android') {
  311. console.log('安卓发送websocket---');
  312. let timer = timestampToTime(Date.now());
  313. let initObj = {
  314. patrolDatetime: timer,
  315. lonLat: '',
  316. refType: 'patrolLog',
  317. refid: AllData.patrolLogId,
  318. userName: pinias.userName,
  319. };
  320. console.log('安卓发送websocket111---', initObj);
  321. //给Android发送参数,通知给后端发送websocket
  322. window.android.initwebSocket(JSON.stringify(initObj));
  323. } else if (systems == 'IOS') {
  324. console.log('IOS开始发送websocket---');
  325. let timer = timestampToTime(Date.now());
  326. let initObj = {
  327. callId: 'sendCurrentLocationIOS',
  328. data: {
  329. patrolDatetime: timer,
  330. lonLat: '',
  331. refType: 'patrolLog',
  332. refid: AllData.patrolLogId,
  333. userName: pinias.userName,
  334. },
  335. };
  336. //给ios发送参数,通知给后端发送websocket
  337. window.webkit.messageHandlers.sendLocation.postMessage(initObj);
  338. }
  339. };
  340.  
  341. watch(
  342. route,
  343. (val) => {
  344. console.log(route.query.id, 'route.query.id');
  345. if (!!!route.query.id) return;
  346. setTimeout(() => {
  347. //option为object类型,会序列化上个页面传递的参数
  348. console.log('传递的参数222--', route.query.id); //打印出上个页面传递的参数。
  349. //获取当前巡检任务详情
  350. getInspectionInfo(route.query.id);
  351. });
  352. },
  353. { immediate: true }
  354. );
  355. onMounted(() => {
  356. setTimeout(() => {
  357. if (newfiberMap.map.getLayer('point_start')) {
  358. newfiberMap.map.removeLayer('point_start');
  359. newfiberMap.map.removeLayer('point_end');
  360. newfiberMap.map.removeLayer('recordLineGeojson');
  361. newfiberMap.map.removeSource('point_start');
  362. newfiberMap.map.removeSource('point_end');
  363. newfiberMap.map.removeSource('recordLineGeojson');
  364. }
  365. if (newfiberMap.map.getLayer('dynamicPepoleGeojson')) {
  366. newfiberMap.map.removeLayer('dynamicPepoleGeojson');
  367. newfiberMap.map.removeSource('dynamicPepoleGeojson');
  368. }
  369. }, 1000);
  370. });
  371. </script>
  372.  
  373. <style lang="less">
  374. .inspectionRiver {
  375. width: 100%;
  376. height: calc(100vh - var(--van-nav-bar-height));
  377. position: relative;
  378. // background: red;
  379.  
  380. // 底部三个按钮
  381. .BottomBtn {
  382. width: calc(100% - 52px);
  383. height: 140px;
  384. background: rgba(255, 255, 255, 0.7);
  385. box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.1);
  386. border-radius: 10px 10px 10px 10px;
  387. opacity: 1;
  388. position: absolute;
  389. bottom: 100px;
  390. left: 26px;
  391. box-sizing: border-box;
  392. display: flex;
  393. align-content: space-around;
  394. flex-direction: row;
  395. flex-wrap: wrap;
  396. justify-content: space-evenly;
  397. z-index: 111;
  398. .Btn {
  399. width: 190px;
  400. height: 86px;
  401. line-height: 86px;
  402. text-align: center;
  403. border-radius: 9px 9px 9px 9px;
  404. opacity: 1;
  405. }
  406.  
  407. .Btn1 {
  408. background: #409eff;
  409. font-size: 32px;
  410. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  411. font-weight: 400;
  412. color: #ffffff;
  413. }
  414.  
  415. .Btn2 {
  416. border: 2px solid #409eff;
  417. background: #eef6ff;
  418. font-size: 32px;
  419. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  420. font-weight: 400;
  421. color: #409eff;
  422. }
  423.  
  424. .Btn3 {
  425. background: #fff3f3;
  426. border: 2px solid #ea0000;
  427. font-size: 32px;
  428. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  429. font-weight: 400;
  430. color: #ea0000;
  431. }
  432. }
  433. // 确认取消弹窗
  434. .QxBox {
  435. width: 100%;
  436. height: 350px;
  437. background-color: #ffffff;
  438.  
  439. .Titlediv {
  440. width: 100%;
  441. height: 80px;
  442. line-height: 80px;
  443. text-align: center;
  444. font-size: 32px;
  445. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  446. font-weight: 400;
  447. box-sizing: border-box;
  448. padding: 0 20px;
  449. position: relative;
  450. border-bottom: 1px solid #ececec;
  451. }
  452. .QxBoxBtn {
  453. width: 100%;
  454. height: calc(350px - 80px);
  455. // background: red;box-sizing: border-box;
  456. display: flex;
  457. align-content: space-around;
  458. flex-direction: row;
  459. flex-wrap: wrap;
  460. justify-content: space-evenly;
  461. }
  462. }
  463. .TaskTItle {
  464. width: 100%;
  465. height: 80px;
  466. text-align: center;
  467. line-height: 80px;
  468. background: #fdfdfd;
  469. position: relative;
  470. font-size: 32px;
  471. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  472. font-weight: 400;
  473.  
  474. .ClearClass {
  475. position: absolute;
  476. right: 10px;
  477. top: 0;
  478. }
  479. }
  480. }
  481. </style>