<template>
<view>
<view class="box">
<view class="search">
<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/mini-wx/images/homeIndex/search.png" mode=""></image>
<view class="inputCon">
<input type="search"
placeholder="搜索地铁站"
v-model="searchValue"
confirm-type="search"
@confirm="search()">
</view>
</view>
<view class="list-box" v-if="showList">
<view class="item active" v-for="(item, index) in stationList" :key="index" @click="onSelectStation(item)" v-html="item.subway_name">
</view>
</view>
<view v-if="isContent">
<view style="margin-top: 20rpx;" class="pickers">
<picker
:value="multiIndex"
@change="onChange"
@columnchange="onColumnChange"
mode="multiSelector"
:range="multiArray"
range-key="label"
>
<text>定位</text>
<view style="max-width:max-content;
height: 46rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
border: 2rpx solid rgba(0,139,124,0.1);
padding: 10rpx;">
<image src="https://ebk-picture.oss-cn-hangzhou.aliyuncs.com/ebk-wap/img-202304231132081261-Group%2034001.png" mode=""></image>
<text style="font-size: 28rpx;
font-weight: 400;
color: #008B7C;
line-height: 33rpx;">{{station}}</text>
</view>
<!-- <view class="picker-value">{{ line }} - {{ station }}</view> -->
</picker>
</view>
<text class="search_txt">历史记录:</text>
<view class="search_history">
<view v-for="(item, index) in searchHistory" :key="index" @tap="onSearchHistoryTap(item)" class="search_item" @click="toIndex()">
<text>{{ item }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
sub: "",
multiArray: [],
multiIndex: [0, 0],
line: "",
station: "",
lines: [],
stations: [] ,
City:[],
searchValue:'',
searchHistory:[],
stationList: [], // 下拉列表数据
showList: false ,// 判断下拉列表是否显示
timer: null ,// 定时器开关
isContent:true,//出现下拉列表时隐藏页面内容
zhanshi:""
};
},
watch: {
searchValue: function(val) {
if (this.timer) clearTimeout(this.timer); // 清除上个定时器
this.timer = setTimeout(() => {
if (val) {
this.search(); // 发起搜索请求
this.showList = true; // 显示下拉菜单
this.isContent = false
} else {
this.stationList = []//清空上一次的下拉展示记录
this.showList = false; // 隐藏下拉菜单
this.isContent = true
}
}, 300); // 设置定时器,延迟 300 毫秒后开始搜索
}
},
// 在组件挂载后获取 localcityNm 缓存值,并请求地铁线路列表
mounted() {
this.sub = uni.getStorageSync("localcityNm");
this.getSubwayLinesList();
},
// 在页面加载时获取历史搜索记录和定位标志,将定位标志设为 false
onLoad(){
this.searchHistory = uni.getStorageSync("searchHistory")
console.log(this.searchHistory+'11')
const isDinwei = uni.getStorageSync('isDinwei')
uni.setStorageSync('isDinwei',false)
},
methods: {
// 跳转到首页
toIndex(){
uni.navigateBack(1)
},
// 点击历史搜索记录项触发的事件
onSearchHistoryTap(item) {
console.log(item,'我是点击的某一项')
// 将点击的历史搜索记录项值赋给搜索框
this.searchValue = item;
// 执行搜索方法进行搜索,并将定位标志设置为 true
this.onSelectStation();
uni.setStorageSync('localcityNm', this.searchValue);
const isDinwei = uni.getStorageSync('isDinwei')
uni.setStorageSync('isDinwei',true)
},
// 选择了某个地铁站时,更新当前页面显示的地铁站名称和存储的相关信息
onSelectStation(station) {
this.station = station.subway_name; // 更新当前显示的地铁站名称
uni.setStorageSync('localcityNm', station.subway_name); // 存储所选地铁站名称
const currentStationObj = JSON.parse(JSON.stringify(station));
const { subway_latitude, subway_longitude } = currentStationObj;
const newCityData = { lat: subway_latitude, lng: subway_longitude };
uni.setStorageSync('City', newCityData); // 存储所选地铁站的经纬度信息
const history = uni.getStorageSync('searchHistory') || [];
const newStationName = station.subway_name.replace(/<[^>]*>/g, ''); // 去除所有 HTML 标签
if (!history.includes(newStationName)) {//判断搜索历史记录中是否有值,无值执行以下代码
this.searchHistory = history;
this.searchHistory.unshift(newStationName);//在历史记录数组中首位添加搜索内容
if (this.searchHistory.length > 10) { // 保留10个值
this.searchHistory.pop()//当大于十个值时删掉数组末尾的值
}
uni.setStorageSync('searchHistory', this.searchHistory); // 存储搜索历史记录
const isDinwei = uni.getStorageSync('isDinwei');
uni.setStorageSync('isDinwei', true); // 设置已定位标志为true,避免再次进行定位操作
// history.push(newStationName);
uni.setStorageSync('localcityNm', newStationName);
this.searchValue = ''
this.toIndex(); // 跳转到首页
this.searchHistory = history;
uni.setStorageSync('searchHistory', this.searchHistory); // 存储搜索历史记录
}else{
//有搜索记录,删除之前的旧记录,将新搜索值重新push到数组首位
console.log('11111111111111111111111')
this.searchHistory = history;
let i = this.searchHistory.indexOf(newStationName);
this.searchHistory.splice(i, 1);
this.searchHistory.unshift(newStationName);
if (this.searchHistory.length > 10) { // 保留10个值
this.searchHistory.pop()
}
uni.setStorageSync('searchHistory', this.searchHistory); // 存储搜索历史记录
// 请勿重复搜索
this.toIndex(); // 跳转到首页
const isDinwei = uni.getStorageSync('isDinwei');
uni.setStorageSync('isDinwei', true); // 设置已定位标志为true,避免再次进行定位操作
uni.setStorageSync('localcityNm', newStationName);
uni.setStorageSync('isDinwei', true); // 设置已定位标志为true,避免再次进行定位操作
this.searchValue = ''
this.isContent = true
this.showList = false; // 关闭下拉列表
}
},
async search() {
try {
const res = await this.$request.post("subway/getSubwayStation", {
city_id: uni.getStorageSync("localcityId"),
subway_name: this.searchValue.trim()
});
const data = res.data;
// console.log(data,'数据格式')
const station = data[0];
if (station) {
this.showList = true;
this.isContent = false
//一定要是大于等于,不然匹配规则就有问题,匹配到单个不会显示
if (data.length >= 1) {
// 如果匹配到多个地铁站,则将所有信息保存到stationList中,并显示下拉列表
this.stationList = data;
this.stationList = data.map(item => {
const reg = new RegExp(this.searchValue, 'g'); // 使用正则表达式进行全局匹配
const newName = item.subway_name.replace(reg, `<span style="color:#008B7C">${this.searchValue}</span>`); // 将匹配到的部分用<span>标签包裹,并修改文字颜色
return { ...item, subway_name: newName };
});
console.log(this.stationList,'我是处理好的数据')
}
else {
// 如果只匹配到一个地铁站,则直接定位到该地铁站
this.station = station.subway_name;
uni.setStorageSync('localcityNm', station.subway_name);
const currentStationObj = JSON.parse(JSON.stringify(station));
const { subway_latitude, subway_longitude } = currentStationObj;
const newCityData = { lat: subway_latitude, lng: subway_longitude };
uni.setStorageSync('City', newCityData);
const history = uni.getStorageSync('searchHistory') || [];
const newStationName = station.subway_name.replace(/<[^>]*>/g, '');
// if (!history.includes(newStationName)) {
// const isDinwei = uni.getStorageSync('isDinwei')
// uni.setStorageSync('isDinwei',true)
// this.toIndex()
// history.push(newStationName);
// uni.setStorageSync('localcityNm', newStationName);
// this.searchHistory=history;
// uni.setStorageSync('searchHistory', this.searchHistory);
// }
}
} else {
this.showList = false;
this.isContent = true
uni.showToast({
title: '未找到该地铁站点',
icon: 'none'
});
}
} catch (error) {
console.log(error);
}
},
// 请求地铁线路列表
async getSubwayLinesList() {
try {
const res = await this.$request.post("subway/getSubwayLinesList", {
city_id: uni.getStorageSync("localcityId")
});
const data = res.data;
const lines = data;
// 格式化地铁线路名称列表数据,并存储到当前组件实例的 lines 属性中
this.lines = lines.map(item => ({
label: item.lines,
value: item.id
}));
this.line = lines[0].lines; // 初始化当前选中的地铁线路名
this.getSubwayStations(lines[0].id); // 获取第一个地铁线路的站点列表
} catch (error) {
console.log(error);
}
},
// 请求指定地铁线路的站点列表
async getSubwayStations(lineId) {
try {
// 调用后端API获取数据
const res = await this.$request.post("subway/getSubwayStationList", {
lines_id: lineId
});
const data = res.data;
// 将数据存储到stations变量中
const stations = data;
// 将每个站点的名称和id转换为label和value,存储到this.stations数组中
this.stations = stations.map(item => ({
label: item.subway_name,
value: item.id
})); // 存储地铁站点名称列表到 data 中
// 将data中的所有数据存储到City变量中
const City = data
this.City = City
// 如果用户没有选择站点,则默认选择距离用户最近的站点
if (!this.station) {
// 如果用户还没有选择站点,则将其设为本地存储中的城市名localcityNm
this.station = uni.getStorageSync('localcityNm')
}
// 设置选中的站点为当前地铁线路的第一个站点
this.multiIndex = [this.multiIndex[0], 0];
// 更新多列选择器的数据源
this.multiArray = [this.lines, this.stations];
} catch (error) {
console.log(error);
}
},
// 线路选择器值改变事件
onChange(e) {
const that = this;
// 获取picker选择器中的索引值
const multiIndex = e.detail.value;
// 获取当前选中的地铁线路的名称
const lineName = that.lines[multiIndex[0]].label;
// 获取当前选中的地铁站点的名称
const stationName = that.stations[multiIndex[1]].label;
// 将当前选中的地铁站点的名称存储到本地存储中,用于下次默认选择
uni.setStorageSync('localcityNm', stationName);
// 根据当前选中的地铁站点名称获取该站点的经纬度信息,并存储到localStorage中
const currentStation = that.City.find(item => item.subway_name === stationName);
if (currentStation) {
const currentStationObj = JSON.parse(JSON.stringify(currentStation));
const { subway_latitude, subway_longitude } = currentStationObj;
const newObj ={lat:subway_latitude, lng:subway_longitude}
uni.setStorageSync('City', newObj);
}
// 更新选中的地铁线路、站点名称
that.line = lineName;
that.station = stationName;
// 重新获取并更新站点列表数据
that.getSubwayStations(
that.lines.find(item => item.label === lineName).value
);
// 更新多列选择器的数据源和选中的索引值
that.multiArray = [that.lines, that.stations];
that.multiIndex = multiIndex;
// 跳转到首页
this.toIndex()
// 设置isDinwei为true,表示已经定位
const isDinwei = uni.getStorageSync('isDinwei')
uni.setStorageSync('isDinwei',true)
},
// 列变化事件
onColumnChange(e) {
let that = this
// 获取列和行的索引值
const columnIndex = e.detail.column;
const rowIndex = e.detail.value;
// 如果列变化的是地铁线路列,则重新获取站点列表并更新右侧 picker 列表的数据源
if (columnIndex === 0) {
const lineId = that.lines[rowIndex].value;
that.getSubwayStations(lineId);
}
}
}
};
</script>
<style lang="less" scoped>
.box{
padding-left:24rpx ;
padding-right: 20rpx;
.search_history{
width: 100%;
display: flex;
flex-wrap: wrap;
.search_item{
width: max-content;
height: 56rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
opacity: 1;
border: 2rpx solid rgba(0,0,0,0.1);
margin-right:20rpx ;
padding-left: 8rpx;
padding-right: 8rpx;
margin-bottom: 20rpx;
text{
font-size: 28rpx;
font-weight: 400;
line-height: 56rpx;
text-align: center;
color:
}
}
}
.picker {
font-size: 16px;
color:
line-height: 40px;
text-align: center;
border: 1px solid
border-radius: 4px;
padding: 0 10px;
margin-top: 20px;
}
.pickers{
text{
font-size: 24rpx;
font-weight: 400;
color:
line-height: 68rpx;
}
image{
width: 24rpx;
height: 28rpx;
vertical-align: middle;margin-right: 6rpx;
}
}
.search_txt{
font-size: 24rpx;
font-weight: 400;
color:
line-height: 98rpx;
}
.search {
/* // flex: 1; */
height: 64rpx;
position: relative;
background-color:
// bottom: -0rpx;
border-radius: 300rpx;
image {
position: absolute;
width: 22rpx;
height: 18rpx;
top: 22rpx;
left: 22rpx;
z-index: 999;
}
input {
width: 90%;
height: 62rpx;
position: absolute;
left: 0;
top: 0;
margin: 0 auto;
// border: none;
background-color:
border: 1rpx solid rgba(0,0,0,0.2);
border-radius: 300rpx;
padding: 0;
margin: 0;
padding-left: 60rpx;
color:
font-size: 24rpx;
}
}
.dinwei{
font-size: 24rpx;
font-weight: 400;
color:
line-height: 28rpx;
}
}
.list-box{
padding: 22rpx;
.item{
width: 100%;
padding-bottom: 20rpx;
padding-top: 20rpx;
border-bottom: 1rpx solid rgba(0,0,0,0.02);
color:
font-size: 30rpx;
}
.item:hover .active{
color:
}
}
</style>