| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  | <template> | 
					
						
							|  |  |  |   <div | 
					
						
							|  |  |  |     v-if="popupVisible" | 
					
						
							|  |  |  |     class="region-select-overlay" | 
					
						
							|  |  |  |     @click.self="handleClose" | 
					
						
							|  |  |  |   > | 
					
						
							|  |  |  |     <div class="region-select-popup"> | 
					
						
							|  |  |  |       <div class="popup-header"> | 
					
						
							|  |  |  |         <h3 class="popup-title">选择收益区域</h3> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |       <div class="popup-content"> | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  |         <picker-view | 
					
						
							|  |  |  |           v-if="popupVisible" | 
					
						
							|  |  |  |           class="picker-view" | 
					
						
							|  |  |  |           :indicator-style="indicatorStyle" | 
					
						
							|  |  |  |           :value="pickerValue" | 
					
						
							|  |  |  |           @change="handlePickerChange" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           <picker-view-column> | 
					
						
							|  |  |  |             <div v-for="p in provinces" :key="p.id" class="picker-item"> | 
					
						
							|  |  |  |               {{ p.name }} | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           </picker-view-column> | 
					
						
							|  |  |  |           <picker-view-column> | 
					
						
							|  |  |  |             <div v-for="c in cities" :key="c.id" class="picker-item"> | 
					
						
							|  |  |  |               {{ c.name }} | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           </picker-view-column> | 
					
						
							|  |  |  |           <picker-view-column> | 
					
						
							|  |  |  |             <div v-for="d in districts" :key="d.id" class="picker-item"> | 
					
						
							|  |  |  |               {{ d.name }} | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           </picker-view-column> | 
					
						
							|  |  |  |         </picker-view> | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |       </div> | 
					
						
							|  |  |  |       <div class="popup-footer"> | 
					
						
							|  |  |  |         <button class="popup-btn popup-cancel" @click="handleClose"> | 
					
						
							|  |  |  |           取消 | 
					
						
							|  |  |  |         </button> | 
					
						
							|  |  |  |         <button class="popup-btn popup-confirm" @click="handleConfirm"> | 
					
						
							|  |  |  |           确认 | 
					
						
							|  |  |  |         </button> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   </div> | 
					
						
							|  |  |  | </template> | 
					
						
							| 
									
										
										
										
											2025-06-11 11:24:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | <script> | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  | import { getRegionSelect, setRegion, getRegionAreaTree } from '@/config/mine.js' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-11 11:24:56 +08:00
										 |  |  | export default { | 
					
						
							|  |  |  |   name: 'region-select', | 
					
						
							|  |  |  |   data() { | 
					
						
							|  |  |  |     return { | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |       popupVisible: false, | 
					
						
							|  |  |  |       areaTree: [], | 
					
						
							|  |  |  |       provinces: [], | 
					
						
							|  |  |  |       cities: [], | 
					
						
							|  |  |  |       districts: [], | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  |       pickerValue: [0, 0, 0], | 
					
						
							|  |  |  |       indicatorStyle: `height: 50px;`, | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   async created() { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       const res = await getRegionSelect() | 
					
						
							|  |  |  |       if ( | 
					
						
							|  |  |  |         res.code === 200 && | 
					
						
							|  |  |  |         res.data && | 
					
						
							|  |  |  |         res.data.regionStatus === 0 && | 
					
						
							|  |  |  |         !res.data.province | 
					
						
							|  |  |  |       ) { | 
					
						
							| 
									
										
										
										
											2025-06-12 18:04:32 +08:00
										 |  |  |         this.open() | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } catch (error) { | 
					
						
							|  |  |  |       console.error('Failed to get region select info:', error) | 
					
						
							| 
									
										
										
										
											2025-06-11 11:24:56 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |   methods: { | 
					
						
							| 
									
										
										
										
											2025-06-12 18:04:32 +08:00
										 |  |  |     async open() { | 
					
						
							|  |  |  |       return new Promise(async (resolve, reject) => { | 
					
						
							| 
									
										
										
										
											2025-06-12 20:21:33 +08:00
										 |  |  |         if (this.areaTree?.length === 0) { | 
					
						
							| 
									
										
										
										
											2025-06-12 18:04:32 +08:00
										 |  |  |           await this.loadAreaTree() | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         this.popupVisible = true | 
					
						
							|  |  |  |         resolve() | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |     async loadAreaTree() { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         const res = await getRegionAreaTree() | 
					
						
							|  |  |  |         if (res.code === 200 && res.data) { | 
					
						
							|  |  |  |           this.areaTree = res.data | 
					
						
							|  |  |  |           this.provinces = this.areaTree | 
					
						
							|  |  |  |           if (this.provinces.length > 0) { | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  |             this.cities = this.provinces[0].children || [] | 
					
						
							|  |  |  |             if (this.cities.length > 0) { | 
					
						
							|  |  |  |               this.districts = this.cities[0].children || [] | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               this.districts = [] | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } catch (error) { | 
					
						
							|  |  |  |         console.error('Failed to load area tree:', error) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  |     handlePickerChange(e) { | 
					
						
							|  |  |  |       const [pIndex, cIndex] = e.detail.value | 
					
						
							|  |  |  |       const oldPIndex = this.pickerValue[0] | 
					
						
							|  |  |  |       const oldCIndex = this.pickerValue[1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.pickerValue = e.detail.value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (pIndex !== oldPIndex) { | 
					
						
							|  |  |  |         this.cities = this.provinces[pIndex]?.children || [] | 
					
						
							|  |  |  |         this.districts = this.cities[0]?.children || [] | 
					
						
							|  |  |  |       } else if (cIndex !== oldCIndex) { | 
					
						
							|  |  |  |         this.districts = this.cities[cIndex]?.children || [] | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     handleClose() { | 
					
						
							|  |  |  |       this.popupVisible = false | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     async handleConfirm() { | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  |       const [pIndex, cIndex, dIndex] = this.pickerValue | 
					
						
							|  |  |  |       const province = this.provinces[pIndex] | 
					
						
							|  |  |  |       const city = this.cities[cIndex] | 
					
						
							|  |  |  |       const district = this.districts[dIndex] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!province || !city || !district) { | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |         return | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         const params = { | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  |           province: province.id, | 
					
						
							|  |  |  |           city: city.id, | 
					
						
							|  |  |  |           county: district.id, | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         const res = await setRegion(params) | 
					
						
							|  |  |  |         if (res.code === 200) { | 
					
						
							|  |  |  |           this.handleClose() | 
					
						
							|  |  |  |           this.$emit('success') | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           throw new Error(res.message || 'Failed to set region') | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } catch (error) { | 
					
						
							|  |  |  |         console.error('Failed to set region:', error) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2025-06-11 11:24:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  | <style scoped> | 
					
						
							|  |  |  | .region-select-overlay { | 
					
						
							|  |  |  |   position: fixed; | 
					
						
							|  |  |  |   top: 0; | 
					
						
							|  |  |  |   left: 0; | 
					
						
							|  |  |  |   width: 100%; | 
					
						
							|  |  |  |   height: 100%; | 
					
						
							|  |  |  |   background-color: rgba(0, 0, 0, 0.5); | 
					
						
							|  |  |  |   display: flex; | 
					
						
							|  |  |  |   align-items: center; | 
					
						
							|  |  |  |   justify-content: center; | 
					
						
							|  |  |  |   z-index: 1000; | 
					
						
							|  |  |  |   transition: opacity 0.3s ease; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .region-select-popup { | 
					
						
							|  |  |  |   width: 90%; | 
					
						
							|  |  |  |   max-width: 680rpx; | 
					
						
							|  |  |  |   background-color: white; | 
					
						
							|  |  |  |   border-radius: 24rpx; | 
					
						
							|  |  |  |   animation: scale-up 0.3s ease-out; | 
					
						
							|  |  |  |   max-height: 80vh; | 
					
						
							|  |  |  |   display: flex; | 
					
						
							|  |  |  |   flex-direction: column; | 
					
						
							|  |  |  |   overflow: hidden; | 
					
						
							|  |  |  |   box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-header { | 
					
						
							|  |  |  |   display: flex; | 
					
						
							|  |  |  |   justify-content: center; | 
					
						
							|  |  |  |   align-items: center; | 
					
						
							|  |  |  |   padding: 30rpx; | 
					
						
							|  |  |  |   border-bottom: 1rpx solid #f5f5f5; | 
					
						
							|  |  |  |   flex-shrink: 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-title { | 
					
						
							|  |  |  |   font-size: 32rpx; | 
					
						
							|  |  |  |   font-weight: 600; | 
					
						
							|  |  |  |   color: #1c1c1e; | 
					
						
							|  |  |  |   margin: 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-btn { | 
					
						
							|  |  |  |   border: none; | 
					
						
							|  |  |  |   background: none; | 
					
						
							|  |  |  |   cursor: pointer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-content { | 
					
						
							|  |  |  |   overflow: hidden; | 
					
						
							|  |  |  |   flex-grow: 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  | .picker-view { | 
					
						
							|  |  |  |   width: 100%; | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |   height: 500rpx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-11 14:14:00 +08:00
										 |  |  | .picker-item { | 
					
						
							|  |  |  |   display: flex; | 
					
						
							|  |  |  |   align-items: center; | 
					
						
							|  |  |  |   justify-content: center; | 
					
						
							|  |  |  |   height: 50px; | 
					
						
							| 
									
										
										
										
											2025-06-11 14:09:05 +08:00
										 |  |  |   font-size: 30rpx; | 
					
						
							|  |  |  |   color: #666; | 
					
						
							|  |  |  |   white-space: nowrap; | 
					
						
							|  |  |  |   overflow: hidden; | 
					
						
							|  |  |  |   text-overflow: ellipsis; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-footer { | 
					
						
							|  |  |  |   display: flex; | 
					
						
							|  |  |  |   flex-shrink: 0; | 
					
						
							|  |  |  |   padding: 24rpx; | 
					
						
							|  |  |  |   gap: 24rpx; | 
					
						
							|  |  |  |   background-color: #f7f7f7; | 
					
						
							|  |  |  |   border-top: 1rpx solid #efefef; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-footer .popup-btn { | 
					
						
							|  |  |  |   flex: 1; | 
					
						
							|  |  |  |   text-align: center; | 
					
						
							|  |  |  |   padding: 14rpx 0; | 
					
						
							|  |  |  |   font-size: 28rpx; | 
					
						
							|  |  |  |   border-radius: 40rpx; | 
					
						
							|  |  |  |   font-weight: 500; | 
					
						
							|  |  |  |   transition: | 
					
						
							|  |  |  |     transform 0.1s ease, | 
					
						
							|  |  |  |     box-shadow 0.2s ease; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-footer .popup-btn:active { | 
					
						
							|  |  |  |   transform: scale(0.97); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-footer .popup-cancel { | 
					
						
							|  |  |  |   background-color: #eee; | 
					
						
							|  |  |  |   color: #555; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .popup-footer .popup-confirm { | 
					
						
							|  |  |  |   background: linear-gradient(135deg, #007aff, #0056b3); | 
					
						
							|  |  |  |   color: white; | 
					
						
							|  |  |  |   box-shadow: 0 4rpx 12rpx rgba(0, 122, 255, 0.25); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @keyframes scale-up { | 
					
						
							|  |  |  |   from { | 
					
						
							|  |  |  |     transform: scale(0.8); | 
					
						
							|  |  |  |     opacity: 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   to { | 
					
						
							|  |  |  |     transform: scale(1); | 
					
						
							|  |  |  |     opacity: 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | </style> |