163 lines
4.5 KiB
Vue
163 lines
4.5 KiB
Vue
<template>
|
|
<view style="min-height:100vh;background: #FFFFFF" v-if="ready">
|
|
<view style="padding: 20rpx 32rpx">
|
|
<u-input v-model="keyword" :customStyle="{'border':'none','background': '#F6F6F6'}"
|
|
placeholder="输入城市名、拼音或字母查询" shape="circle" @confirm="onSearch" @change="onChange">
|
|
<template v-slot:suffix>
|
|
<u-icon name="search" color="#FD5749" size="32rpx" @click="onSearch"/>
|
|
</template>
|
|
</u-input>
|
|
</view>
|
|
|
|
<view style="margin: 32rpx" v-if="searchList.length">
|
|
<view class="flex flex-wrap">
|
|
<view class="n-tag jc-center ai-center" v-for="(item,index) in searchList" :key="index"
|
|
@click="navToWatch(item['name'])">{{ item['name'] }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<template v-else>
|
|
<view style="margin: 32rpx" v-if="cityName">
|
|
<view style="margin-bottom: 16rpx">当前定位</view>
|
|
<view class="n-tag jc-center ai-center" @click="navToWatch(cityName)">
|
|
<u-icon name="map" color="#333333" size="36rpx"/>
|
|
{{ cityName }}
|
|
</view>
|
|
</view>
|
|
|
|
<view style="margin: 32rpx" v-if="watchCity.length">
|
|
<view style="margin-bottom: 16rpx">历史访问</view>
|
|
<view class="flex flex-wrap">
|
|
<view class="n-tag jc-center ai-center" v-for="(item,index) in watchCity" :key="index"
|
|
@click="navToWatch(item)">{{ item }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<u-index-list :index-list="indexList" inactiveColor="#666666" activeColor="#FD5749">
|
|
<template v-for="(item, index) in itemArr">
|
|
<u-index-item>
|
|
<u-index-anchor :text="indexList[index].toUpperCase()" color="#333333" size="32rpx" bgColor="#FFFFFF"/>
|
|
<view class="list-cell" v-for="(cell, cIndex) in item" :key="cIndex" @click="navToWatch(cell['name'])">
|
|
{{ cell['name'] }}
|
|
</view>
|
|
</u-index-item>
|
|
</template>
|
|
</u-index-list>
|
|
</template>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {onMounted, ref} from '@vue/composition-api'
|
|
import {getCurAddress, getLocation} from "@/utils/common";
|
|
import {getVideoCity} from "@/api/video";
|
|
|
|
const watchCity = ref(uni.getStorageSync('watchCity') || [])
|
|
|
|
onMounted(() => {
|
|
getMapData()
|
|
fetchList()
|
|
})
|
|
|
|
const ready = ref(false)
|
|
const cityName = ref('')
|
|
const keyword = ref('')
|
|
|
|
const onSearch = () => {
|
|
const name = keyword.value.trim()
|
|
if (name.length > 0) {
|
|
navToWatch(name)
|
|
}
|
|
}
|
|
|
|
const raw = ref()
|
|
const searchList = ref([])
|
|
const onChange = (value) => {
|
|
searchList.value = []
|
|
if (value.trim().length === 0) return
|
|
searchList.value = raw.value.filter(city => {
|
|
if (city['name'].indexOf(value) > -1) return city
|
|
})
|
|
}
|
|
|
|
const handleHistory = (name) => {
|
|
for (let i = 0; i < watchCity.value.length; i++) {
|
|
if (name === watchCity.value[i]) return
|
|
}
|
|
if (watchCity.value.length === 4) {
|
|
watchCity.value.pop()
|
|
}
|
|
watchCity.value.unshift(name)
|
|
uni.setStorageSync('watchCity', watchCity.value)
|
|
}
|
|
|
|
const getMapData = async () => {
|
|
const map = await getLocation();
|
|
if (map.length > 1) {
|
|
const {latitude, longitude} = map[1];
|
|
const address = await getCurAddress(latitude, longitude);
|
|
cityName.value = address[1].data.result['ad_info']['city']
|
|
}
|
|
}
|
|
|
|
const indexList = ref(["A", "B", "C"])
|
|
const itemArr = ref([
|
|
['列表A1', '列表A2', '列表A3'],
|
|
['列表B1', '列表B2', '列表B3'],
|
|
['列表C1', '列表C2', '列表C3']
|
|
])
|
|
|
|
const fetchList = async () => {
|
|
const res = await getVideoCity()
|
|
if (res.success) {
|
|
raw.value = res.data
|
|
const groupedByName = res.data.reduce((accumulator, current) => {
|
|
const groupKey = current['firstLetter'].toUpperCase()
|
|
if (!accumulator[groupKey]) {
|
|
accumulator[groupKey] = []
|
|
}
|
|
accumulator[groupKey].push(current)
|
|
return accumulator
|
|
}, {})
|
|
|
|
indexList.value = Object.keys(groupedByName)
|
|
itemArr.value = Object.values(groupedByName)
|
|
}
|
|
ready.value = true
|
|
}
|
|
|
|
const navToWatch = (name) => {
|
|
handleHistory(name)
|
|
uni.redirectTo({url: '/pkg-video/views/watch?name=' + name})
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
/deep/ .u-index-item {
|
|
.u-border-bottom {
|
|
border: none !important;
|
|
}
|
|
}
|
|
|
|
.list-cell {
|
|
margin: 0 30rpx;
|
|
padding: 16rpx 0;
|
|
border-bottom: 1rpx solid #DCDCDC;
|
|
color: #333333;
|
|
font-size: 32rpx;
|
|
}
|
|
|
|
.n-tag {
|
|
display: inline-flex;
|
|
height: 60rpx;
|
|
box-sizing: border-box;
|
|
margin: 0 32rpx 16rpx 0;
|
|
padding: 0 20rpx;
|
|
border: 2px solid #B5B5B5;
|
|
border-radius: 8rpx;
|
|
color: #333333;
|
|
font-size: 32rpx;
|
|
}
|
|
</style> |