Kaynağa Gözat

城市选择

your_username 3 hafta önce
ebeveyn
işleme
335f3794af
1 değiştirilmiş dosya ile 464 ekleme ve 0 silme
  1. 464 0
      pages/index/citySelect.vue

+ 464 - 0
pages/index/citySelect.vue

@@ -0,0 +1,464 @@
+<template>
+	<view class="city-select-page">
+		<!-- 城市选择头部 -->
+		<view class="city-header">
+			<view class="header-content">
+				<view class="header-left" @click="goBack">
+					<u-icon name="close" color="#333" size="32"></u-icon>
+				</view>
+				<view class="header-title">城市选择</view>
+				<view class="header-right"></view>
+			</view>
+		</view>
+		
+		<!-- 三列选择区域 -->
+		<view class="city-list">
+			<!-- 左侧城市列 -->
+			<view class="city-column city-column-left">
+				<scroll-view scroll-y="true" style="width: 100%;height: 100%;padding-bottom: 20rpx;">
+					<view 
+						class="city-item" 
+						@click="selectCity(index)" 
+						:class="currentCity==index?'active':''" 
+						v-for="(item,index) in cityList" 
+						:key="index"
+					>
+						{{item.name}}
+					</view>
+				</scroll-view>
+			</view>
+			
+			<!-- 中间区域列 -->
+			<view class="city-column city-column-middle">
+				<view class="city-column-container">
+					<!-- 区域标题列 -->
+					<view class="city-column-titles">
+						<scroll-view scroll-y="true" style="width: 100%;height: 100%;padding-bottom: 20rpx;">
+							<view 
+								class="city-title-item" 
+								@click="setActiveDistrict(index)" 
+								:class="activeDistrict==index?'active':''" 
+								v-for="(item,index) in districtList" 
+								:key="index"
+							>
+								{{item.name}}
+							</view>
+						</scroll-view>
+					</view>
+					
+					<!-- 最右侧子区域列 -->
+					<view class="city-column-content">
+						<scroll-view scroll-y="true" style="width: 100%;height: 100%;padding-bottom: 20rpx;">
+							<view class="city-sub-items" v-if="districtList.length>0 && districtList[activeDistrict]">
+								<view 
+									class="city-sub-item" 
+									@click="selectSubArea(item)" 
+									:class="selectedSubAreas.includes(item.name)?'selected':''"
+									v-for="(item,ind) in districtList[activeDistrict].subAreas" 
+									:key="ind"
+								>
+									{{item.name}}
+								</view>
+							</view>
+						</scroll-view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- 底部确定按钮 -->
+		<view class="bottom-btn-container">
+			<view class="confirm-btn" @click="confirmSelection">
+				<text>确定</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			currentCity: 0,
+			activeDistrict: 0,
+			selectedSubAreas: ['蛇口', '海岸城'],
+			cityList: [
+				{ name: '深圳', code: 'sz' },
+				{ name: '广州', code: 'gz' },
+			],
+			districtList: [
+				{
+					name: '全深圳',
+					subAreas: [
+                    { name: '全南山' },
+						{ name: '科技园' },
+						{ name: '西丽' },
+						{ name: '前海' },
+						{ name: '蛇口' },
+						{ name: '大学城' },
+						{ name: '海岸城' },
+						{ name: '南山中心' },
+						{ name: '华侨城' },
+						{ name: '南油' },
+						{ name: '海上世界' },
+						{ name: '欢乐海岸' },
+						{ name: '后海' },
+						{ name: '大冲' }
+                    ]
+				},
+				{
+					name: '南山区',
+					subAreas: [
+						{ name: '全南山' },
+						{ name: '科技园' },
+						{ name: '西丽' },
+						{ name: '前海' },
+						{ name: '蛇口' },
+						{ name: '大学城' },
+						{ name: '海岸城' },
+						{ name: '南山中心' },
+						{ name: '华侨城' },
+						{ name: '南油' },
+						{ name: '海上世界' },
+						{ name: '欢乐海岸' },
+						{ name: '后海' },
+						{ name: '大冲' }
+					]
+				},
+				{
+					name: '龙岗区',
+					subAreas: [
+						{ name: '全龙岗' },
+						{ name: '布吉' },
+						{ name: '坂田' },
+						{ name: '横岗' },
+						{ name: '龙城' },
+						{ name: '坪地' },
+						{ name: '平湖' }
+					]
+				},
+				{
+					name: '宝安区',
+					subAreas: [
+						{ name: '全宝安' },
+						{ name: '西乡' },
+						{ name: '福永' },
+						{ name: '沙井' },
+						{ name: '松岗' },
+						{ name: '石岩' }
+					]
+				},
+				{
+					name: '福田区',
+					subAreas: [
+						{ name: '全福田' },
+						{ name: '华强北' },
+						{ name: '车公庙' },
+						{ name: '中心区' },
+						{ name: '皇岗' },
+						{ name: '梅林' }
+					]
+				},
+				{
+					name: '龙华区',
+					subAreas: [
+						{ name: '全龙华' },
+						{ name: '民治' },
+						{ name: '大浪' },
+						{ name: '观澜' },
+						{ name: '福城' }
+					]
+				},
+				{
+					name: '罗湖区',
+					subAreas: [
+						{ name: '全罗湖' },
+						{ name: '东门' },
+						{ name: '国贸' },
+						{ name: '翠竹' },
+						{ name: '莲塘' }
+					]
+				},
+				{
+					name: '光明区',
+					subAreas: [
+						{ name: '全光明' },
+						{ name: '公明' },
+						{ name: '光明' },
+						{ name: '新湖' }
+					]
+				},
+				{
+					name: '坪山区',
+					subAreas: [
+						{ name: '全坪山' },
+						{ name: '坪山' },
+						{ name: '坑梓' }
+					]
+				},
+				{
+					name: '盐田区',
+					subAreas: [
+						{ name: '全盐田' },
+						{ name: '盐田' },
+						{ name: '沙头角' }
+					]
+				}
+			]
+		};
+	},
+	methods: {
+		/**
+		 * 返回上一页
+		 */
+		goBack() {
+			uni.navigateBack()
+		},
+		
+		/**
+		 * 选择城市
+		 */
+		selectCity(index) {
+			this.currentCity = index
+			this.activeDistrict = 0
+			this.selectedSubAreas = []
+		},
+		
+		/**
+		 * 选择区域
+		 */
+		setActiveDistrict(index) {
+			this.activeDistrict = index
+		},
+		
+		/**
+		 * 选择子区域
+		 */
+		selectSubArea(item) {
+			const index = this.selectedSubAreas.indexOf(item.name)
+			if (index > -1) {
+				this.selectedSubAreas.splice(index, 1)
+			} else {
+				this.selectedSubAreas.push(item.name)
+			}
+		},
+		
+		/**
+		 * 确认选择
+		 */
+		confirmSelection() {
+			console.log('选中的城市:', this.cityList[this.currentCity])
+			console.log('选中的区域:', this.districtList[this.activeDistrict])
+			console.log('选中的子区域:', this.selectedSubAreas)
+			
+			uni.showToast({
+				title: '选择成功',
+				icon: 'success'
+			})
+			
+			setTimeout(() => {
+				uni.navigateBack()
+			}, 1500)
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+page {
+	background-color: #FCFCFC;
+	padding: 0 20rpx;
+}
+
+.city-select-page {
+	min-height: 100vh;
+}
+
+.city-header {
+	padding-top: 80rpx;
+	background-color: #FCFCFC;
+	z-index: 9999;
+	box-sizing: border-box;
+	margin-bottom: 40rpx;
+	
+	.header-content {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		height: 100%;
+		
+		.header-left, .header-right {
+			width: 60rpx;
+			height: 60rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+		}
+		
+		.header-title {
+			color: rgba(51, 51, 51, 1);
+			font-family: DM Sans;
+			font-size: 36rpx;
+			font-weight: 700;
+			line-height: 26px;
+			letter-spacing: 0px;
+			text-align: center;
+		}
+	}
+}
+
+.city-list {
+	width: 100%;
+	height: calc(100vh - 200rpx);
+	gap: 16rpx;
+	display: flex;
+	
+	.city-column {
+		border-radius: 6px;
+		// background-color: #ffffff;
+		// border-left: 1rpx solid #F2F2F7;
+		box-sizing: border-box;
+		
+		&.city-column-left {
+			width: 25%;
+			height: 90%;
+			background: rgba(245, 245, 245, 1);
+			border-left: none;
+            padding-top: 42rpx;
+			
+			.city-item {
+                color: rgba(102, 102, 102, 1);
+                font-family: DM Sans;
+                font-size: 32rpx;
+                font-weight: 400;
+                line-height: 42rpx;
+                letter-spacing: 0%;
+                text-align: center;
+                padding: 16rpx 0;
+                margin-bottom: 16rpx;
+				
+				&.active {
+                    color: rgba(1, 107, 246, 1);
+                    font-family: DM Sans;
+                    font-size: 32rpx;
+                    font-weight: 400;
+                    line-height: 42rpx;
+                    letter-spacing: 0%;
+                    text-align: center;
+                    padding: 16rpx auto;
+                    margin-bottom: 16rpx;
+				}
+			}
+		}
+		
+		&.city-column-middle {
+			width: 75%;
+			height: 90%;
+            // gap: 16rpx;
+			
+			.city-column-container {
+				width: 100%;
+				height: 100%;
+				display: flex;
+				flex-direction: row;
+			}
+			
+			.city-column-titles {
+				width: 50%;
+				height: 100%;
+                background: rgba(255, 255, 255, 1);
+				// border-right: 1rpx solid #F2F2F7;
+				box-sizing: border-box;
+                margin-right: 16rpx;
+                border-radius: 12rpx;
+                box-shadow: 0px 8px 150px 0px rgba(0, 0, 0, 0.05);
+                padding-top: 42rpx;
+				
+				.city-title-item {
+                    color: rgba(153, 153, 153, 1);
+                    font-family: DM Sans;
+                    font-size: 32rpx;
+                    font-weight: 400;
+                    line-height: 42rpx;
+                    letter-spacing: 0%;
+                    text-align: left;
+                    padding: 16rpx 0 16rpx 40rpx;
+					
+					&.active {
+                        color: rgba(1, 107, 246, 1);
+                        background: rgba(153, 196, 250, 0.4);
+                        font-family: DM Sans;
+                        font-size: 32rpx;
+                        font-weight: 400;
+                        line-height: 42rpx;
+                        letter-spacing: 0%;
+                        text-align: left;
+                        padding: 16rpx 0 16rpx 40rpx;
+					}
+				}
+			}
+			
+			.city-column-content {
+				width: 70%;
+				height: 100%;
+                background: #F5F5F5;
+                border-radius: 12rpx;
+                box-shadow: 0px 8px 150px 0px rgba(0, 0, 0, 0.05);
+				flex: 1;
+				
+				.city-sub-items {
+					width: 100%;
+					display: flex;
+					flex-direction: column;
+					gap: 12rpx;
+					padding-top: 42rpx;
+					
+					.city-sub-item {
+                        color: rgba(153, 153, 153, 1);
+                        font-family: DM Sans;
+                        font-size: 32rpx;
+                        font-weight: 400;
+                        line-height: 42rpx;
+                        letter-spacing: 0%;
+                        text-align: left;
+                        padding: 16rpx 0 16rpx 40rpx;
+						
+						&.selected {
+                            color: rgba(255, 255, 255, 1);
+                            border-radius: 0px 6px 6px 0px;
+                            background: rgba(1, 107, 246, 1);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+.bottom-btn-container {
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	padding: 30rpx 20rpx;
+	background: #fff;
+	border-top: 1px solid #f0f0f0;
+	z-index: 9999;
+}
+
+.confirm-btn {
+	width: 100%;
+	height: 88rpx;
+	background: var(--线性渐变, linear-gradient(90.00deg, rgba(13, 39, 247, 1),rgba(19, 193, 234, 1) 100%));
+	border-radius: 44rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	
+	text {
+		font-size: 32rpx;
+		font-weight: 600;
+		color: #fff;
+	}
+}
+</style>