index.vue 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  1. <template>
  2. <div class="base-container no-events">
  3. <fnHeader showDate></fnHeader>
  4. <div class="content">
  5. <navigation style="margin-left: 50px" @handleTab="handleTab"></navigation>
  6. <div class="left yes-events" :class="{ 'collapsed-left': isLeftShrink }">
  7. <div class="home-btn">
  8. <div class="btn" @click="changeLeftComponent(0)" :class="{active: activeBtn === 0}">实时感知</div>
  9. <div class="btn" @click="changeLeftComponent(1)" :class="{active: activeBtn === 1}">诊断识别</div>
  10. </div>
  11. <tool-list direction="left" ref="leftTool" :list="leftToolList[activeBtn]" @handleActive="handleActiveLeft"></tool-list>
  12. <component :is="components[currentComponent]" />
  13. <!-- 箭头 -->
  14. <div class="arrow" @click="handleShrink('left')">
  15. <el-icon class="icon" :class="{ 'arrow-left': isLeftShrink }" color="#141414"><DArrowLeft /></el-icon>
  16. </div>
  17. </div>
  18. <div class="home-bottom">
  19. <img class="img yes-events" @click="handlePage" src="@/assets/images/home/table-btn-sk.png" alt="">
  20. <!-- <div class="garden-file" :class="{ isShrink: isShrink }">
  21. <home-file></home-file>
  22. </div> -->
  23. </div>
  24. <div class="right yes-events" :class="{ 'collapsed-right': isRightShrink }">
  25. <div class="home-btn">
  26. <div class="btn" @click="changeRightComponent(0)" :class="{active: activeRightBtn === 0}">精细农事</div>
  27. <div class="btn" @click="changeRightComponent(1)" :class="{active: activeRightBtn === 1}">人机执行</div>
  28. </div>
  29. <div class="list album-r">
  30. <chart-box name="农事列表" arrow="arrow-left" :class="{ 'list-wrap': rightIndex === 0 }">
  31. <template v-if="rightIndex === 0">
  32. <album></album>
  33. </template>
  34. <template v-if="rightIndex === 1">
  35. <div class="img-box1">
  36. <img src="@/assets/images/home/fh01.png" alt="" />
  37. <img src="@/assets/images/home/fh02.png" alt="" />
  38. </div>
  39. </template>
  40. </chart-box>
  41. </div>
  42. <tool-list direction="right" ref="rightTool" :list="rightToolList[activeRightBtn]" @handleActive="handleActiveRight"></tool-list>
  43. <!-- 箭头 -->
  44. <!-- <div class="arrow" @click="handleShrink('right')">
  45. <el-icon class="icon" :class="{ 'arrow-right': isRightShrink }" color="#141414"><DArrowRight /></el-icon>
  46. </div> -->
  47. </div>
  48. <!-- 图例 -->
  49. <!-- <img class="legend yes-events" src="@/assets/images/home/legend-img.png" alt="" /> -->
  50. <div v-if="legendArr && legendArr.length" class="map-bg map-legend yes-events">
  51. <div class="item" v-for="(legend, legendI) in legendArr" :key="legendI">
  52. <span class="legend-block" :style="{background: legend.color}"></span>
  53. {{ legend.name }}
  54. </div>
  55. </div>
  56. <div v-else class="map-bg map-legend yes-events">
  57. <div class="item">
  58. <img src="@/assets/images/map/status/status-bh.png" alt="" />
  59. 病害异常
  60. </div>
  61. <div class="item">
  62. <img src="@/assets/images/map/status/status-ch.png" alt="" />
  63. 虫害异常
  64. </div>
  65. <div class="item">
  66. <img src="@/assets/images/map/status/status-zc.png" alt="" />
  67. 正常
  68. </div>
  69. <!-- <div class="item">
  70. <img src="@/assets/images/map/status/defalut-icon.png" alt="" />
  71. 无照片
  72. </div> -->
  73. </div>
  74. </div>
  75. </div>
  76. <div ref="mapRef" class="bottom-map"></div>
  77. <!-- 图片弹窗 -->
  78. <PicturePreview :imageUrl="urls" :curIndex="urlsIndex"></PicturePreview>
  79. <album-carousel></album-carousel>
  80. <PdfDialog title="果园报告"></PdfDialog>
  81. <!-- 对比 -->
  82. <compareDialog></compareDialog>
  83. <div class="compare-start-btn yes-events" v-show="showCompareBtn" @click="showCompare">
  84. <img src="@/assets/images/home/compare-btn.png" alt="" />
  85. </div>
  86. <!-- 作物档案 -->
  87. <div class="file-wrap map-file" id="popup-file">
  88. <div class="file-title">
  89. <img src="@/assets/images/common/chart-yellow.png" alt="" />
  90. 作物档案
  91. <span id="tag-nh" class="tag">小农户</span>
  92. </div>
  93. <div class="overview-file">
  94. <div class="box-title">总体档案</div>
  95. <div class="base-data" id="file-overview">
  96. </div>
  97. <div class="list" id="file-text">
  98. <div class="list-item" v-for="item in photoList" :key="item.key">
  99. <div class="list-name">
  100. <img src="@/assets/images/common/title-icon.png" alt="" />
  101. {{ item.key }}
  102. </div>
  103. {{ item.statement }}
  104. </div>
  105. </div>
  106. </div>
  107. <div class="overview-file">
  108. <div class="box-title">产量信息</div>
  109. <div class="box-wrap" id="file-output">
  110. <div class="box-item">
  111. <div class="item-name"></div>
  112. <div class="item-val"></div>
  113. </div>
  114. </div>
  115. </div>
  116. <div class="overview-file">
  117. <div class="box-title">生态评估</div>
  118. <div class="box-wrap" id="file-quality">
  119. <div class="box-item">
  120. <div class="item-name"></div>
  121. <div class="item-val"></div>
  122. </div>
  123. </div>
  124. </div>
  125. </div>
  126. <FarmFightTask class="farm-fight-task" :farmId="currentFarm.id"></FarmFightTask>
  127. </template>
  128. <script setup>
  129. import { onMounted, onUnmounted, ref } from "vue";
  130. import config from "@/api/config.js";
  131. import timeLine from "@/components/timeLine.vue";
  132. import PicturePreview from "@/components/PicturePreview.vue";
  133. import fnHeader from "@/components/fnHeader.vue";
  134. import navigation from "@/components/navigation.vue";
  135. import chartBox from "@/components/chartBox.vue";
  136. import toolList from "@/components/toolList.vue";
  137. import fileBar from "@/components/fileBar.vue";
  138. import HomeMap from "./map/homeMap";
  139. import homePage from "./components/homePage.vue";
  140. import weatherPage from "./components/weatherPage.vue";
  141. import phenologyPage from "./components/phenologyPage.vue";
  142. import indicatorChart from "./components/indicatorChart.vue";
  143. import homeFile from "./components/homeFile.vue";
  144. import { useRouter } from "vue-router";
  145. import SamplePointLayer from "./map/samplePointLayer";
  146. import { useStore } from "vuex";
  147. import RegionLayer from "./map/regionLayer";
  148. import BlueRegionLayer from "./map/blueRegionLayer";
  149. import eventBus from "@/api/eventBus";
  150. import AlbumCarousel from "./album_compoents/albumCarousel.vue";
  151. import compareDialog from "./album_compoents/compareDialog.vue";
  152. import album from "./album/index.vue";
  153. import PdfDialog from "../../components/PdfDialog";
  154. import StaticMapLayers from "@/components/static_map_change/Layers.js"
  155. import FarmFightTask from "./components/farmFightTask";
  156. import leftFly from "./components/leftComponents/leftFly.vue";
  157. import leftWeather from "./components/leftComponents/leftWeather.vue";
  158. import leftStation from "./components/leftComponents/leftStation.vue";
  159. const activeBtn = ref(0)
  160. const leftTool = ref(null)
  161. function changeLeftComponent(i) {
  162. activeBtn.value = i
  163. handleActiveLeft(leftToolList[i][0])
  164. // if(i){
  165. // isDisable.value = false
  166. // }else{
  167. // isDisable.value = true
  168. // }
  169. leftTool.value.resetActive(0)
  170. }
  171. const rightTool = ref(null)
  172. const activeRightBtn = ref(0)
  173. function changeRightComponent(i) {
  174. activeRightBtn.value = i
  175. handleActiveRight(rightToolList[i][0])
  176. rightTool.value.resetActive(0)
  177. }
  178. let store = useStore();
  179. const components = {
  180. leftFly,
  181. leftWeather,
  182. leftStation,
  183. homePage,
  184. weatherPage,
  185. phenologyPage,
  186. };
  187. //当前农场
  188. const currentFarm = {
  189. id: sessionStorage.getItem("farmId"),
  190. name: store.getters.userinfo.curFarmName,
  191. };
  192. //当前区域
  193. const currentRegion = {
  194. id: null,
  195. name: null,
  196. };
  197. let homeMap = new HomeMap();
  198. let staticMapLayers = null;
  199. let samplePointLayer = null;
  200. let regionLayer = null;
  201. let blueRegionLayer = null;
  202. const router = useRouter();
  203. const mapRef = ref();
  204. onMounted(() => {
  205. homeMap.initMap("POINT(113.61448114737868 23.585550924763083)", mapRef.value);
  206. // homeMap.initMap(store.getters.userinfo.location, mapRef.value);
  207. // regionLayer = new RegionLayer(homeMap.kmap.map, currentFarm, currentRegion)
  208. samplePointLayer = new SamplePointLayer(homeMap.kmap);
  209. VE_API.warning.fetchWarningLayer({
  210. k: "gspgjdfbt",
  211. resultType: "json",
  212. }).then(({data}) => {
  213. staticMapLayers = new StaticMapLayers(homeMap.kmap, data)
  214. eventBus.on("showGspgjdfbt",function(v){
  215. if(v){
  216. staticMapLayers.showSingle("聚类结果3", true)
  217. }else{
  218. staticMapLayers.hideAll()
  219. }
  220. })
  221. })
  222. blueRegionLayer = new BlueRegionLayer(homeMap.kmap);
  223. function changeStaticMapLayers(e){
  224. // staticMapLayers.
  225. }
  226. getYellow();
  227. // getFarmLog()
  228. //区域切换监听事件
  229. eventBus.on("area:id", areaId);
  230. //选项卡子项事件监听
  231. // eventBus.on("handleTabItem", handleTabItem);
  232. // 是否开启指标对比
  233. eventBus.on("compareTree", handleCompare)
  234. eventBus.on("clickToCompare:point", toggleCompare);
  235. });
  236. onUnmounted(() => {
  237. eventBus.off("area:id", areaId);
  238. // eventBus.off("handleTabItem", handleTabItem);
  239. eventBus.off("compareTree", handleCompare)
  240. eventBus.off("clickToCompare:point", toggleCompare);
  241. });
  242. function handleCompare(v) {
  243. isShrink.value = v
  244. if (v === false) {
  245. showCompareBtn.value = v
  246. }
  247. }
  248. const blueList = ref([]);
  249. const getBlueRegionList = (callback) => {
  250. if(!organId.value){
  251. return;
  252. }
  253. let selectAll = undefined;
  254. if (regionId.value === 0) {
  255. selectAll = 1;
  256. }
  257. const areaId = selectAll ? undefined : regionId.value;
  258. VE_API.farm.blueRegionList({ farmId: organId.value, regionId: areaId, selectAll }).then(({ data }) => {
  259. blueList.value = data.map((item) => {
  260. let color = "rgba(255, 255, 255, 0.5)"; //失效区域
  261. if (item.status === 2) {
  262. //物候期风险
  263. // color = "rgba(63, 255, 53, 0.5)";
  264. color = "#2BFE00";
  265. }
  266. if (item.status === 3) {
  267. //生长异常
  268. // color = "rgba(255, 252, 61, 0.5)";
  269. color = "#FF7410";
  270. }
  271. if (item.status === 4) {
  272. //病虫害
  273. // color = "rgba(255, 73, 73, 0.5)";
  274. color = "#F82121";
  275. }
  276. return {
  277. ...item,
  278. color,
  279. };
  280. });
  281. blueRegionLayer.initData(blueList.value);
  282. callback && callback();
  283. });
  284. };
  285. // 图例
  286. const legendArr = ref([])
  287. const organId = ref(null);
  288. const regionId = ref(null);
  289. const tabName = ref("");
  290. const tabId = ref(0);
  291. eventBus.off("changePointLegend", toggleLegend)
  292. eventBus.on("changePointLegend", toggleLegend)
  293. function toggleLegend({colorObj}) {
  294. legendArr.value = colorObj?.list
  295. }
  296. //选项卡事件监听
  297. const handleTab = async ({ name, id, isUpdate, params, legend, colorObj }) => {
  298. eventBus.emit("changePointType", {legend, colorObj})
  299. legendArr.value = colorObj?.list
  300. console.log('name, id, isUpdate, params', name, id, isUpdate, params, legend, colorObj);
  301. tabName.value = name;
  302. tabId.value = id;
  303. if (id === 0) {
  304. getBlueRegionList(() => {
  305. if (isUpdate) {
  306. handleTabItem(params);
  307. }
  308. });
  309. } else {
  310. getFarmIndexReport(() => {
  311. if (isUpdate) {
  312. handleTabItem(params);
  313. }
  314. });
  315. }
  316. // 切换点位数据
  317. // samplePointLayer.changePointType(name, params)
  318. };
  319. //区域切换监听事件
  320. function areaId({ areaId, farmId }) {
  321. organId.value = farmId;
  322. regionId.value = areaId;
  323. samplePointLayer.initData(farmId, areaId);
  324. if (tabId.value === 0) {
  325. getBlueRegionList();
  326. } else {
  327. getFarmIndexReport();
  328. }
  329. }
  330. //选项卡子项事件监听
  331. const handleTabItem = (e) => {
  332. // if (reportData.value.blueZoneList) {
  333. // const index = reportData.value.blueZoneList.findIndex((item) => item.key === e);
  334. // let arr = [];
  335. // if (reportData.value.blueZoneList.length) {
  336. // arr = blueListConvert(reportData.value.blueZoneList[index].obj, index);
  337. // }
  338. // blueRegionLayer.initData(arr, "87");
  339. // }
  340. };
  341. const reportData = ref({});
  342. const blueListConvert = (data, index) => {
  343. const list = [];
  344. for (let key in data) {
  345. const filterData = reportData.value.blueZoneLegendList[index].list.filter((item) => item.val === key);
  346. const arr = data[key];
  347. arr.forEach((item) => {
  348. const listObj = blueList.value.filter((ele) => ele.blueZoneCode === item);
  349. const updateList = listObj.map((ele) => {
  350. return {
  351. ...ele,
  352. level: key,
  353. name: filterData[0].name,
  354. color: filterData[0].color,
  355. };
  356. });
  357. list.push(...updateList);
  358. });
  359. }
  360. return list;
  361. };
  362. const getFarmIndexReport = (callback) => {
  363. // const params = { farmId:organId.value,regionId:regionId.value, type: tabName.value };
  364. // VE_API.farm.farmIndexReport(params).then(({data,code}) => {
  365. // if (code === 0) {
  366. // reportData.value = data || {};
  367. // let arr = []
  368. // if(data.blueZoneList.length){
  369. // arr = blueListConvert(data.blueZoneList[0].obj,0)
  370. // }
  371. // blueRegionLayer.initData(arr,'87')
  372. // callback && callback()
  373. // }
  374. // });
  375. };
  376. const indicatorChartData = ref({});
  377. const blueZone = ref("ws0y1meyhxp4");
  378. const getFarmLog = () => {
  379. console.log("getfarmlog");
  380. const params = {
  381. id: null,
  382. farmId: 766,
  383. blueZone: blueZone.value,
  384. };
  385. VE_API.warning.fetchFarmLog(params).then(({ data }) => {
  386. indicatorChartData.value = data || {};
  387. eventBus.emit("chart:updateOption", data);
  388. });
  389. };
  390. const urls = ref([]);
  391. const urlsIndex = ref(0);
  392. const getYellow = () => {
  393. VE_API.home.getYellowList().then((res) => {
  394. // urls.value = res.data.map(item =>{
  395. // return {
  396. // ...item,
  397. // imgPath:config.base_img_url2+item.cloudFilename
  398. // }
  399. // })
  400. // urls.value = [
  401. // "@/assets/images/home/HB-ws0y1menggxv/HB-ws0y1menggxv2025-01-07.jpg",
  402. // "@/assets/images/home/HB-ws0y1menggxv/HB-ws0y1menggxv2025-01-08.jpg",
  403. // "@/assets/images/home/HB-ws0y1menggxv/HB-ws0y1menggxv2025-01-09.jpg",
  404. // "@/assets/images/home/HB-ws0y1menggxv/HB-ws0y1menggxv2025-01-10.jpg",
  405. // "@/assets/images/home/HB-ws0y1menggxv/HB-ws0y1menggxv2025-01-11.jpg",
  406. // "@/assets/images/home/HB-ws0y1menggxv/HB-ws0y1menggxv2025-01-12.jpg",
  407. // "@/assets/images/home/HB-ws0y1menggxv/HB-ws0y1menggxv2025-01-13.jpg",
  408. // ]
  409. });
  410. };
  411. const btnIndex = ref(null);
  412. const btnName = ref("");
  413. const handleBtn = (e) => {
  414. btnName.value = "";
  415. btnIndex.value = e;
  416. eventBus.emit("clear:area");
  417. samplePointLayer.updateAreaStatus(e === 0 ? true : false);
  418. regionLayer.resetData();
  419. samplePointLayer.resetPoint();
  420. };
  421. //点击果园日志
  422. const handleSelectArea = () => {
  423. btnName.value = "";
  424. btnIndex.value = null;
  425. eventBus.emit("clear:area");
  426. regionLayer.resetData();
  427. samplePointLayer.resetPoint();
  428. samplePointLayer.updateAreaStatus(true);
  429. };
  430. //农事点击高亮
  431. const act = ref(null);
  432. const handleAct = (v) => {
  433. act.value = v;
  434. samplePointLayer.resetPoint();
  435. if (v === 1) {
  436. regionLayer.selectAreaMultiple([
  437. { value: 2, color: "blue" },
  438. { value: 4, color: "blue1" },
  439. { value: 5, color: "blue2" },
  440. { value: 7, color: "blue" },
  441. { value: 13, color: "blue2" },
  442. ]);
  443. }
  444. if (v === 2) {
  445. regionLayer.selectAreaMultiple([
  446. { value: 1, color: "blue" },
  447. { value: 2, color: "blue1" },
  448. { value: 9, color: "blue2" },
  449. { value: 12, color: "blue2" },
  450. ]);
  451. }
  452. };
  453. //柱状图点击事件监听
  454. eventBus.on("echart:barClick", (e) => {
  455. btnName.value = "";
  456. btnIndex.value = null;
  457. eventBus.emit("clear:area");
  458. samplePointLayer.updateAreaStatus(false);
  459. const arr = ["花穗伸长", "啃食虫害", "毛毡病"];
  460. const isDraw = arr.includes(e);
  461. const index = arr.indexOf(e);
  462. if (isDraw) {
  463. if (index === 0) {
  464. regionLayer.selectAreaMultiple([
  465. { value: 0, color: "green" },
  466. { value: 1, color: "green" },
  467. { value: 2, color: "green" },
  468. { value: 3, color: "green1" },
  469. { value: 4, color: "green1" },
  470. { value: 5, color: "green2" },
  471. { value: 6, color: "green1" },
  472. { value: 7, color: "green2" },
  473. { value: 8, color: "green2" },
  474. { value: 9, color: "green" },
  475. { value: 10, color: "green" },
  476. { value: 11, color: "green1" },
  477. { value: 12, color: "green2" },
  478. { value: 13, color: "green" },
  479. { value: 14, color: "green2" },
  480. ]);
  481. } else if (index === 1) {
  482. regionLayer.selectAreaMultiple([{ value: 6, color: "red" }]);
  483. } else {
  484. regionLayer.selectAreaMultiple([
  485. { value: 12, color: "red2" },
  486. { value: 10, color: "red" },
  487. { value: 1, color: "red" },
  488. ]);
  489. }
  490. }
  491. });
  492. //黄板点击事件监听
  493. eventBus.on("click:yellowBlock", (e) => {
  494. const arr = ["113.61396985128522", "113.61390710255375", "113.61491218688275"];
  495. if (arr[0] == e) {
  496. urls.value = ["HB-ws0y1menggxv"];
  497. urlsIndex.value = 0;
  498. }
  499. if (arr[1] == e) {
  500. urls.value = ["HB-ws0y1mg0pvd"];
  501. urlsIndex.value = 3;
  502. }
  503. if (arr[2] == e) {
  504. urls.value = ["HB-ws0y1mg9wpcp"];
  505. urlsIndex.value = 6;
  506. }
  507. eventBus.emit("dialog:show", true);
  508. });
  509. const showPoint = ref(true);
  510. const showType = ref("point");
  511. eventBus.on("click:updateArea", (e) => {
  512. blueZone.value = e.value;
  513. btnName.value = e.name;
  514. regionLayer.selectArea(e.name * 1 === 0 ? 0 : e.name * 1 - 1, "blue");
  515. //getFarmLog()
  516. });
  517. const currentComponent = ref("leftFly");
  518. const handleActiveLeft = (e) => {
  519. currentComponent.value = e.componentName;
  520. };
  521. const leftToolList = [[
  522. {
  523. title: "飞巡感知",
  524. componentName: "leftFly",
  525. },
  526. {
  527. title: "气象感知",
  528. componentName: "leftWeather"
  529. },
  530. {
  531. title: "人工感知",
  532. componentName: "phenologyPage",
  533. },
  534. {
  535. title: "站点感知",
  536. componentName: "leftStation",
  537. },
  538. ],
  539. [
  540. {
  541. title: "首页",
  542. name:'home',
  543. componentName: "homePage"
  544. },
  545. {
  546. title: "气象预警",
  547. componentName: "weatherPage"
  548. },
  549. {
  550. title: "物候调节",
  551. componentName: "phenologyPage"
  552. },
  553. {
  554. title: "病虫指标",
  555. componentName: "rightWeather"
  556. },
  557. {
  558. title: "营养评估",
  559. componentName: "rightWeather"
  560. },
  561. ]
  562. ];
  563. const rightIndex = ref(0);
  564. const handleActiveRight = ({ index }) => {
  565. rightIndex.value = index;
  566. btnIndex.value = null;
  567. btnName.value = "";
  568. samplePointLayer.updateAreaStatus(false);
  569. regionLayer.resetData();
  570. samplePointLayer.resetPoint();
  571. if (index !== 0) {
  572. act.value = null;
  573. }
  574. };
  575. const hanleRightIndex = (num) => {
  576. rightIndex.value = num;
  577. eventBus.emit("tool:updateAct", num);
  578. };
  579. const rightToolList = [[
  580. {
  581. title: "农事列表",
  582. componentName: "leftFly",
  583. index: 0,
  584. },
  585. {
  586. title: "认证评估",
  587. componentName: "leftFly",
  588. index: 1,
  589. },
  590. ],
  591. [
  592. {
  593. title: "无人机",
  594. componentName: "leftFly",
  595. index: 2,
  596. },
  597. {
  598. title: "农机设备",
  599. componentName: "leftFly",
  600. index: 2,
  601. },
  602. {
  603. title: "人工巡园",
  604. componentName: "leftFly",
  605. index: 2,
  606. },
  607. ]
  608. ];
  609. // 跳转果园档案
  610. const toFilePage = () => {
  611. router.push("/garden-file");
  612. };
  613. // 地图图例
  614. const showMapLegend = ref(true);
  615. const handleLegend = (e) => {
  616. blueRegionLayer.toggleLayer(e);
  617. };
  618. // 对比
  619. const compareData = ref([]);
  620. const showCompareBtn = ref(false);
  621. function toggleCompare(arr) {
  622. // eventBus.emit("clickToCompare:point",{farmId:fs.get("farmId"),sampleId:fs.get("sampleId"), data: fs.getProperties()})
  623. compareData.value = [];
  624. arr.map((fs) => {
  625. compareData.value.push({ farmId: fs.get("farmId"), sampleId: fs.get("id"), data: fs.getProperties() });
  626. });
  627. console.log("compareData", compareData.value);
  628. showCompareBtn.value = compareData.value.length > 1 ? true : false;
  629. }
  630. function showCompare() {
  631. eventBus.emit("showCompareDialog", compareData.value);
  632. }
  633. const isShrink = ref(false);
  634. const isLeftShrink = ref(false);
  635. const isRightShrink = ref(false);
  636. const handleShrink = (position) => {
  637. switch (position) {
  638. case "bottom":
  639. isShrink.value = !isShrink.value;
  640. break;
  641. case "left":
  642. isLeftShrink.value = !isLeftShrink.value;
  643. break;
  644. case "rigth":
  645. isRightShrink.value = !isRightShrink.value;
  646. break;
  647. }
  648. };
  649. const photoList = ref([
  650. {key: "病虫", statement: "病虫 2025年02月19日,发现毛毡病异常1级"},
  651. {key: "异常", statement: "2025年03月17日,发现花量大异常3级"},
  652. {key: "营养", statement: "无营养异常"},
  653. ]);
  654. </script>
  655. <style lang="scss" scoped>
  656. .base-container {
  657. width: 100%;
  658. height: 100vh;
  659. color: #fff;
  660. position: absolute;
  661. box-sizing: border-box;
  662. z-index: 1;
  663. .content {
  664. width: 100%;
  665. height: calc(100% - 74px - 48px - 54px);
  666. display: flex;
  667. justify-content: space-between;
  668. box-sizing: border-box;
  669. margin-top: 60px;
  670. .home-btn {
  671. position: absolute;
  672. top: -60px;
  673. left: 0;
  674. height: 54px;
  675. display: flex;
  676. border: 1px solid #444444;
  677. background: #101010;
  678. border-radius: 0 8px 8px 0;
  679. padding: 8px;
  680. box-sizing: border-box;
  681. width: 429px;
  682. .btn {
  683. flex: 1;
  684. background: rgba(79, 79, 79, 0.6);
  685. border-radius: 4px;
  686. font-size: 20px;
  687. font-family: "PangMenZhengDao";
  688. color: #fff;
  689. text-align: center;
  690. height: 38px;
  691. line-height: 38px;
  692. cursor: pointer;
  693. &.active {
  694. background: linear-gradient(180deg, #FFD887, #ED9E1E);
  695. color: #1D1D1D;
  696. }
  697. }
  698. .btn + .btn {
  699. margin-left: 8px;
  700. }
  701. }
  702. .left,
  703. .right {
  704. width: calc(376px + 54px);
  705. height: 100%;
  706. margin-top: 10px;
  707. box-sizing: border-box;
  708. display: flex;
  709. position: relative;
  710. transition: transform 0.3s;
  711. }
  712. .collapsed-left{
  713. transform: translateX(-430px);
  714. }
  715. .collapsed-right{
  716. transform: translateX(430px);
  717. }
  718. .arrow-left{
  719. transform: rotate(180deg);
  720. }
  721. .left {
  722. background: #101010;
  723. border-radius: 4px;
  724. border: 1px solid #444444;
  725. .arrow {
  726. position: absolute;
  727. right: -16px;
  728. top: calc(50% - 40px);
  729. background: #fff;
  730. width: 16px;
  731. height: 80px;
  732. line-height: 80px;
  733. border-radius: 0 5px 5px 0;
  734. text-align: center;
  735. cursor: pointer;
  736. transition: transform 0.3s;
  737. }
  738. }
  739. .right {
  740. width: calc(376px + 54px + 10px);
  741. .album-r {
  742. .list-wrap {
  743. width: 375px;
  744. }
  745. }
  746. .list {
  747. width: 100%;
  748. height: 100%;
  749. .btn-wrap {
  750. width: 100%;
  751. height: 25px;
  752. line-height: 25px;
  753. margin: 10px 0;
  754. display: flex;
  755. align-items: center;
  756. justify-content: space-between;
  757. div {
  758. width: 48%;
  759. height: 100%;
  760. color: #ffd489;
  761. border: 1px solid rgba(255, 213, 137, 0.6);
  762. border-radius: 2px;
  763. text-align: center;
  764. font-size: 12px;
  765. cursor: pointer;
  766. &.active {
  767. background: #ffd489;
  768. color: #000;
  769. }
  770. }
  771. }
  772. .img-box {
  773. width: 100%;
  774. height: calc(100% - 35px);
  775. overflow: auto;
  776. }
  777. .img-box1 {
  778. width: 100%;
  779. height: calc(100% - 10px);
  780. overflow: auto;
  781. margin-top: 10px;
  782. }
  783. .img-box2 {
  784. width: 100%;
  785. height: calc(100% - 45px);
  786. overflow: auto;
  787. margin-top: 10px;
  788. }
  789. img {
  790. width: 100%;
  791. height: auto;
  792. object-fit: cover;
  793. margin-bottom: 12px;
  794. cursor: pointer;
  795. }
  796. .mt {
  797. margin-top: -12px;
  798. }
  799. .list-wrap {
  800. ::v-deep {
  801. .chart-content {
  802. padding: 16px 0 0 0;
  803. }
  804. }
  805. }
  806. }
  807. }
  808. .overflow {
  809. overflow: auto;
  810. }
  811. .home-bottom {
  812. display: flex;
  813. align-items: flex-end;
  814. width: calc(100% - 20px - 430px * 2);
  815. height: 152px;
  816. align-self: flex-end;
  817. justify-content: center;
  818. .img{
  819. width: 268px;
  820. height: 66px;
  821. cursor: pointer;
  822. }
  823. .time-wrap {
  824. height: 85px;
  825. }
  826. .fly-icon {
  827. width: 148px;
  828. height: 100%;
  829. margin-left: 27px;
  830. }
  831. .log-box {
  832. height: 34%;
  833. width: calc(100% - 340px - 28px);
  834. margin-right: 28px;
  835. .box-name {
  836. width: 89px;
  837. height: 22px;
  838. text-align: center;
  839. line-height: 22px;
  840. border-radius: 20px;
  841. margin: 10px 0 5px 6px;
  842. cursor: pointer;
  843. background: linear-gradient(0deg, #bba269 0%, #3d3523 100%);
  844. }
  845. .log-content {
  846. font-size: 12px;
  847. line-height: 1.5;
  848. padding: 0 18px;
  849. }
  850. .chart-wrap {
  851. width: 100%;
  852. height: calc(100% - 50px);
  853. .line {
  854. margin-top: 10px;
  855. margin-bottom: 12px;
  856. }
  857. img {
  858. width: 100%;
  859. margin-bottom: 10px;
  860. }
  861. }
  862. }
  863. .garden-file {
  864. position: relative;
  865. top: 10px;
  866. // height: 30%;
  867. // min-height: 210px;
  868. // width: 640px;
  869. transition: all 0.3s;
  870. // width: 800px;
  871. // height: 320px;
  872. width: 100vw;
  873. height: 100vh;
  874. overflow: hidden;
  875. &.isShrink {
  876. height: 66px;
  877. width: 450px;
  878. overflow: hidden;
  879. .arrow {
  880. .icon {
  881. transform: rotate(90deg);
  882. }
  883. }
  884. }
  885. .arrow {
  886. position: absolute;
  887. right: 56px;
  888. top: 36px;
  889. background: #fff;
  890. height: 16px;
  891. width: 80px;
  892. line-height: 16px;
  893. border-radius: 0 0 5px 5px;
  894. text-align: center;
  895. cursor: pointer;
  896. .icon {
  897. transform: rotate(270deg);
  898. }
  899. }
  900. }
  901. .file-box {
  902. height: 25%;
  903. min-height: 210px;
  904. width: 340px;
  905. position: relative;
  906. img {
  907. width: 100%;
  908. margin-top: 12px;
  909. }
  910. .arrow-icon {
  911. top: -32px;
  912. left: 50%;
  913. position: absolute;
  914. background: #fff;
  915. width: 16px;
  916. height: 80px;
  917. line-height: 80px;
  918. border-radius: 5px 0 0 5px;
  919. text-align: center;
  920. transform: translateX(-50%) rotate(270deg);
  921. }
  922. .edit-btn {
  923. padding: 2px 24px;
  924. background: #ffd489;
  925. border-radius: 4px;
  926. color: #000;
  927. }
  928. }
  929. }
  930. .legend {
  931. position: fixed;
  932. bottom: 8px;
  933. right: 64px;
  934. // width: 525px;
  935. height: 20px;
  936. }
  937. .map-bg {
  938. position: fixed;
  939. z-index: 2;
  940. background: rgba(35, 35, 35, 0.8);
  941. border-radius: 18px;
  942. padding: 7px 16px;
  943. right: 460px;
  944. }
  945. .map-btn {
  946. top: 19px;
  947. cursor: pointer;
  948. }
  949. .map-legend {
  950. bottom: 34px;
  951. .item {
  952. display: flex;
  953. align-items: center;
  954. font-size: 14px;
  955. img {
  956. width: 16px;
  957. margin-right: 6px;
  958. }
  959. .legend-block {
  960. width: 16px;
  961. height: 16px;
  962. box-sizing: border-box;
  963. border-radius: 50%;
  964. border: 2px solid #fff;
  965. margin-right: 6px;
  966. }
  967. }
  968. .legend-title {
  969. border-bottom: 1px solid rgba(102, 102, 102, 0.35);
  970. }
  971. .item + .item {
  972. padding-top: 10px;
  973. }
  974. }
  975. }
  976. }
  977. .bottom-map {
  978. width: 100%;
  979. height: 100vh;
  980. position: absolute;
  981. z-index: 0;
  982. }
  983. .compare-start-btn {
  984. position: absolute;
  985. z-index: 2;
  986. left: 50%;
  987. transform: translateX(-50%);
  988. cursor: pointer;
  989. bottom: 106px;
  990. // right: 445px;
  991. img {
  992. height: 55px;
  993. }
  994. }
  995. </style>
  996. <style lang="less">
  997. .file-wrap {
  998. &.map-file {
  999. width: 367px;
  1000. position: relative;
  1001. background: url("@/assets/images/home/file-bg.png") no-repeat top center / 100% 100%;
  1002. margin-left: 12px;
  1003. padding: 12px;
  1004. .file-title {
  1005. font-size: 20px;
  1006. color: #ffd489;
  1007. .tag {
  1008. border: 1px solid #FFD489;
  1009. border-radius: 4px;
  1010. font-size: 12px;
  1011. display: inline-block;
  1012. width: 44px;
  1013. height: 20px;
  1014. text-align: center;
  1015. line-height: 18px;
  1016. margin-left: 8px;
  1017. padding: 1px 4px;
  1018. }
  1019. }
  1020. .overview-file {
  1021. padding-top: 20px;
  1022. .box-title {
  1023. font-size: 16px;
  1024. padding-left: 13px;
  1025. margin-bottom: 16px;
  1026. position: relative;
  1027. display: flex;
  1028. justify-content: space-between;
  1029. color: #fff;
  1030. &::before {
  1031. content: "";
  1032. position: absolute;
  1033. left: 0;
  1034. top: 3px;
  1035. width: 3px;
  1036. height: 16px;
  1037. background: #fff;
  1038. border-radius: 11px;
  1039. }
  1040. }
  1041. .title {
  1042. color: #f3c11d;
  1043. font-size: 16px;
  1044. font-family: "PangMenZhengDao";
  1045. margin-bottom: 20px;
  1046. .big {
  1047. width: 13px;
  1048. height: 13px;
  1049. margin: -10px 0 0 4px;
  1050. }
  1051. .small {
  1052. width: 7px;
  1053. height: 7px;
  1054. margin-left: -3px;
  1055. }
  1056. }
  1057. .base-data {
  1058. background: rgba(207, 207, 207, 0.1);
  1059. border-radius: 4px;
  1060. padding: 6px 0;
  1061. display: flex;
  1062. .base-item {
  1063. flex: 1;
  1064. text-align: center;
  1065. .label {
  1066. font-size: 12px;
  1067. color: #666666;
  1068. }
  1069. .value {
  1070. padding-top: 2px;
  1071. font-size: 16px;
  1072. color: #ffffff;
  1073. }
  1074. }
  1075. .base-item + .base-item {
  1076. border-left: 1px solid rgba(102, 102, 102, 0.42);
  1077. }
  1078. }
  1079. .list {
  1080. margin-top: 15px;
  1081. width: max-content;
  1082. font-size: 14px;
  1083. .list-item {
  1084. color: #bbbbbb;
  1085. display: flex;
  1086. margin-bottom: 8px;
  1087. .list-name {
  1088. color: #f3c11d;
  1089. margin-right: 6px;
  1090. img {
  1091. width: 17px;
  1092. height: 13px;
  1093. }
  1094. }
  1095. }
  1096. }
  1097. }
  1098. .overview-file + .overview-file {
  1099. margin-top: 8px;
  1100. }
  1101. .box-wrap {
  1102. display: flex;
  1103. .box-item {
  1104. // flex: 1;
  1105. min-width: 109px;
  1106. display: flex;
  1107. flex-direction: column;
  1108. justify-content: center;
  1109. align-items: center;
  1110. padding: 6px;
  1111. box-sizing: border-box;
  1112. background: rgba(207, 207, 207, 0.1);
  1113. border-radius: 4px;
  1114. border: 1px solid rgba(207, 207, 207, 0.1);
  1115. cursor: pointer;
  1116. .item-name {
  1117. font-size: 12px;
  1118. color: #666666;
  1119. width: max-content;
  1120. }
  1121. .item-val {
  1122. font-size: 18px;
  1123. color: #fff;
  1124. width: max-content;
  1125. padding-top: 3px;
  1126. }
  1127. &.active {
  1128. background: rgba(255, 212, 137, 0.16);
  1129. border: 1px solid #ffd489;
  1130. .item-name {
  1131. color: #bbbbbb;
  1132. }
  1133. }
  1134. }
  1135. .box-item + .box-item {
  1136. margin-left: 8px;
  1137. }
  1138. }
  1139. }
  1140. }
  1141. .farm-fight-task{
  1142. position: fixed;
  1143. top: 100px;
  1144. left: 25%;
  1145. z-index: 1000;
  1146. }
  1147. </style>