leader.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. <template>
  2. <div class="visual-con">
  3. <!--头部-->
  4. <vheader></vheader>
  5. <!--主体-->
  6. <div class="visual-body">
  7. <!-- 左侧 -->
  8. <div class="leftbar" :class="indentleft" ref="left">
  9. <div class="forthis">
  10. <dv-border-box-13
  11. backgroundColor="rgba(12, 19, 38, .90)"
  12. style="padding-bottom: 1rem"
  13. >
  14. <img
  15. src="../assets/images/integrated/light.png"
  16. style="width: 100%; margin-top: 0.4rem"
  17. />
  18. <div class="this-title">
  19. <span>人员分布</span>
  20. <dv-decoration-3
  21. style="width: 150px; height: 15px; margin-right: 1rem"
  22. />
  23. </div>
  24. <div class="i-list-con h-25">
  25. <div id="personnel-chart" style="width: 100%; height: 12vh"></div>
  26. <div class="d-l-con-icon">
  27. <div
  28. class="icon-con w-50"
  29. :class="{ on: iconCurrentIndex1 == item.dict_sort }"
  30. v-for="(item, index) in visuForestCloudRYBO"
  31. @click="getRyListByJob(item.dict_sort, item.dictType)"
  32. >
  33. <div class="icon icon-mid el-icon-user"></div>
  34. <div class="icon-text">
  35. <h5>{{ item.job }}</h5>
  36. <h6>{{ item.number }}</h6>
  37. </div>
  38. </div>
  39. <!-- <div class="icon-con w-50 m-btm-no" :class="{on:listCurrentIndex1==item.jobType}" v-for="(item,index) in visuForestCloudRYBO" v-if="index%2!=0" @click="getForestLeader(item.jobValue,item.jobType)">
  40. <div class="icon icon-mid el-icon-user"></div>
  41. <div class="icon-text">
  42. <h5>{{item.job}}</h5>
  43. <h6>{{item.number}}</h6>
  44. </div>
  45. </div> -->
  46. </div>
  47. </div>
  48. </dv-border-box-13>
  49. </div>
  50. <!-- avatar: ""-->
  51. <!-- deptName: "锦程社区第一网格"-->
  52. <!-- nickName: "李猛"-->
  53. <!-- userId: 102-->
  54. <!-- userName: "limeng"-->
  55. <div class="forthis">
  56. <dv-border-box-13
  57. backgroundColor="rgba(12, 19, 38, .90)"
  58. style="padding-bottom: 1rem"
  59. >
  60. <img
  61. src="../assets/images/integrated/light.png"
  62. style="width: 100%; margin-top: 0.4rem"
  63. />
  64. <div class="sj-search">
  65. <el-input
  66. v-model="name"
  67. placeholder="请输入姓名"
  68. clearable
  69. size="small"
  70. prefix-icon="el-icon-search"
  71. />
  72. </div>
  73. <div class="i-list-con" style="height: 40vh">
  74. <div class="d-l-con-icon">
  75. <div
  76. class="icon-con"
  77. :class="{ on: listCurrentIndex1 == item.userId }"
  78. v-for="(item, index) in peopleList2"
  79. @click="getPlanList(item.userId)"
  80. >
  81. <div class="icon icon-mid el-icon-user"></div>
  82. <div class="icon-text personnel-name">
  83. <h6>
  84. {{ item.name }}
  85. <span v-if="item.phone != undefined">
  86. - {{ item.phone }}</span
  87. >
  88. </h6>
  89. <h5>{{ item.deptName }}</h5>
  90. </div>
  91. </div>
  92. </div>
  93. </div>
  94. </dv-border-box-13>
  95. </div>
  96. </div>
  97. <!-- 地图 -->
  98. <!-- <supermap ref="supermap" style="width: 100%;height: 100vh;" :mapDiv="'forestMap'" class="indexSupermapClass"-->
  99. <!-- :mapSite="{doubleClickZoom:false}" :codes="['9fa5']" :isSideBySide="false"></supermap>-->
  100. <supermap ref="supermap" style="width: 100%; height: 100vh"></supermap>
  101. <!-- 右侧 -->
  102. <div class="rightbar" :class="indentright" ref="right">
  103. <div class="forthis">
  104. <dv-border-box-13
  105. backgroundColor="rgba(12, 19, 38, .90)"
  106. style="padding-bottom: 1rem"
  107. >
  108. <img
  109. src="../assets/images/integrated/light.png"
  110. style="width: 100%; margin-top: 0.4rem"
  111. />
  112. <div class="this-title">
  113. <span>巡田任务</span>
  114. <dv-decoration-3
  115. style="width: 150px; height: 15px; margin-right: 1rem"
  116. />
  117. </div>
  118. <div class="i-list-con h-73">
  119. <div class="h-73 overflow-y">
  120. <el-collapse accordion>
  121. <el-collapse-item v-for="(item, index) in xunLinListOne">
  122. <template slot="title">
  123. <div
  124. class="d-l-con sj-collapse"
  125. @click="getRecordList(item.id, item.patrolTrajectory)"
  126. >
  127. <div class="d-l-l-text">
  128. <el-tooltip
  129. class="item"
  130. effect="dark"
  131. placement="left"
  132. style="width: 10rem"
  133. :disabled="item.taskName.length <= 20"
  134. >
  135. <div slot="content">
  136. <h4 class="collapse-title" style="width: 200px">
  137. {{ item.taskName }}
  138. </h4>
  139. </div>
  140. <h4 class="collapse-title" style="width: 100px">
  141. {{ item.taskName | ellipsis20 }}
  142. </h4>
  143. </el-tooltip>
  144. </div>
  145. <div class="d-l-l-count">
  146. ({{ item.recordCount }}/{{ item.planCount }})
  147. </div>
  148. </div>
  149. </template>
  150. <div
  151. class="d-l-con this-child sj-collapse"
  152. @click="getPointList(child.id)"
  153. v-for="(child, index) in recordList"
  154. >
  155. <div class="d-l-l-text">
  156. <h4>{{ child.beginTime }} - {{ child.endTime }}</h4>
  157. </div>
  158. <!--<div class="d-l-l-count">{{index}}</div>-->
  159. </div>
  160. <div
  161. class="d-l-con this-child sj-collapse"
  162. v-if="
  163. showNothing &&
  164. (recordList == null ||
  165. recordList == '' ||
  166. recordList == [])
  167. "
  168. >
  169. <div class="d-l-l-text">
  170. <h4 class="text-gray">暂无信息</h4>
  171. </div>
  172. </div>
  173. </el-collapse-item>
  174. </el-collapse>
  175. <!--<div class="d-l-con" :class="{on:listCurrentIndex2==item.planName}"
  176. v-for="(item,index) in xunLinListOne"
  177. @click="setConnectList(item.planLine,item.planName)">
  178. <div class="d-l-l-text">
  179. <i class="i-small"></i>
  180. <h4>{{ item.planName }}</h4>
  181. </div>
  182. </div>-->
  183. </div>
  184. </div>
  185. </dv-border-box-13>
  186. </div>
  187. </div>
  188. <vBottomMenu ref="bottomMenu"></vBottomMenu>
  189. <!-- <el-tooltip :content="indentText" placement="top" :disabled="indentdisabled">-->
  190. <!-- <div class="mascot" ref="mascot" :class="indentStyle" @click="indent">-->
  191. <!-- <img src="@/assets/images/mascot.png"/>-->
  192. <!-- </div>-->
  193. <!-- </el-tooltip>-->
  194. </div>
  195. <eventLocation ref="eventLocation"></eventLocation>
  196. <TVWall ref="TVWall"></TVWall>
  197. </div>
  198. </template>
  199. <script>
  200. import {
  201. getForestLeader,
  202. getPlanList,
  203. getRecordList,
  204. getPointList,
  205. getRy,
  206. } from "@/api/leader";
  207. import supermap from "@/components/supermap-2.5d"; //超图
  208. import vheader from "@/components/v-header.vue"; //一体化共用头部
  209. import vBottomMenu from "@/components/vBottomMenu.vue"; //一体化公共底部菜单
  210. import eventLocation from "@/components/eventLocation.vue"; //事件定位弹窗
  211. import TVWall from "@/components/TVWall.vue";
  212. import { getRyList, getRyListByJob } from "@/api/forest";
  213. import {getUserProfile} from "@/api/system/user"; //电视墙弹窗
  214. let echarts = require("echarts");
  215. export default {
  216. components: {
  217. supermap,
  218. vheader,
  219. vBottomMenu,
  220. eventLocation,
  221. TVWall,
  222. },
  223. data() {
  224. return {
  225. iconCurrentIndex1: "",
  226. listCurrentIndex1: "",
  227. listCurrentIndex2: "",
  228. //左右缩进
  229. indentStyle: "",
  230. indentleft: "",
  231. indentright: "",
  232. indentText: "收起左右栏",
  233. indentdisabled: false,
  234. visuForestCloudRYBO: [], //人员类型列表
  235. peopleList: [], //人员列表
  236. name: "",
  237. peopleList2: [], //人员列表
  238. connectList: [], //画线
  239. xunLinListOne: [], //巡林任务
  240. recordList: [], //巡查记录
  241. showNothing: false, //暂无信息
  242. zrs: 0, //总人数
  243. zxrs: 0, //在线人数
  244. };
  245. },
  246. created() {
  247. this.getRyList();
  248. // this.getInit()
  249. /** ----------------------------------底部按钮公用组件开始------------------------------------- */
  250. window.showDialog = this.showDialog;
  251. window.choseLayerSwitching = this.choseLayerSwitching;
  252. window.choseLayerSwitchingList = this.choseLayerSwitchingList;
  253. window.choseLayerSwitchingList_Data = this.choseLayerSwitchingList_Data;
  254. /** ----------------------------------底部按钮公用组件结束------------------------------------- */
  255. },
  256. mounted() {
  257. // 初始化地图数据
  258. this.getSuperMapUrl();
  259. this.bottomMenuList(); //获取底部公共组件消息和任务
  260. },
  261. watch: {
  262. name(val) {
  263. this.peopleList2 = [];
  264. for (let i in this.peopleList) {
  265. if (this.peopleList[i].name.indexOf(val) != -1) {
  266. this.peopleList2.push(this.peopleList[i]);
  267. }
  268. }
  269. },
  270. },
  271. methods: {
  272. //初始化地图数据
  273. getSuperMapUrl(){
  274. getUserProfile().then(response => {
  275. let mapDeptId=response.mapDeptId
  276. let num = 0;
  277. if (mapDeptId == "365") {
  278. num = 0;
  279. } else if (mapDeptId == "369") {
  280. num = 1;
  281. } else if (mapDeptId == "371") {
  282. num = 2;
  283. } else if (mapDeptId == "373") {
  284. num = 3;
  285. } else if (mapDeptId == "372") {
  286. num = 4;
  287. } else if (mapDeptId == "370") {
  288. num = 5;
  289. }
  290. this.$refs.supermap.removeAllviewer(num, -1);
  291. });
  292. },
  293. /** ----------------------------------底部按钮公用组件开始------------------------------------- */
  294. bottomMenuList() {
  295. this.$refs.bottomMenu.selectTaskList(); //获取任务列表
  296. this.$refs.bottomMenu.selectMessageList(); //获取消息列表
  297. },
  298. showDialog(click) {
  299. if (click == "eventLocation") {
  300. this.$refs.eventLocation.showEventLocation();
  301. this.$refs.bottomMenu.showMeasure = false;
  302. this.$refs.bottomMenu.showChild = false;
  303. this.$refs.bottomMenu.showBanChild = false;
  304. this.$refs.bottomMenu.showChangChild = false;
  305. } else if (click == "editableLayers") {
  306. this.$refs.bottomMenu.showChild = false;
  307. this.$refs.bottomMenu.showBanChild = false;
  308. this.$refs.bottomMenu.showChangChild = false;
  309. if (!this.$refs.bottomMenu.showMeasure) {
  310. this.$refs.bottomMenu.showMeasure = true;
  311. } else {
  312. this.$refs.bottomMenu.showMeasure = false;
  313. }
  314. } else if (click == "layerSwitching") {
  315. this.$refs.bottomMenu.showMeasure = false;
  316. this.$refs.bottomMenu.showBanChild = false;
  317. this.$refs.bottomMenu.showChangChild = false;
  318. if (!this.$refs.bottomMenu.showChild) {
  319. this.$refs.bottomMenu.showChild = true;
  320. } else {
  321. this.$refs.bottomMenu.showChild = false;
  322. }
  323. } else if (click == "TVWall") {
  324. this.$refs.TVWall.showTVWall();
  325. this.$refs.bottomMenu.showMeasure = false;
  326. this.$refs.bottomMenu.showChild = false;
  327. this.$refs.bottomMenu.showBanChild = false;
  328. this.$refs.bottomMenu.showChangChild = false;
  329. } else if (click == "forestban") {
  330. this.$refs.bottomMenu.showMeasure = false;
  331. this.$refs.bottomMenu.showChild = false;
  332. this.$refs.bottomMenu.showChangChild = false;
  333. if (!this.$refs.bottomMenu.showBanChild) {
  334. this.$refs.bottomMenu.showBanChild = true;
  335. } else {
  336. this.$refs.bottomMenu.showBanChild = false;
  337. }
  338. } else if (click == "forestchang") {
  339. this.$refs.bottomMenu.showMeasure = false;
  340. this.$refs.bottomMenu.showBanChild = false;
  341. this.$refs.bottomMenu.showChild = false;
  342. if (!this.$refs.bottomMenu.showChangChild) {
  343. this.$refs.bottomMenu.showChangChild = true;
  344. } else {
  345. this.$refs.bottomMenu.showChangChild = false;
  346. }
  347. }
  348. },
  349. //选择图层
  350. choseLayerSwitching(url, isClear) {
  351. this.$refs.supermap.layerSwitching(url, isClear);
  352. },
  353. //选择图层(传递数组)
  354. choseLayerSwitchingList(urlList) {
  355. this.$refs.supermap.layerSwitchingList(urlList);
  356. },
  357. //选择图层(传递数组) 带数据
  358. choseLayerSwitchingList_Data(urlList) {
  359. this.$refs.supermap.layerSwitchingList_Data(urlList);
  360. },
  361. /** ----------------------------------底部按钮公用组件结束------------------------------------- */
  362. // 获取人员信息(河长、路长、田长)
  363. getRyList() {
  364. let that = this;
  365. that.iconCurrentIndex1 = "";
  366. that.listCurrentIndex1 = "";
  367. that.listCurrentIndex2 = "";
  368. getRyList({
  369. leadType: "6",
  370. }).then(function (response) {
  371. // console.log(JSON.stringify(response.data));
  372. that.visuForestCloudRYBO = response.data.ryList;
  373. that.zrs = response.data.num;
  374. that.personnelChart();
  375. });
  376. },
  377. getRyListByJob(jobValue, jobType) {
  378. let that = this;
  379. that.listCurrentIndex1 = "";
  380. that.listCurrentIndex2 = "";
  381. that.iconCurrentIndex1 = jobValue;
  382. that.name = "";
  383. that.peopleList = [];
  384. that.peopleList2 = [];
  385. getRyListByJob({
  386. leadType: "6",
  387. dictType: jobType,
  388. }).then(function (response) {
  389. // console.log(JSON.stringify(response.data));
  390. that.peopleList = response.data;
  391. that.peopleList2 = response.data;
  392. });
  393. },
  394. //初始化 废弃
  395. // getInit() {
  396. // let that = this
  397. // this.iconCurrentIndex1 = '1'
  398. // this.listCurrentIndex1 = ''
  399. // this.listCurrentIndex2 = ''
  400. // //获取左侧菜单列表
  401. // getRy().then(res => {
  402. // that.visuForestCloudRYBO = res.data.visuForestCloudRYBO
  403. // that.zrs = res.data.visuForestCloudRyZxBO.zrs
  404. // that.zxrs = res.data.visuForestCloudRyZxBO.zxrs
  405. // this.personnelChart()
  406. // })
  407. // },
  408. //获取左侧人员列表
  409. getForestLeader(linJob, linType) {
  410. this.listCurrentIndex1 = "";
  411. this.listCurrentIndex2 = "";
  412. this.iconCurrentIndex1 = linJob;
  413. this.peopleList = [];
  414. this.peopleList2 = [];
  415. getForestLeader(linJob, linType).then((res) => {
  416. this.peopleList = res.data;
  417. this.peopleList2 = res.data;
  418. });
  419. this.connectList = [];
  420. this.personId = null;
  421. this.xunLinListOne = [];
  422. this.patrolTrajectory = null;
  423. this.$refs.supermap.clearC();
  424. this.$refs.supermap.clearTwoC();
  425. },
  426. //点击左侧人员列表获取 巡林计划
  427. getPlanList(personId) {
  428. this.listCurrentIndex1 = personId;
  429. if (this.personId == personId) {
  430. //当前人员已经被点击一次 不再重复加载
  431. return;
  432. }
  433. this.personId = personId;
  434. this.showNothing = false;
  435. this.recordList = [];
  436. getPlanList(personId).then((res) => {
  437. this.xunLinListOne = res.data;
  438. });
  439. this.patrolTrajectory = null;
  440. this.$refs.supermap.clearC();
  441. this.$refs.supermap.clearTwoC();
  442. },
  443. //点击右侧巡林计划获取 巡查记录
  444. getRecordList(id, patrolTrajectory) {
  445. this.showNothing = false;
  446. this.recordList = [];
  447. getRecordList(id, this.personId).then((res) => {
  448. this.recordList = res.data;
  449. });
  450. this.$refs.supermap.clearC();
  451. this.$refs.supermap.clearTwoC();
  452. this.setTaskPointList(patrolTrajectory);
  453. },
  454. //点击右侧巡查记录获取 巡查轨迹
  455. getPointList(id) {
  456. getPointList(id).then((res) => {
  457. // console.log("落点",res.data);
  458. this.setPointList(res);
  459. });
  460. },
  461. //点击巡查人员 巡查任务落点
  462. setTaskPointList(patrolTrajectory) {
  463. console.log("巡查任务落点", typeof JSON.parse(patrolTrajectory));
  464. if (this.patrolTrajectory == patrolTrajectory) {
  465. this.patrolTrajectory = null;
  466. } else {
  467. this.patrolTrajectory = patrolTrajectory;
  468. this.drawTaskPoint(this.patrolTrajectory);
  469. }
  470. },
  471. // 巡查任务落点
  472. drawTaskPoint(patrolTrajectory) {
  473. let list = JSON.parse(patrolTrajectory);
  474. let data = [];
  475. for (var i = 0; i < list.length; i++) {
  476. data.push(list[i].lng);
  477. data.push(list[i].lat);
  478. }
  479. setTimeout(() => {
  480. this.$refs.supermap.clearC();
  481. this.$refs.supermap.clearTwoC();
  482. this.$refs.supermap.setConnectList(data, "#04f", 0.8);
  483. }, 1000);
  484. },
  485. //点击巡查轨迹时段 巡查轨迹落点
  486. setPointList(res) {
  487. let that = this;
  488. this.connectList = [];
  489. console.log("落点", res.data);
  490. if (res.data != null && res.data.length > 0) {
  491. for (let i = 0; i < res.data.length; i++) {
  492. that.connectList.push(res.data[i].longitude);
  493. that.connectList.push(res.data[i].latitude);
  494. }
  495. setTimeout(() => {
  496. that.$refs.supermap.clearTwoC();
  497. that.$refs.supermap.setConnectTwoList(this.connectList, "#f40", 0.8);
  498. }, 1000);
  499. } else {
  500. that.$refs.supermap.clearTwoC();
  501. }
  502. },
  503. setConnectList(points, planName) {
  504. this.listCurrentIndex2 = planName;
  505. this.connectList = [];
  506. if (points != null && points != "") {
  507. this.connectList = JSON.parse(points);
  508. this.$refs.supermap.setConnectTwoList(this.connectList, "red");
  509. }
  510. },
  511. //吉祥物收起左右框
  512. indent() {
  513. let list = document.getElementsByClassName("el-tooltip__popper");
  514. list[list.length - 1].style.display = "none";
  515. if (this.indentStyle == "") {
  516. this.indentStyle = "indent-style";
  517. this.indentleft = "indent-left";
  518. this.indentright = "indent-right";
  519. this.indentText = "展开左右栏";
  520. } else if (this.indentText == "展开左右栏") {
  521. this.indentStyle = "";
  522. this.indentleft = "";
  523. this.indentright = "";
  524. this.indentText = "收起左右栏";
  525. }
  526. },
  527. //人员chart
  528. personnelChart() {
  529. // 基于准备好的dom,初始化echarts实例
  530. let myChart = echarts.init(document.getElementById("personnel-chart"));
  531. // 绘制图表
  532. const handred = this.zrs;
  533. let point = this.zxrs;
  534. myChart.setOption({
  535. title: [
  536. {
  537. text:
  538. "总人数:" +
  539. handred +
  540. "人" +
  541. "\n" +
  542. "\n",
  543. // "在线人数:" +
  544. // point +
  545. // "人",
  546. x: "48%",
  547. y: "25%",
  548. textStyle: {
  549. fontWeight: "normal",
  550. color: "#02d6fc",
  551. fontSize: "14",
  552. },
  553. },
  554. ],
  555. series: [
  556. {
  557. name: "circle",
  558. type: "pie",
  559. center: ["22%", "50%"],
  560. radius: ["60%", "70%"],
  561. clockWise: true,
  562. label: {
  563. normal: {
  564. position: "center",
  565. },
  566. },
  567. itemStyle: {
  568. normal: {
  569. label: {
  570. show: false,
  571. },
  572. labelLine: {
  573. show: false,
  574. },
  575. },
  576. },
  577. data: [
  578. {
  579. value: point,
  580. name: "当前在线",
  581. label: {
  582. show: true, //单独显示该数据项
  583. formatter: handred+"人",
  584. labelLayout: {
  585. top: "50%",
  586. },
  587. textStyle: {
  588. color: "#02d6fc",
  589. fontSize: 14,
  590. },
  591. },
  592. itemStyle: {
  593. normal: {
  594. color: {
  595. // 完成的圆环的颜色
  596. colorStops: [
  597. {
  598. offset: 0,
  599. color: "#02d6fc", // 0% 处的颜色
  600. },
  601. {
  602. offset: 1,
  603. color: "#367bec", // 100% 处的颜色
  604. },
  605. ],
  606. },
  607. label: {
  608. show: false,
  609. },
  610. labelLine: {
  611. show: false,
  612. },
  613. },
  614. },
  615. },
  616. {
  617. value: handred - point,
  618. itemStyle: {
  619. color: "#666",
  620. },
  621. },
  622. ],
  623. },
  624. ],
  625. });
  626. },
  627. },
  628. //过滤器
  629. filters: {
  630. //标题截取前20
  631. ellipsis20(value) {
  632. if (!value) return "";
  633. if (value.length > 20) {
  634. return value.slice(0, 20) + "...";
  635. }
  636. return value;
  637. },
  638. },
  639. };
  640. </script>
  641. <style rel="stylesheet/scss" lang="scss" scoped>
  642. @import "@/assets/styles/base.scss";
  643. .h-27 {
  644. height: 27rem;
  645. }
  646. </style>