web-base-h5/pages/mine/region/index.vue

331 lines
7.9 KiB
Vue
Raw Normal View History

<template>
<view class="region-container">
<!-- 收益区域列表 -->
<view class="region-list">
<!-- 省级区域 -->
<view v-if="shouldShowProvince" class="region-item">
<view class="region-card">
<view class="region-header">
<text class="region-level">省级区域</text>
</view>
<view v-if="selectedData.provinceData" class="region-content">
<text class="region-name">{{
selectedData.provinceData.provinceName
}}</text>
</view>
<view v-if="unSelected.includes('province')" class="region-action">
<button class="select-btn" @click="selectProvinceRegion">
选择省级收益区域
</button>
</view>
</view>
</view>
<!-- 市级区域 -->
<view v-if="shouldShowCity" class="region-item">
<view class="region-card">
<view class="region-header">
<text class="region-level">市级区域</text>
</view>
<view v-if="selectedData.cityData" class="region-content">
<text class="region-name">{{
selectedData.cityData.provinceName
}}</text>
<text class="region-separator">·</text>
<text class="region-name">{{
selectedData.cityData.cityName
}}</text>
</view>
<view v-if="unSelected.includes('city')" class="region-action">
<button class="select-btn" @click="selectCityRegion">
选择市级收益区域
</button>
</view>
</view>
</view>
<!-- 区县级区域 -->
<view v-if="shouldShowCounty" class="region-item">
<view class="region-card">
<view class="region-header">
<text class="region-level">区县级区域</text>
</view>
<view v-if="selectedData.countyData" class="region-content">
<text class="region-name">{{
selectedData.countyData.provinceName
}}</text>
<text class="region-separator">·</text>
<text class="region-name">{{
selectedData.countyData.cityName
}}</text>
<text class="region-separator">·</text>
<text class="region-name">{{
selectedData.countyData.countyName
}}</text>
</view>
<view v-if="unSelected.includes('county')" class="region-action">
<button class="select-btn" @click="selectCountyRegion">
选择区县收益区域
</button>
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view
v-if="!shouldShowProvince && !shouldShowCity && !shouldShowCounty"
class="empty-state"
>
<text class="empty-text">暂无收益区域数据</text>
</view>
<RegionSelect
@success="successHandle"
:autoTrigger="false"
ref="regionSelect"
/>
</view>
</template>
<script>
import { getRegionSelect } from '@/config/mine.js'
import RegionSelect from '@/components/region-select/index.vue'
export default {
name: 'RegionPage',
components: {
RegionSelect,
},
data() {
return {
unSelected: [],
selectedData: {},
rawData: {}, // 保存原始接口数据
}
},
computed: {
// 是否显示省级区域:有数据或者需要选择
shouldShowProvince() {
return (
this.selectedData.provinceData || this.unSelected.includes('province')
)
},
// 是否显示市级区域:有数据或者需要选择
shouldShowCity() {
return this.selectedData.cityData || this.unSelected.includes('city')
},
// 是否显示区县级区域:有数据或者需要选择
shouldShowCounty() {
return this.selectedData.countyData || this.unSelected.includes('county')
},
},
onShow() {
this.getRegionSelect()
},
methods: {
async getRegionSelect() {
uni.showLoading({
title: '加载中...',
})
return new Promise(async (resolve, reject) => {
try {
const res = await getRegionSelect()
if (res?.code === 200) {
this.rawData = res.data || {}
// 需要选择的区域字段为true的
const unSelected = Object.keys(res?.data || {})
.filter(key => key !== 'data')
.filter(key => res.data[key] === true)
this.unSelected = unSelected
this.selectedData = res.data?.data || {}
resolve()
}
} catch (error) {
reject(false)
} finally {
uni.hideLoading()
}
})
},
// 选择省级收益区域
selectProvinceRegion() {
this.$refs.regionSelect.open('province')
},
// 选择市级收益区域
selectCityRegion() {
this.$refs.regionSelect.open('city')
},
// 选择区县收益区域
selectCountyRegion() {
this.$refs.regionSelect.open('county')
},
successHandle(data) {
this.getRegionSelect()
},
},
}
</script>
<style lang="scss" scoped>
.region-container {
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 15rpx;
}
.region-list {
padding: 0 15rpx;
}
.region-item {
margin-bottom: 15rpx;
.region-card {
background: #ffffff;
border-radius: 20rpx;
padding: 20rpx;
box-shadow: 0 8rpx 30rpx rgba(0, 91, 172, 0.1);
border: 2rpx solid rgba(0, 91, 172, 0.1);
transition: all 0.3s ease;
&:hover {
box-shadow: 0 12rpx 40rpx rgba(0, 91, 172, 0.15);
transform: translateY(-4rpx);
}
}
.region-header {
text-align: center;
padding: 15rpx 0 20rpx 0;
position: relative;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100rpx;
height: 4rpx;
background: linear-gradient(135deg, #005bac 0%, #0071d9 100%);
border-radius: 2rpx;
}
.region-level {
font-size: 32rpx;
color: #005bac;
font-weight: bold;
letter-spacing: 1rpx;
}
}
.region-content {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
margin-bottom: 15rpx;
2025-07-25 09:42:30 +08:00
// margin-top: 10rpx;
padding: 10rpx 0;
.region-name {
font-size: 28rpx;
color: #333333;
font-weight: 500;
}
.region-separator {
margin: 0 10rpx;
font-size: 24rpx;
color: #999999;
}
}
.region-action {
2025-07-25 09:42:30 +08:00
margin-top: 16rpx;
.select-btn {
width: 100%;
height: 70rpx;
background: linear-gradient(135deg, #005bac 0%, #0071d9 100%);
color: #ffffff;
border: none;
border-radius: 35rpx;
font-size: 26rpx;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 6rpx 20rpx rgba(0, 91, 172, 0.3);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
box-shadow: 0 4rpx 15rpx rgba(0, 91, 172, 0.4);
}
&::after {
border: none;
}
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60rpx 40rpx;
.empty-text {
font-size: 26rpx;
color: #999999;
}
}
/* 响应式设计 */
@media screen and (max-width: 750rpx) {
.region-container {
padding: 10rpx;
}
.region-list {
padding: 0 10rpx;
}
.region-item {
margin-bottom: 12rpx;
.region-card {
padding: 18rpx;
}
.region-header {
padding: 12rpx 0 15rpx 0;
.region-level {
font-size: 30rpx;
}
}
.region-content {
padding: 8rpx 0;
margin-bottom: 12rpx;
.region-name {
font-size: 26rpx;
}
.region-separator {
font-size: 22rpx;
}
}
.region-action .select-btn {
height: 65rpx;
font-size: 24rpx;
}
}
}
</style>