|
@@ -0,0 +1,353 @@
|
|
|
+<template>
|
|
|
+ <view class="serve-content" :style="{'height':height +'px' }">
|
|
|
+ <view class="serve-title">可以办事项</view>
|
|
|
+ <view class="serve-search">
|
|
|
+ <input confirm-type="search" ref="searchInputRef" class="search-input" :auto-blur="true" type="text"
|
|
|
+ placeholder="搜索服务事项" v-model="matterName" @confirm="getMatterList" />
|
|
|
+ <view class="search-btn" @click.stop="getMatterList"> 搜 索 </view>
|
|
|
+ </view>
|
|
|
+ <view class="matter-loading" v-if="MatterListLoading">
|
|
|
+ <u-loading-icon />
|
|
|
+ </view>
|
|
|
+ <view class="serve" :style="{'height':scrollH +'px' }" v-else-if="MatterList">
|
|
|
+ <scroll-view class="scroll-lable" :style="{'height':scrollH +'px' }" scroll-y="true"
|
|
|
+ :show-scrollbar="false">
|
|
|
+ <template v-for="(value, key , index) in MatterList">
|
|
|
+ <view :class="['lable one-row' , index === activeIndex ? 'active-lable' : '' ]"
|
|
|
+ @click.stop="openTyle(index)">{{ key }}</view>
|
|
|
+ </template>
|
|
|
+ </scroll-view>
|
|
|
+ <scroll-view class="scroll-val" :scroll-into-view="scrollIntoView" @scroll="scrollService"
|
|
|
+ :style="{'height':scrollH +'px' }" scroll-y="true" :show-scrollbar="false">
|
|
|
+ <template v-for="(value, key , index) in MatterList">
|
|
|
+ <view class="val-content" :id="`service_${index}`">
|
|
|
+ <view class="val-name">{{key}}</view>
|
|
|
+ <template v-for="(t_v, t_k , t_i) in (value || [])">
|
|
|
+ <!-- @click.stop="LookMatterDetails(item)" -->
|
|
|
+ <view class="val">
|
|
|
+ <view class="val-label val-item" @click.stop="setShowKey(index , t_i)">
|
|
|
+ <text class="val-text one-row">{{ t_k }}</text>
|
|
|
+ <template v-if="t_v && t_v.length">
|
|
|
+ <svg t="1734508422065"
|
|
|
+ :class="['val-icon' , showKey === getShowKey(index , t_i ) ? 'avtive-icon' : '']"
|
|
|
+ viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
|
+ p-id="4279" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
|
+ <path
|
|
|
+ d="M492.675886 904.817574L885.696074 511.797385 492.675886 118.777197c-12.258185-12.258185-12.432147-32.892131 0.187265-45.51052 12.707416-12.707416 32.995485-12.703323 45.511543-0.187265l411.660734 411.660734c7.120165 7.120165 10.163477 17.065677 8.990768 26.624381 1.500167 9.755178-1.5104 20.010753-8.990768 27.491121L538.374694 950.515359c-12.258185 12.258185-32.892131 12.432147-45.511543-0.187265-12.707416-12.707416-12.703323-32.995485-0.187265-45.51052z"
|
|
|
+ p-id="4280"></path>
|
|
|
+ </svg>
|
|
|
+ </template>
|
|
|
+ </view>
|
|
|
+ <!-- showKey -->
|
|
|
+ <template v-if="showKey === getShowKey(index , t_i )">
|
|
|
+ <view class="val-item" v-for="item in (t_v || [])">
|
|
|
+ {{item.name}}
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ <view v-else class="matter-loading">
|
|
|
+ <u-empty mode="data" :iconSize="emptySize" text="暂无可办事项" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import { getMapMatterListH6_Api } from "@/api/map.js"
|
|
|
+ export default {
|
|
|
+ props: {
|
|
|
+ height: {
|
|
|
+ type: Number,
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ mapLocationId: {
|
|
|
+ type: Number | String,
|
|
|
+ default: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ showKey: '',
|
|
|
+ scrollH: 0,
|
|
|
+ matterName: '',
|
|
|
+ MatterList: null,
|
|
|
+ MatterListLoading: false,
|
|
|
+ activeIndex: undefined,
|
|
|
+ scrollIntoView: undefined,
|
|
|
+ scrollStatus: true,
|
|
|
+ oldScrollNum: 0,
|
|
|
+ RightTopArr: [],
|
|
|
+
|
|
|
+ emptySize: uni.upx2px(130)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ height: {
|
|
|
+ handler(newH) {
|
|
|
+ // 区域高度 - 标题高度 - 搜索区域高度
|
|
|
+ this.scrollH = newH - uni.upx2px(60) - uni.upx2px(100);
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ },
|
|
|
+ mapLocationId: {
|
|
|
+ handler(newId) {
|
|
|
+ this.getMatterList(newId)
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getShowKey(k_1, k_2) {
|
|
|
+ return `${k_1}${k_2}`
|
|
|
+ },
|
|
|
+ setShowKey(index, t_i) {
|
|
|
+ const k = this.getShowKey(index, t_i);
|
|
|
+ if (!this.showKey || this.showKey !== k) {
|
|
|
+ this.showKey = k;
|
|
|
+ } else {
|
|
|
+ this.showKey = ''
|
|
|
+ };
|
|
|
+ },
|
|
|
+ getLabel(item) {
|
|
|
+ console.log("getLabel = ", item)
|
|
|
+ const label = Object.keys(item)[0];
|
|
|
+ return label;
|
|
|
+ },
|
|
|
+ getMatterList() {
|
|
|
+ this.MatterListLoading = true;
|
|
|
+ const parmas = {
|
|
|
+ mapLocationId: this.mapLocationId,
|
|
|
+ matterName: this.matterName
|
|
|
+ };
|
|
|
+ getMapMatterListH6_Api(parmas).then(res => {
|
|
|
+ const keys = Object.keys(res || {});
|
|
|
+ if (keys && keys.length > 0) {
|
|
|
+ this.MatterList = res;
|
|
|
+ this.activeIndex = 0;
|
|
|
+ this.getNodesInfo()
|
|
|
+ } else {
|
|
|
+ this.MatterList = null;
|
|
|
+ this.activeIndex = undefined;
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ this.MatterList = null;
|
|
|
+ this.activeIndex = undefined;
|
|
|
+ }).finally(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.MatterListLoading = false;
|
|
|
+ }, 300)
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ openTyle(index) {
|
|
|
+ this.scrollStatus = false;
|
|
|
+ this.activeIndex = index
|
|
|
+ this.scrollIntoView = `service_${index}`
|
|
|
+ setTimeout(() => {
|
|
|
+ this.scrollStatus = true;
|
|
|
+ }, 200)
|
|
|
+ },
|
|
|
+ scrollService(event) {
|
|
|
+ // console.log('stopPropagation ' , event)
|
|
|
+ // event.stopPropagation();
|
|
|
+ if (!this.scrollStatus) return
|
|
|
+ const { scrollTop } = event.detail;
|
|
|
+ let scrollNums = scrollTop;
|
|
|
+ if (this.oldScrollNum > scrollTop) {
|
|
|
+ scrollNums = scrollTop + 80;
|
|
|
+ };
|
|
|
+ try {
|
|
|
+ this.RightTopArr.forEach((el, index) => {
|
|
|
+ let data = this.RightTopArr[index];
|
|
|
+ if (scrollNums >= data.height && index == this.RightTopArr.length - 1 ? true :
|
|
|
+ scrollNums < this.RightTopArr[parseInt(index) + 1].height) {
|
|
|
+ this.activeIndex = index;
|
|
|
+ throw new Error()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } catch (e) {
|
|
|
+ //TODO handle the exception
|
|
|
+ }
|
|
|
+
|
|
|
+ this.oldScrollNum = scrollTop;
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+ // 查看事项详情
|
|
|
+ LookMatterDetails(item) {
|
|
|
+ // pages/map/matterDetails
|
|
|
+ // 在起始页面跳转到test.vue页面,并监听test.vue发送过来的事件数据
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '/pages/map/matterDetails',
|
|
|
+ success: function(res) {
|
|
|
+ // 通过eventChannel向被打开页面传送数据
|
|
|
+ res.eventChannel.emit('acceptDataFromOpenerPage', item)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ getNodesInfo() {
|
|
|
+ new Promise(resolve => {
|
|
|
+ let selectorQuery = uni.createSelectorQuery();
|
|
|
+ // 获取节点的位置信息
|
|
|
+ selectorQuery.selectAll('.val-content').boundingClientRect((rects) => {
|
|
|
+ // 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
|
|
|
+ if (!rects.length) {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.getNodesInfo();
|
|
|
+ })
|
|
|
+ }, 10);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.RightTopArr = [];
|
|
|
+ // 生成之后开始添加进去数组
|
|
|
+ rects.forEach((rect) => {
|
|
|
+ // 这里减去rects[0].top,是因为第一项顶部不是贴到导航栏=>每一个商品距离顶部的高度,如果此页面顶部没有其他的view那就不用减去rects[0].top,自己视情况而定。
|
|
|
+ let tops = rect.top - rects[0].top;
|
|
|
+ this.RightTopArr.push({
|
|
|
+ height: tops,
|
|
|
+ id: rect.id
|
|
|
+ });
|
|
|
+ })
|
|
|
+ resolve();
|
|
|
+ }).exec()
|
|
|
+ });
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .serve-content {
|
|
|
+ border-top: 1rpx solid #F0F0F0;
|
|
|
+
|
|
|
+ .serve-title {
|
|
|
+ color: #7D7D7D;
|
|
|
+ font-size: 32rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ line-height: 60rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .serve-search {
|
|
|
+ width: 100%;
|
|
|
+ padding: 20rpx 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: stretch;
|
|
|
+
|
|
|
+ .search-input {
|
|
|
+ flex: 1;
|
|
|
+ height: 60rpx;
|
|
|
+ border: 1rpx solid #F0F0F0;
|
|
|
+ border-radius: 10rpx;
|
|
|
+ padding: 0 15rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-btn {
|
|
|
+ width: 120rpx;
|
|
|
+ background-color: #3291F8;
|
|
|
+ margin-left: 20rpx;
|
|
|
+ line-height: 60rpx;
|
|
|
+ text-align: center;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 28rpx;
|
|
|
+ border-radius: 10rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .serve {
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ display: flex;
|
|
|
+ align-items: stretch;
|
|
|
+
|
|
|
+ .scroll-lable {
|
|
|
+ width: 160rpx;
|
|
|
+
|
|
|
+ .lable {
|
|
|
+ width: 100%;
|
|
|
+ height: 80rpx;
|
|
|
+ font-size: 30rpx;
|
|
|
+ line-height: 80rpx;
|
|
|
+ text-align: center;
|
|
|
+ border-left: 6rpx solid transparent;
|
|
|
+ padding: 0 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .active-lable {
|
|
|
+ color: #3291F8;
|
|
|
+ font-weight: 600;
|
|
|
+ border-left-color: #3291F8;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .scroll-val {
|
|
|
+ width: calc(100% - 160rpx);
|
|
|
+ padding: 0 0 0 20rpx;
|
|
|
+
|
|
|
+ .val-content {
|
|
|
+ // height: 300px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .val-name {
|
|
|
+ font-size: 30rpx;
|
|
|
+ padding: 15rpx 0;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ .val {
|
|
|
+ width: 100%;
|
|
|
+ border: 1rpx solid #F0F0F0;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ transition: height 1s;
|
|
|
+
|
|
|
+ .val-item {
|
|
|
+ width: 100%;
|
|
|
+ min-height: 100rpx;
|
|
|
+ padding: 10rpx 20rpx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ border-top: 1rpx solid #F0F0F0;
|
|
|
+ &:first-child{
|
|
|
+ border-top:none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .val-label {
|
|
|
+ font-weight: 600;
|
|
|
+ .val-text {
|
|
|
+ flex: 1;
|
|
|
+ width: 1px;
|
|
|
+ font-size: 30rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .val-icon {
|
|
|
+ width: 34rpx;
|
|
|
+ height: 34rpx;
|
|
|
+ transition: transform 0.3s;
|
|
|
+ }
|
|
|
+ .avtive-icon{
|
|
|
+ transform: rotate(90deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .matter-loading {
|
|
|
+ padding-top: 50rpx;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+</style>
|