123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- <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>
|