index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. <template>
  2. <div class="base-container no-events">
  3. <fnHeader showDate></fnHeader>
  4. <div class="content">
  5. <navigation @handleTab="handleTab"></navigation>
  6. <div class="left yes-events">
  7. <component :is="components[currentComponent]" @backHome="backHome"/>
  8. </div>
  9. <div class="right yes-events">
  10. <div class="list adopt-list-wrap">
  11. <chart-box name="认养管理" arrow="">
  12. <el-tabs v-model="activeName" class="demo-tabs">
  13. <el-tab-pane label="认养列表" name="认养列表">
  14. <adopt-list></adopt-list>
  15. </el-tab-pane>
  16. <el-tab-pane label="客户列表" name="客户列表">
  17. <client-list></client-list>
  18. </el-tab-pane>
  19. <el-tab-pane label="认养申请" name="认养申请">
  20. <apply-list></apply-list>
  21. </el-tab-pane>
  22. <el-tab-pane label="确认地址" name="确认地址">
  23. <address-list></address-list>
  24. </el-tab-pane>
  25. </el-tabs>
  26. </chart-box>
  27. </div>
  28. </div>
  29. <!-- 图例 -->
  30. <div v-if="legendArr && legendArr.length" class="map-bg map-legend yes-events">
  31. <div class="item" v-for="(legend, legendI) in legendArr" :key="legendI">
  32. <span class="legend-block" :style="{background: legend.color}"></span>
  33. {{ legend.name }}
  34. </div>
  35. </div>
  36. <div v-else class="map-bg map-legend yes-events">
  37. <div class="item">
  38. <img src="@/assets/images/map/status/wry.png" alt="" />
  39. 未开放认养
  40. </div>
  41. <div class="item" v-show="!checkShow">
  42. <img src="@/assets/images/map/status/dry.png" alt="" />
  43. 待认养
  44. </div>
  45. <div class="item" v-show="!checkShow">
  46. <img src="@/assets/images/map/status/yry.png" alt="" />
  47. 已认养
  48. </div>
  49. <div class="item selected-item" v-show="checkShow">
  50. <img src="@/assets/images/map/status/selected.png" alt="" />
  51. 已选择
  52. </div>
  53. </div>
  54. <div class="tips" v-show="checkShow">
  55. <div class="text">
  56. <span>提示:</span>请在底图上点选 <span>认养的果树</span>,或按住 Ctrl 框选 <span>认养的区域</span>
  57. </div>
  58. </div>
  59. <div v-show="!checkShow" class="right-button yes-events" @click="hanldeCheck">勾选认养区域</div>
  60. <div v-show="checkShow" class="center-button">
  61. <div class="cancel yes-events" @click="handleCancel">取消</div>
  62. <div class="yes-events" @click="handleCancel">确认开放认养权限</div>
  63. </div>
  64. </div>
  65. </div>
  66. <custom-map class="bottom-map" ref="mapRef"></custom-map>
  67. <!-- 图片弹窗 -->
  68. <PicturePreview :imageUrl="urls" :curIndex="urlsIndex"></PicturePreview>
  69. <album-carousel></album-carousel>
  70. <PdfDialog title="果园报告"></PdfDialog>
  71. </template>
  72. <script setup>
  73. import { nextTick, onMounted, onUnmounted, ref } from "vue";
  74. import config from "@/api/config.js";
  75. import timeLine from "@/components/timeLine.vue";
  76. import PicturePreview from "@/components/PicturePreview.vue";
  77. import fnHeader from "@/components/fnHeader.vue";
  78. import navigation from "@/components/navigation.vue";
  79. import chartBox from "@/components/chartBox.vue";
  80. import homePage from "./components/homePage.vue";
  81. import treeDetail from "./components/treeDetail.vue";
  82. import adoptList from "./components/adoptList.vue";
  83. import clientList from "./components/clientList.vue";
  84. import customMap from "./homeMap.vue";
  85. import applyList from "./components/applyList.vue";
  86. import addressList from "./components/addressList.vue";
  87. import { convertPointToArray } from "@/utils/index";
  88. import { useRouter } from "vue-router";
  89. import { useStore } from "vuex";
  90. import eventBus from "@/api/eventBus";
  91. import AlbumCarousel from "./album_compoents/albumCarousel.vue";
  92. import PdfDialog from "../../components/PdfDialog";
  93. let store = useStore();
  94. const components = {
  95. homePage,
  96. treeDetail,
  97. };
  98. const router = useRouter();
  99. const mapRef = ref(null);
  100. const activeName = ref('认养列表')
  101. // 用户角色
  102. store.commit("home/SET_USER_ROLE", 2);
  103. onMounted(() => {
  104. //区域切换监听事件
  105. eventBus.on("area:id", areaId);
  106. });
  107. onUnmounted(() => {
  108. eventBus.off("area:id", areaId);
  109. });
  110. const getPointList = () =>{
  111. VE_API.variety.pointList({ farmId:organId.value, selectAll:1 }).then(({ data }) => {
  112. // const arr = data.map(item =>{
  113. // return{
  114. // ...item,
  115. // color: item.fosterStatus === 0 ? "transprent" : (item.fosterStatus === 1 ? "#EEEEEE" : (item.fosterStatus === 2 ? "#F0AC37" : "transprent")),
  116. // lnglat:convertPointToArray(item.point)
  117. // }
  118. // })
  119. if(mapRef.value){
  120. nextTick(() => {
  121. data[0].icon = "123"
  122. data[1].icon = "123"
  123. data[100].icon = "123"
  124. data[170].icon = "123"
  125. data[190].icon = "123"
  126. data[10].icon = "123"
  127. data[20].icon = "123"
  128. data[30].icon = "123"
  129. mapRef.value.addCluster(data)
  130. // mapRef.value.initData(arr)
  131. // mapRef.value.initMap(arr, () => mapRef.value.getRegionList(organId.value))
  132. })
  133. }
  134. })
  135. }
  136. function getBlueRegionList() {
  137. VE_API.region.list({farmId: organId.value}).then(({data}) =>{
  138. mapRef.value.initAreaMap(data);
  139. })
  140. }
  141. const checkShow = ref(false)
  142. const hanldeCheck = () =>{
  143. checkShow.value = true
  144. mapRef.value.enableBoxSelect()
  145. }
  146. const handleCancel = () =>{
  147. checkShow.value = false
  148. // mapRef.value.clearSelection()
  149. mapRef.value.stopBoxSelect()
  150. }
  151. // 图例
  152. const legendArr = ref([])
  153. const organId = ref("");
  154. const regionId = ref(null);
  155. const tabName = ref("");
  156. const tabId = ref(0);
  157. eventBus.off("changePointLegend", toggleLegend)
  158. eventBus.on("changePointLegend", toggleLegend)
  159. function toggleLegend({colorObj}) {
  160. legendArr.value = colorObj?.list
  161. }
  162. //选项卡事件监听
  163. const handleTab = async ({ name, id, isUpdate, params, legend, colorObj }) => {
  164. eventBus.emit("changePointType", {legend, colorObj})
  165. legendArr.value = colorObj?.list
  166. tabName.value = name;
  167. tabId.value = id;
  168. // if (id === 0) {
  169. // }
  170. };
  171. //区域切换监听事件
  172. function areaId({ areaId, farmId }) {
  173. organId.value = farmId;
  174. regionId.value = areaId;
  175. // 树点位
  176. getPointList()
  177. // 分区
  178. getBlueRegionList();
  179. }
  180. const urls = ref([]);
  181. const urlsIndex = ref(0);
  182. const currentComponent = ref("homePage");
  183. eventBus.on("clickMapPoint", toggleLeftComponet)
  184. function toggleLeftComponet() {
  185. currentComponent.value = "treeDetail"
  186. }
  187. function backHome() {
  188. console.log('home');
  189. currentComponent.value = "homePage"
  190. }
  191. </script>
  192. <style lang="scss" scoped>
  193. .base-container {
  194. width: 100%;
  195. height: 100vh;
  196. color: #fff;
  197. position: absolute;
  198. box-sizing: border-box;
  199. z-index: 1;
  200. .content {
  201. width: 100%;
  202. height: calc(100% - 74px - 48px);
  203. display: flex;
  204. justify-content: space-between;
  205. box-sizing: border-box;
  206. .left,
  207. .right {
  208. width: 376px;
  209. height: 100%;
  210. margin-top: 10px;
  211. box-sizing: border-box;
  212. display: flex;
  213. position: relative;
  214. }
  215. .left {
  216. background: #101010;
  217. border-radius: 4px;
  218. border: 1px solid #444444;
  219. margin-left: 25px;
  220. .arrow {
  221. position: absolute;
  222. right: -16px;
  223. top: calc(50% - 40px);
  224. background: #fff;
  225. width: 16px;
  226. height: 80px;
  227. line-height: 80px;
  228. border-radius: 0 5px 5px 0;
  229. text-align: center;
  230. cursor: pointer;
  231. }
  232. }
  233. .right {
  234. width: 376px;
  235. margin-right: 25px;
  236. .adopt-list-wrap {
  237. ::v-deep {
  238. .el-tabs {
  239. height: 100%;
  240. }
  241. .el-tabs__content {
  242. height: calc(100% - 40px - 15px);
  243. position: static;
  244. }
  245. .el-tabs__item {
  246. color: #727272;
  247. }
  248. .el-tabs__active-bar {
  249. background-color: #FFFFFF;
  250. height: 1px;
  251. }
  252. .el-tabs__item.is-active {
  253. color: #fff;
  254. }
  255. .el-tabs__nav-wrap:after {
  256. height: 1px;
  257. background-color: rgba(127, 127, 127, 0.3);
  258. }
  259. .el-tabs__nav {
  260. left: 50%;
  261. transform: translateX(-50%) !important;
  262. }
  263. .el-tab-pane {
  264. height: 100%;
  265. }
  266. }
  267. }
  268. .list {
  269. width: 100%;
  270. height: 100%;
  271. overflow: auto;
  272. .btn-wrap {
  273. width: 100%;
  274. height: 25px;
  275. line-height: 25px;
  276. margin: 10px 0;
  277. display: flex;
  278. align-items: center;
  279. justify-content: space-between;
  280. div {
  281. width: 48%;
  282. height: 100%;
  283. color: #ffd489;
  284. border: 1px solid rgba(255, 213, 137, 0.6);
  285. border-radius: 2px;
  286. text-align: center;
  287. font-size: 12px;
  288. cursor: pointer;
  289. &.active {
  290. background: #ffd489;
  291. color: #000;
  292. }
  293. }
  294. }
  295. .img-box {
  296. width: 100%;
  297. height: calc(100% - 35px);
  298. overflow: auto;
  299. }
  300. .img-box1 {
  301. width: 100%;
  302. height: calc(100% - 10px);
  303. overflow: auto;
  304. margin-top: 10px;
  305. }
  306. .img-box2 {
  307. width: 100%;
  308. height: calc(100% - 45px);
  309. overflow: auto;
  310. margin-top: 10px;
  311. }
  312. img {
  313. width: 100%;
  314. height: auto;
  315. object-fit: cover;
  316. margin-bottom: 12px;
  317. cursor: pointer;
  318. }
  319. .mt {
  320. margin-top: -12px;
  321. }
  322. }
  323. }
  324. .overflow {
  325. overflow: auto;
  326. }
  327. .legend {
  328. position: fixed;
  329. bottom: 8px;
  330. right: 64px;
  331. height: 20px;
  332. }
  333. .map-bg {
  334. position: fixed;
  335. z-index: 2;
  336. background: rgba(35, 35, 35, 0.8);
  337. border-radius: 18px;
  338. padding: 7px 16px;
  339. left: 460px;
  340. }
  341. .tips{
  342. position: fixed;
  343. z-index: 2;
  344. top: 105px;
  345. width: 100%;
  346. display: flex;
  347. justify-content: center;
  348. .text{
  349. font-size: 20px;
  350. padding: 6px 16px;
  351. font-family: "PangMenZhengDao";
  352. background: rgba(4, 3, 0, 0.6);
  353. border-radius: 20px;
  354. span{
  355. color: #FFD489;
  356. }
  357. }
  358. }
  359. .right-button{
  360. position: fixed;
  361. z-index: 2;
  362. right: 460px;
  363. bottom: 36px;
  364. font-size: 24px;
  365. font-family: "PangMenZhengDao";
  366. padding: 16px 32px 20px 32px;
  367. cursor: pointer;
  368. background: url('@/assets/images/foster-home/btn-bg.png') no-repeat center center /100% 100%;
  369. }
  370. .center-button{
  371. position: fixed;
  372. z-index: 2;
  373. width: 100%;
  374. display: flex;
  375. align-items: center;
  376. justify-content: center;
  377. bottom: 116px;
  378. div{
  379. cursor: pointer;
  380. width: 248px;
  381. text-align: center;
  382. padding: 15px;
  383. font-family: "PangMenZhengDao";
  384. color: #000;
  385. font-size: 20px;
  386. background: linear-gradient(0deg,#FFD887,#ED9E1E);
  387. border: 2px solid rgba(255, 255, 255, 0.61);
  388. border-radius: 12px;
  389. }
  390. .cancel{
  391. margin-right: 20px;
  392. background: #EEEEEE;
  393. }
  394. }
  395. .map-btn {
  396. top: 19px;
  397. cursor: pointer;
  398. }
  399. .map-legend {
  400. bottom: 36px;
  401. display: flex;
  402. align-items: center;
  403. .item {
  404. display: flex;
  405. align-items: center;
  406. font-size: 14px;
  407. img {
  408. width: 16px;
  409. margin-right: 6px;
  410. }
  411. .legend-block {
  412. width: 16px;
  413. height: 16px;
  414. box-sizing: border-box;
  415. border-radius: 50%;
  416. border: 2px solid #fff;
  417. margin-right: 6px;
  418. }
  419. }
  420. .selected-item {
  421. img {
  422. width: 24px;
  423. }
  424. }
  425. .legend-title {
  426. border-bottom: 1px solid rgba(102, 102, 102, 0.35);
  427. }
  428. .item + .item {
  429. padding-left: 12px;
  430. }
  431. }
  432. }
  433. }
  434. .bottom-map {
  435. width: 100%;
  436. height: 100vh;
  437. position: absolute;
  438. z-index: 0;
  439. }
  440. .compare-start-btn {
  441. position: absolute;
  442. z-index: 2;
  443. left: 50%;
  444. transform: translateX(-50%);
  445. cursor: pointer;
  446. bottom: 106px;
  447. // right: 445px;
  448. img {
  449. height: 55px;
  450. }
  451. }
  452. </style>
  453. <style lang="less">
  454. .file-wrap {
  455. &.map-file {
  456. width: 367px;
  457. position: relative;
  458. background: url("@/assets/images/home/file-bg.png") no-repeat top center / 100% 100%;
  459. margin-left: 12px;
  460. padding: 12px;
  461. .file-title {
  462. font-size: 20px;
  463. color: #ffd489;
  464. .tag {
  465. border: 1px solid #FFD489;
  466. border-radius: 4px;
  467. font-size: 12px;
  468. display: inline-block;
  469. width: 44px;
  470. height: 20px;
  471. text-align: center;
  472. line-height: 18px;
  473. margin-left: 8px;
  474. padding: 1px 4px;
  475. }
  476. }
  477. .overview-file {
  478. padding-top: 20px;
  479. .box-title {
  480. font-size: 16px;
  481. padding-left: 13px;
  482. margin-bottom: 16px;
  483. position: relative;
  484. display: flex;
  485. justify-content: space-between;
  486. color: #fff;
  487. &::before {
  488. content: "";
  489. position: absolute;
  490. left: 0;
  491. top: 3px;
  492. width: 3px;
  493. height: 16px;
  494. background: #fff;
  495. border-radius: 11px;
  496. }
  497. }
  498. .title {
  499. color: #f3c11d;
  500. font-size: 16px;
  501. font-family: "PangMenZhengDao";
  502. margin-bottom: 20px;
  503. .big {
  504. width: 13px;
  505. height: 13px;
  506. margin: -10px 0 0 4px;
  507. }
  508. .small {
  509. width: 7px;
  510. height: 7px;
  511. margin-left: -3px;
  512. }
  513. }
  514. .base-data {
  515. background: rgba(207, 207, 207, 0.1);
  516. border-radius: 4px;
  517. padding: 6px 0;
  518. display: flex;
  519. .base-item {
  520. flex: 1;
  521. text-align: center;
  522. .label {
  523. font-size: 12px;
  524. color: #666666;
  525. }
  526. .value {
  527. padding-top: 2px;
  528. font-size: 16px;
  529. color: #ffffff;
  530. }
  531. }
  532. .base-item + .base-item {
  533. border-left: 1px solid rgba(102, 102, 102, 0.42);
  534. }
  535. }
  536. .list {
  537. margin-top: 15px;
  538. width: max-content;
  539. font-size: 14px;
  540. .list-item {
  541. color: #bbbbbb;
  542. display: flex;
  543. margin-bottom: 8px;
  544. .list-name {
  545. color: #f3c11d;
  546. margin-right: 6px;
  547. img {
  548. width: 17px;
  549. height: 13px;
  550. }
  551. }
  552. }
  553. }
  554. }
  555. .overview-file + .overview-file {
  556. margin-top: 8px;
  557. }
  558. .box-wrap {
  559. display: flex;
  560. .box-item {
  561. // flex: 1;
  562. min-width: 109px;
  563. display: flex;
  564. flex-direction: column;
  565. justify-content: center;
  566. align-items: center;
  567. padding: 6px;
  568. box-sizing: border-box;
  569. background: rgba(207, 207, 207, 0.1);
  570. border-radius: 4px;
  571. border: 1px solid rgba(207, 207, 207, 0.1);
  572. cursor: pointer;
  573. .item-name {
  574. font-size: 12px;
  575. color: #666666;
  576. width: max-content;
  577. }
  578. .item-val {
  579. font-size: 18px;
  580. color: #fff;
  581. width: max-content;
  582. padding-top: 3px;
  583. }
  584. &.active {
  585. background: rgba(255, 212, 137, 0.16);
  586. border: 1px solid #ffd489;
  587. .item-name {
  588. color: #bbbbbb;
  589. }
  590. }
  591. }
  592. .box-item + .box-item {
  593. margin-left: 8px;
  594. }
  595. }
  596. }
  597. }
  598. </style>