天波h5前端应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

426 lines
14KB

  1. <template>
  2. <div class="alarm-container" v-show="isPageShow">
  3. <van-nav-bar :title="title" :left-arrow="false" :border="true" @click-left="onNavBack"></van-nav-bar>
  4. <div id="details_map" class="details_map" style="width: 100%;height: 100vh"></div>
  5. <div class="notice">{{ alarm.message + '' }}</div>
  6. <div class="refresh" @click="onRefresh">
  7. <van-icon name="replay" size="25"/>
  8. <span>刷新</span>
  9. </div>
  10. <div class="bottom">
  11. <div class="address">
  12. <div class="title">
  13. <p>{{ params.address }}</p>
  14. </div>
  15. <div class="time">
  16. <span>{{ params.time }}</span>
  17. </div>
  18. </div>
  19. <div class="action">
  20. <van-button
  21. v-for="(item, index) in buttonList"
  22. :key="index"
  23. :type="item.type"
  24. :icon="item.icon"
  25. v-show="item.show"
  26. @click="onErrorReport(item.name)"
  27. >{{ item.text }}</van-button>
  28. </div>
  29. </div>
  30. <!-- 外部地图app选择弹窗 -->
  31. <van-action-sheet
  32. class="actionSheet"
  33. v-model="actionSheetShow"
  34. title="即将打开以下外部APP进行导航"
  35. :actions="mapAppList"
  36. :closeable="false"
  37. cancel-text="取消"
  38. @select="onSelect"
  39. />
  40. </div>
  41. </template>
  42. <script>
  43. import MapLoader from "@/config/amap.js";
  44. import APICore from "@/api/core";
  45. import { isNotNull } from "@/utils/index";
  46. export default {
  47. name: 'alarm-details',
  48. inject: ["reload"],
  49. data(){
  50. return {
  51. alarm: {
  52. message: '你的孩子靠近水域危险区',
  53. address: '',
  54. time: '2023-03-14 14:16:55',
  55. glng: '113.175203274874',
  56. glat: '23.0261293630648'
  57. },
  58. currentAddress: {
  59. address: '',
  60. lng: '',
  61. lat: ''
  62. },
  63. buttonList: [
  64. { name: 'goHere', text: '去这里', type: 'primary', icon: 'guide-o', show: true},
  65. { name: 'errorReport', text: '免告警', type: 'primary', icon: 'warn-o', show: true },
  66. ],
  67. map: {
  68. geocoder: null,
  69. instance: null,
  70. resizeEnable: true,
  71. zoom: 18,
  72. centerMarker: null,
  73. center: [113.175203274874, 23.0261293630648],
  74. },
  75. markers: null,
  76. actionSheetShow: false,
  77. mapAppList: [
  78. { name: "高德地图", wakeUpUrl: "https://uri.amap.com/marker?", number: 0 },
  79. { name: "腾讯地图", wakeUpUrl: "https://apis.map.qq.com/tools/poimarker?", number: 1 }
  80. ],
  81. params: {
  82. imei: '',
  83. poiId: '',
  84. title: '',
  85. lng: '',
  86. lat: '',
  87. address: '',
  88. status: true,
  89. time: ''
  90. },
  91. isPageShow: null,
  92. status: 1
  93. }
  94. },
  95. computed: {
  96. title() {
  97. return this.status === "1" ? '进入涉水区域警报' : '离开涉水区域警报';
  98. }
  99. },
  100. created() {
  101. this.getAuth();
  102. this.getParams();
  103. //this.initAmap();
  104. },
  105. methods: {
  106. // 获取b端接口的token
  107. getAuth() {
  108. let manufactorId = "5bf13062-a41e-4d00-ba14-1101aad12650";
  109. APICore.getAuth({ manufactorId: manufactorId }).then(res => {
  110. this.$store.commit("gatewayToken", res.data.data);
  111. });
  112. },
  113. // 获取路由参数
  114. getParams() {
  115. let params = this.$route.query;
  116. if (isNotNull(params)) {
  117. console.log("params", params);
  118. this.params = {...params};
  119. this.buttonList[1].show = params.status === "1";
  120. this.status = params.status;
  121. this.alarm.message = params.status === "1" ? '你的孩子靠近水域危险区': '你的孩子离开水域危险区';
  122. this.isPageShow = true;
  123. this.initAmap();
  124. console.log("this.params", this.params);
  125. } else {
  126. this.$dialog.confirm({
  127. message: '跳转参数错误,请联系管理员',
  128. showCancelButton: false
  129. })
  130. this.isPageShow = false;
  131. }
  132. },
  133. onNavBack() {},
  134. // 初始化地图
  135. initAmap() {
  136. this.$toast.loading('地图加载中');
  137. MapLoader(false, [ 'AMap.PolyEditor', 'AMap.MouseTool', 'AMap.Geocoder', 'AMap.Geolocation', 'AMap.ToolBar' ]).then(
  138. AMap => {
  139. this.map.instance = new AMap.Map("details_map", {
  140. center: [this.params.lng, this.params.lat],
  141. resizeEnable: this.map.resizeEnable,
  142. zoom: this.map.zoom,
  143. zoomEnable: true
  144. });
  145. // 构建逆地理编码器
  146. this.map.geocoder = new AMap.Geocoder({
  147. extensions: "all"
  148. });
  149. const toolBar = new AMap.ToolBar({ offset: new AMap.Pixel(10, 310), position: 'RB' });
  150. this.map.instance.addControl(toolBar);
  151. this.initCenterMarker();
  152. this.$toast.success('地图加载完成');
  153. this.geocoder([this.params.lng, this.params.lat]);
  154. },
  155. err => {
  156. this.$toast.clear();
  157. console.log("加载地图失败:::", err);
  158. }
  159. );
  160. setTimeout(() => {
  161. this.$toast.clear();
  162. }, 5000)
  163. },
  164. // 初始化marker
  165. initCenterMarker() {
  166. const content = '<div class="centerMarker"><i class="cir"></i></div>';
  167. let position = this.map.instance.getCenter();
  168. console.log("position", position);
  169. position = [ position.lng, position.lat ];
  170. if(this.map.centerMarker) {
  171. // 如果 存在marker,则清掉前一个marker,防止出现多个marker的情况
  172. this.map.instance.remove(this.map.centerMarker);
  173. }
  174. // 创建一个 Icon
  175. let markerIcon = new AMap.Icon({
  176. size: new AMap.Size(25, 34),
  177. image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
  178. imageSize: new AMap.Size(135, 40),
  179. imageOffset: new AMap.Pixel(-95, -3)
  180. });
  181. this.map.centerMarker = new AMap.Marker({
  182. position: position,
  183. icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
  184. offset: new AMap.Pixel(-13, -30)
  185. });
  186. this.map.instance.add(this.map.centerMarker);
  187. },
  188. // 逆地理编码,通过坐标获取详细中文地址
  189. geocoder(lngLat) {
  190. this.map.geocoder.getAddress(lngLat, (status, result) => {
  191. if (status == "complete" && result.info == "OK") {
  192. this.currentAddress.address = result.regeocode.formattedAddress;
  193. this.alarm.address = result.regeocode.formattedAddress;
  194. console.log("使用高德逆地理解析得到的地址", this.currentAddress.address);
  195. }
  196. });
  197. },
  198. // 调用高德定位api获取当前位置
  199. createGeolocation() {
  200. this.map.geolocation = new AMap.Geolocation({
  201. nableHighAccuracy: true, //是否使用高精度定位,默认:true
  202. timeout: 10000, //超过10秒后停止定位,默认:5s
  203. zoomToAccuracy: false, //定位成功后是否自动调整地图视野到定位点
  204. buttonPosition:'LT', //定位按钮的停靠位置
  205. showButton: process.env.NODE_ENV !== 'production',
  206. buttonOffset: new AMap.Pixel(20, 400), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
  207. showMarker: false, // 定位成功后是否显示marker
  208. showCircle: false, // 定位成功并且有精度信息时,是否用一个圆圈circle表示精度范围,默认值:true
  209. });
  210. this.map.instance.addControl(this.map.geolocation);
  211. const _this = this;
  212. const localeLoading = this.$toast.loading('获取定位中...');
  213. this.map.geolocation.getCurrentPosition(function (status, result) {
  214. try {
  215. if(status == 'complete') {
  216. console.log('定位完成:::', result);
  217. const position = [ result.position.lng, result.position.lat ];
  218. _this.geocoder(position);
  219. } else {
  220. console.error('用户未授权定位:::');
  221. console.error('status:::', status);
  222. console.error('result:::', result);
  223. _this.$notify({
  224. type: 'warning',
  225. message: '您未打开定位服务,前往设置可打开'
  226. });
  227. }
  228. } catch (e) {
  229. console.log(e);
  230. } finally {
  231. localeLoading.clear();
  232. }
  233. })
  234. },
  235. // 免告警
  236. onErrorReport(name) {
  237. if(name === 'goHere') {
  238. // 根据选择的地图跳转不同地图app的url
  239. this.actionSheetShow = true;
  240. } else {
  241. this.$dialog({
  242. title: '',
  243. message: '点击确认后,进入这个区域将永不告警',
  244. showCancelButton: true,
  245. closeOnClickOverlay: true,
  246. }).then(() => {
  247. // 调取接口设置该设备IMEI与该水域告警poi_id不做任何报警信息处理
  248. this.drownReportFilterAdd();
  249. }).catch(() => {
  250. console.log("取消");
  251. })
  252. }
  253. },
  254. // 误报接口
  255. drownReportFilterAdd() {
  256. this.$toast.loading('设置中');
  257. let reqBody = {
  258. ...this.params
  259. };
  260. reqBody['status'] = true;
  261. delete reqBody.message;
  262. delete reqBody.time;
  263. console.log("请求的参数", reqBody);
  264. APICore.drownReportFilterAdd(reqBody).then(res => {
  265. console.log("res", res);
  266. let data = res.data;
  267. if(data.code === 0) {
  268. this.$toast.success('设置成功')
  269. };
  270. }).catch(error => {
  271. this.$dialog.confirm({
  272. message: `${error.message}`
  273. });
  274. }).finally(() => {
  275. setTimeout(() => {
  276. this.$toast.clear();
  277. },1500)
  278. })
  279. },
  280. // 选择打开外部地图app
  281. onSelect(item) {
  282. if(item.number === 0) {
  283. // 高德
  284. this.wakeUpGaodeMap(item.wakeUpUrl);
  285. } else if (item.number === 1) {
  286. this.wakeUpTencentMap(item.wakeUpUrl);
  287. }
  288. },
  289. // 唤醒高德地图
  290. wakeUpGaodeMap(wakeUpUrl) {
  291. const position = this.params.lng + ',' +this.params.lat;
  292. const name = this.params.address;
  293. window.location.href = `${wakeUpUrl}position=${position}&name=${name}&callnative=1`;
  294. },
  295. // 唤醒 腾讯地图
  296. wakeUpTencentMap(wakeUpUrl) {
  297. const position = this.params.lat + ',' + this.params.lng ;
  298. const address = this.params.address;
  299. const key = 'UHFBZ-I5ECQ-GSA5B-GW3UW-V2NL5-A3FNY';
  300. const myAppName = 'ssjlqqmap';
  301. window.location.href = `${wakeUpUrl}type=0&marker=coord:${position};title:${address};addr:${address}&key=${key}&referer=${myAppName}`;
  302. },
  303. // 刷新
  304. onRefresh() {
  305. this.reload();
  306. }
  307. }
  308. }
  309. </script>
  310. <style lang="scss">
  311. .alarm-container {
  312. .details_map {
  313. $width: 50PX;
  314. $cirWidth: 15PX;
  315. .centerMarker {
  316. position: relative;
  317. display: flex;
  318. justify-content: center;
  319. align-items: center;
  320. z-index: 999;
  321. }
  322. .centerMarker i.cir {
  323. display: flex;
  324. justify-content: center;
  325. align-items: center;
  326. width: $width;
  327. height: $width;
  328. background: rgba(255, 178, 128, 0.4);
  329. border-radius: 50%;
  330. }
  331. .centerMarker i.cir:after {
  332. content: " ";
  333. width: $cirWidth;
  334. height: $cirWidth;
  335. background: #ff9625;
  336. border: 2PX solid #fff;
  337. border-radius: 50%;
  338. }
  339. }
  340. }
  341. </style>
  342. <style scoped lang="scss">
  343. .alarm-container {
  344. position: relative;
  345. height: 100vh;
  346. width: 100%;
  347. .van-nav-bar {
  348. position: absolute;
  349. left: 0;
  350. top: 0;
  351. width: 100%;
  352. }
  353. .notice {
  354. position: absolute;
  355. top: 40px;
  356. height: 40px;
  357. width: 100%;
  358. background-color: #ee0a24;
  359. color: #fff;
  360. font-size: 14px;
  361. @include center();
  362. }
  363. .refresh {
  364. position: absolute;
  365. top: 100px;
  366. right: 20px;
  367. height: 50px;
  368. width: 50px;
  369. background-color: #fff;
  370. box-shadow: 0 0 5px 1px rgba(185, 185, 185, 0.4);
  371. border-radius: 5px;
  372. @include center();
  373. flex-direction: column;
  374. span {
  375. font-size: 14px;
  376. }
  377. }
  378. .bottom {
  379. width: 100%;
  380. position: absolute;
  381. bottom: 0;
  382. left: 0;
  383. background-color: $background;
  384. z-index: 999;
  385. padding-bottom: constant(safe-area-inset-bottom); //* 兼容 iOS<11.2 */
  386. padding-bottom: env(safe-area-inset-bottom); ///* 兼容iOS>= 11.2 */
  387. .address {
  388. padding: 10px;
  389. display: flex;
  390. justify-content: flex-start;
  391. align-items: flex-start;
  392. flex-direction: column;
  393. font-size: 14px;
  394. margin: 10px 10px 0 10px;
  395. .title {
  396. width: 100%;
  397. text-align: left;
  398. font-weight: bold;
  399. }
  400. .time {
  401. width: 100%;
  402. background-color: #fff;
  403. padding: 5px 0;
  404. margin: 5px 0;
  405. font-weight: 400;
  406. text-align: left;
  407. border-radius: 5px;
  408. span {
  409. margin-left: 5px;
  410. }
  411. }
  412. }
  413. .action {
  414. display: flex;
  415. justify-content: space-around;
  416. padding-bottom: 15px;
  417. .van-button {
  418. width: 120px;
  419. }
  420. }
  421. }
  422. }
  423. </style>