LayerPopup.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <template>
  2. <u-popup
  3. v-model="layerVisible"
  4. @close="layerClose"
  5. :round="8"
  6. :closeOnClickOverlay="false"
  7. @open="layerOpen"
  8. mode="bottom"
  9. >
  10. <view class="layer-popup">
  11. <view class="layer-popup__header">
  12. <view class="layer-popup__close">
  13. <u-icon
  14. name="close"
  15. size="36rpx"
  16. color="#4e6961"
  17. @click="layerClose"
  18. ></u-icon>
  19. </view>
  20. <view class="layer-popup__title">图层</view>
  21. </view>
  22. <view class="layer-popup__content">
  23. <view class="layer-panel" v-for="item in layerList" :key="item.id">
  24. <view class="layer-panel__header">{{ item.title }}</view>
  25. <view class="layer-panel__content">
  26. <u-row gutter="0">
  27. <u-col
  28. span="6"
  29. style="padding:0;width:calc(50% - 10rpx);margin-right:10rpx;flex:auto"
  30. v-for="checkItem in item.children"
  31. :key="checkItem.id"
  32. >
  33. <view
  34. class="check-item"
  35. :class="{ active: checkItem.isActive }"
  36. @click="checkItem.isActive = !checkItem.isActive"
  37. >
  38. <text>{{ checkItem.title }}</text>
  39. <view class="check-item__icon">
  40. <image
  41. src="../../assets/checkedSelect.png"
  42. class="icon"
  43. v-if="checkItem.isActive"
  44. />
  45. <image
  46. src="../../assets/checkedDisabled.png"
  47. class="icon"
  48. v-else
  49. />
  50. </view>
  51. </view>
  52. </u-col>
  53. </u-row>
  54. </view>
  55. </view>
  56. <view class="layer-panel">
  57. <view class="layer-panel__header">地图</view>
  58. <view class="layer-panel__content">
  59. <u-row gutter="0" customStyle="flex-wrap: wrap">
  60. <u-col span="3" customStyle="margin-bottom: 16px">
  61. <view
  62. class="map-check-item"
  63. @click="handleToggleMap(0)"
  64. :class="{ active: currentMapIndex === 0 }"
  65. >
  66. <image
  67. src="../../assets/map-01.png"
  68. class="map-check-item__img"
  69. />
  70. <view class="map-check-item__text">电子地图</view>
  71. </view>
  72. </u-col>
  73. <u-col span="3" customStyle="margin-bottom: 16px">
  74. <view
  75. class="map-check-item"
  76. @click="handleToggleMap(1)"
  77. :class="{ active: currentMapIndex === 1 }"
  78. >
  79. <image
  80. src="../../assets/map-02.png"
  81. class="map-check-item__img"
  82. />
  83. <view class="map-check-item__text">卫星地图</view>
  84. </view>
  85. </u-col>
  86. </u-row>
  87. </view>
  88. </view>
  89. </view>
  90. <view class="layer-popup__footer">
  91. <u-button
  92. type="primary"
  93. size="normal"
  94. customStyle="border-radius:16rpx"
  95. @click="handleConfirm"
  96. class="submit"
  97. >
  98. 确定
  99. </u-button>
  100. </view>
  101. </view>
  102. </u-popup>
  103. </template>
  104. <script>
  105. import { map } from 'lodash-es';
  106. export default {
  107. name: 'LayerPopup',
  108. props: {
  109. visible: {
  110. type: Boolean,
  111. default: false
  112. }
  113. },
  114. data() {
  115. return {
  116. layerVisible: false,
  117. layerList: [
  118. {
  119. id: '1',
  120. title: '图层管理',
  121. children: [
  122. {
  123. id: '1-1',
  124. title: '设备',
  125. value: 'device',
  126. isActive: true
  127. },
  128. {
  129. id: '1-2',
  130. title: '地块',
  131. value: 'block',
  132. isActive: true
  133. },
  134. {
  135. id: '1-3',
  136. title: '基地',
  137. value: 'land',
  138. isActive: true
  139. },
  140. // {
  141. // id: '1-4',
  142. // title: '水源',
  143. // isActive: false
  144. // },
  145. {
  146. id: '1-5',
  147. title: '种植作物',
  148. value: 'crop',
  149. isActive: true
  150. }
  151. ]
  152. }
  153. ],
  154. currentMapIndex: 1
  155. };
  156. },
  157. watch: {
  158. visible(newVal) {
  159. if (newVal !== this.layerVisible) {
  160. this.layerVisible = newVal;
  161. }
  162. }
  163. },
  164. methods: {
  165. layerClose() {
  166. this.$emit('update:visible', false);
  167. this.$emit('close');
  168. },
  169. layerOpen() {
  170. this.$emit('layerOpen');
  171. },
  172. handleToggleMap(index) {
  173. this.currentMapIndex = index;
  174. },
  175. handleConfirm() {
  176. const selectedLayers = this.layerList.reduce((acc, layer) => {
  177. const selectedChildren = layer.children.filter(
  178. (child) => child.isActive
  179. );
  180. if (selectedChildren.length) {
  181. acc.push(...selectedChildren);
  182. }
  183. return acc;
  184. }, []);
  185. this.layerClose();
  186. this.$emit('confirm', {
  187. renderTypes: map(selectedLayers, 'value'),
  188. isSatellite: this.currentMapIndex === 1
  189. });
  190. }
  191. }
  192. };
  193. </script>
  194. <style lang="scss" scoped>
  195. .layer-popup {
  196. background-color: #fff;
  197. &__header {
  198. position: relative;
  199. height: 96rpx;
  200. color: #fff;
  201. border-bottom: 1rpx solid #e4e7ed;
  202. }
  203. &__title {
  204. text-align: center;
  205. font-size: 32rpx;
  206. line-height: 96rpx;
  207. color: #042118;
  208. }
  209. &__close {
  210. position: absolute;
  211. top: 0;
  212. right: 0;
  213. padding: 20rpx;
  214. color: #4e6961;
  215. }
  216. &__content {
  217. padding: 32rpx;
  218. background-color: #fff;
  219. }
  220. &__footer {
  221. display: flex;
  222. justify-content: center;
  223. padding: 16rpx 0rpx;
  224. background-color: #fff;
  225. box-shadow: 0 -2px 4px 0 #0000001a;
  226. }
  227. }
  228. .layer-panel {
  229. &__header {
  230. font-size: 32rpx;
  231. line-height: 46rpx;
  232. color: #042118;
  233. font-weight: 500;
  234. margin-bottom: 16rpx;
  235. }
  236. &__content {
  237. padding: 16rpx 0;
  238. }
  239. }
  240. .check-item {
  241. position: relative;
  242. display: flex;
  243. align-items: center;
  244. height: 70rpx;
  245. font-size: 32rpx;
  246. color: #042118;
  247. background: #f5f7fa;
  248. border-radius: 8rpx;
  249. padding: 4rpx 32rpx;
  250. margin:8rpx 0;
  251. border: 1rpx solid transparent;
  252. &.active {
  253. background: #fff;
  254. border-color: #14a478;
  255. }
  256. &__icon {
  257. position: absolute;
  258. right: 0;
  259. bottom: 0;
  260. width: 48rpx;
  261. height: 48rpx;
  262. .icon {
  263. width: 100%;
  264. height: 100%;
  265. }
  266. }
  267. }
  268. .map-check-item {
  269. position: relative;
  270. width: 136rpx;
  271. height: 126rpx;
  272. font-size: 32rpx;
  273. color: #fff;
  274. border-radius: 8rpx;
  275. border: 1rpx solid transparent;
  276. overflow: hidden;
  277. &.active {
  278. background: #fff;
  279. border-color: #14a478;
  280. .map-check-item__text {
  281. background-color: #14a478;
  282. }
  283. }
  284. &__img {
  285. width: 100%;
  286. height: 100%;
  287. }
  288. &__text {
  289. position: absolute;
  290. bottom: 0;
  291. left: 0;
  292. width: 100%;
  293. height: 44rpx;
  294. font-size: 28rpx;
  295. line-height: 44rpx;
  296. text-align: center;
  297. color: #fff;
  298. background-color: rgba(0, 0, 0, 0.6);
  299. }
  300. }
  301. .submit{
  302. width: 100%;
  303. margin: 0 5%;
  304. display: flex;
  305. height: 40px;
  306. padding: 8px 12px;
  307. justify-content: center;
  308. align-items: center;
  309. gap: 4px;
  310. flex: 1 0 0;
  311. border-radius: 8px;
  312. background: #0BBC58;
  313. }
  314. </style>