243 lines
5.6 KiB
Vue
243 lines
5.6 KiB
Vue
<template>
|
||
<view class="container">
|
||
<view class="nearby-page">
|
||
<!-- 附近美食模块 -->
|
||
<view class="section shadow" v-for="(item,index) in aroundList" :key="index">
|
||
<view class="section-header" @click="goPage(item.id)">
|
||
<view class="section-title">{{item.label}}</view>
|
||
<u-icon name="arrow-right" size="20" color="#999"></u-icon>
|
||
</view>
|
||
<!-- 优化:使用网格布局实现更稳定的四列 -->
|
||
<view class="goods-grid">
|
||
<view class="goods-item" v-for="i in item.serviceList" :key="i.id"
|
||
@click="goDetail(i.id,i.distance)">
|
||
<image class="goods-img" :src="`${IMAGE_BASE_URL}`+i.storeCover" mode="aspectFill"></image>
|
||
<view class="goods-info">
|
||
<text class="goods-name">{{ i.storeName }}</text>
|
||
<view class="goods-distance">
|
||
<u-icon name="map" size="18" color="#c6d8fa"></u-icon>
|
||
<text>{{ formatDistance(i.distance) }} </text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<Copyright/>
|
||
<Footer></Footer>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import Footer from '@/components/footer_common.vue';
|
||
import Copyright from '@/components/gx-copyright.vue';
|
||
import { get, post } from '@/utils/request';
|
||
import { IMAGE_BASE_URL, BASE_URL } from '@/utils/config';
|
||
import { formatTime, formatRelativeTime } from '@/utils/timeFormat';
|
||
|
||
export default {
|
||
components: { Footer,Copyright },
|
||
data() {
|
||
return {
|
||
IMAGE_BASE_URL,
|
||
aroundList:[],
|
||
longitude:null,
|
||
latitude:null,
|
||
}
|
||
},
|
||
onLoad() {},
|
||
mounted() {
|
||
this.surroundingList();
|
||
},
|
||
methods: {
|
||
goDetail(id, local) {
|
||
uni.navigateTo({
|
||
url: `/pages/aroundDetail/index?Id=${id}&local=${local}`,
|
||
});
|
||
},
|
||
goPage(id){
|
||
uni.navigateTo({
|
||
url: `/pages/aroundList/index?Id=${id}&latitude=${this.latitude}&longitude=${this.longitude}`,
|
||
});
|
||
},
|
||
formatDistance(distance) {
|
||
if (!distance) return '未知距离';
|
||
if (distance < 1000) {
|
||
return `${distance}米`;
|
||
} else {
|
||
return `${(distance / 1000).toFixed(1)}公里`;
|
||
}
|
||
},
|
||
async surroundingList() {
|
||
const position = await this.getCurrentPosition();
|
||
this.latitude = position.latitude;
|
||
this.longitude = position.longitude;
|
||
let params = {
|
||
current: 1,
|
||
pageSize: 10,
|
||
longitude: position.longitude,
|
||
latitude: position.latitude
|
||
};
|
||
try {
|
||
const res = await get('/api/v1/apps/surrounding-type', params);
|
||
if (!res || !res.success) {
|
||
throw new Error('获取周边服务失败');
|
||
}
|
||
this.aroundList = [...res.data];
|
||
} catch (err) {
|
||
console.error('获取周边服务失败:', err);
|
||
}
|
||
},
|
||
getCurrentPosition() {
|
||
return new Promise((resolve, reject) => {
|
||
uni.getLocation({
|
||
type: 'wgs84',
|
||
success: (res) => {
|
||
resolve({
|
||
longitude: res.longitude,
|
||
latitude: res.latitude
|
||
});
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取位置失败:', err);
|
||
uni.showToast({
|
||
title: '获取位置失败,请检查位置权限设置',
|
||
icon: 'none'
|
||
});
|
||
reject(err);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 100vh;
|
||
background: #f8faff;
|
||
padding-bottom: 120rpx;
|
||
}
|
||
|
||
.nearby-page {
|
||
padding: 20rpx 24rpx;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
flex: 1;
|
||
}
|
||
|
||
.section {
|
||
margin: 32rpx 0;
|
||
padding: 24rpx;
|
||
border-radius: 20rpx;
|
||
background-color: #fff;
|
||
transition: all 0.3s ease;
|
||
box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06);
|
||
|
||
&:active {
|
||
transform: scale(0.98);
|
||
}
|
||
}
|
||
|
||
.section-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 24rpx;
|
||
padding: 0 10rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 36rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
border-left: 8rpx solid #8dbafc;
|
||
padding-left: 20rpx;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
/* 优化:使用grid布局实现更稳定的四列分布 */
|
||
.goods-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr); /* 强制四列布局 */
|
||
gap: 10rpx; /* 统一间距 */
|
||
}
|
||
|
||
.goods-item {
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
background: #fff;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.96);
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
}
|
||
|
||
.goods-img {
|
||
width: 100%;
|
||
height: 160rpx; /* 优化图片高度比例 */
|
||
border-radius: 12rpx 12rpx 0 0;
|
||
display: block;
|
||
object-fit: cover; /* 确保图片不变形 */
|
||
}
|
||
|
||
.goods-info {
|
||
padding: 16rpx;
|
||
}
|
||
|
||
.goods-name {
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
line-height: 1.5;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.goods-distance {
|
||
font-size: 22rpx;
|
||
color: #666;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.u-icon {
|
||
margin-right: 4rpx;
|
||
}
|
||
}
|
||
|
||
/* 响应式优化:小屏幕自动调整为两列 */
|
||
@media (max-width: 750rpx) { /* 适配常见手机屏幕 */
|
||
.goods-grid {
|
||
grid-template-columns: repeat(2, 1fr); /* 小屏幕两列 */
|
||
}
|
||
|
||
.goods-img {
|
||
height: 200rpx; /* 增加小屏幕图片高度 */
|
||
}
|
||
|
||
.goods-name {
|
||
font-size: 26rpx; /* 增大字体 */
|
||
}
|
||
}
|
||
|
||
/* 针对超小屏幕的额外适配 */
|
||
@media (max-width: 375rpx) {
|
||
.goods-grid {
|
||
grid-template-columns: 1fr; /* 极小屏幕单列 */
|
||
}
|
||
|
||
.goods-img {
|
||
height: 240rpx;
|
||
}
|
||
}
|
||
</style> |