hookehuyr

feat(创建家庭): 添加区域战队选择功能并更新背景色

将家庭规模选择替换为区域战队选择功能,增加区域选择器组件
更新页面背景色为浅灰色(#F9FAFB)
1 <!-- 1 <!--
2 * @Date: 2025-08-27 17:44:53 2 * @Date: 2025-08-27 17:44:53
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-08-29 10:37:54 4 + * @LastEditTime: 2025-08-29 13:58:07
5 * @FilePath: /lls_program/src/pages/CreateFamily/index.vue 5 * @FilePath: /lls_program/src/pages/CreateFamily/index.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
8 <template> 8 <template>
9 - <view class="min-h-screen flex flex-col bg-white"> 9 + <view class="min-h-screen flex flex-col bg-[#F9FAFB]">
10 <!-- <AppHeader title="创建家庭" /> --> 10 <!-- <AppHeader title="创建家庭" /> -->
11 <view class="flex-1 px-4 py-6 overflow-auto"> 11 <view class="flex-1 px-4 py-6 overflow-auto">
12 <view class="mb-6"> 12 <view class="mb-6">
...@@ -37,23 +37,16 @@ ...@@ -37,23 +37,16 @@
37 /> 37 />
38 </view> 38 </view>
39 </view> 39 </view>
40 - <!-- Family Size --> 40 + <!-- District Selection -->
41 <view class="mb-6"> 41 <view class="mb-6">
42 <view class="bg-white rounded-lg border border-gray-200 p-4"> 42 <view class="bg-white rounded-lg border border-gray-200 p-4">
43 - <view class="block text-lg font-medium mb-4">家庭规模</view> 43 + <view class="block text-lg font-medium mb-4">快来挑选加入哪个区域战队</view>
44 - <view class="flex gap-2"> 44 + <view class="bg-white rounded-xl p-4 border border-gray-200" @click="showDistrictPicker = true">
45 - <view 45 + <view class="flex justify-between items-center">
46 - v-for="size in familySizes" 46 + <text :class="{'text-gray-400': !selectedDistrictText, 'text-gray-900': selectedDistrictText}" class="text-base">
47 - :key="size" 47 + {{ selectedDistrictText || '请选择区域' }}
48 - @click="familySize = size" 48 + </text>
49 - :class="[ 49 + <Right size="16" color="#888" />
50 - 'flex-1 py-3 rounded-lg border text-center',
51 - familySize === size
52 - ? 'border-blue-500 bg-blue-50 text-blue-500'
53 - : 'border-gray-200 text-gray-700'
54 - ]"
55 - >
56 - {{ size }}
57 </view> 50 </view>
58 </view> 51 </view>
59 </view> 52 </view>
...@@ -124,7 +117,7 @@ ...@@ -124,7 +117,7 @@
124 <!-- 上传区域 --> 117 <!-- 上传区域 -->
125 <view 118 <view
126 v-if="!familyAvatar" 119 v-if="!familyAvatar"
127 - class="border border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center" 120 + class="border border-dashed border-gray-200 rounded-lg p-6 flex flex-col items-center justify-center"
128 @click="chooseImage" 121 @click="chooseImage"
129 > 122 >
130 <view class="text-gray-400 mb-2"> 123 <view class="text-gray-400 mb-2">
...@@ -159,22 +152,55 @@ ...@@ -159,22 +152,55 @@
159 :init-no="previewIndex" 152 :init-no="previewIndex"
160 @close="closePreview" 153 @close="closePreview"
161 /> 154 />
155 +
156 + <!-- 区域选择器 -->
157 + <nut-popup v-model:visible="showDistrictPicker" position="bottom">
158 + <nut-picker
159 + v-model="districtValue"
160 + :columns="districtColumns"
161 + @confirm="onDistrictConfirm"
162 + @cancel="showDistrictPicker = false"
163 + title="选择区域战队"
164 + ></nut-picker>
165 + </nut-popup>
162 </view> 166 </view>
163 </template> 167 </template>
164 168
165 <script setup> 169 <script setup>
166 import { ref, nextTick, computed } from 'vue'; 170 import { ref, nextTick, computed } from 'vue';
167 import Taro from '@tarojs/taro'; 171 import Taro from '@tarojs/taro';
168 -import { Edit, Tips, Photograph } from '@nutui/icons-vue-taro'; 172 +import { Edit, Tips, Photograph, Right } from '@nutui/icons-vue-taro';
169 // import AppHeader from '../../components/AppHeader.vue'; 173 // import AppHeader from '../../components/AppHeader.vue';
170 import BASE_URL from '@/utils/config'; 174 import BASE_URL from '@/utils/config';
171 175
172 const familyName = ref(''); 176 const familyName = ref('');
173 const familyIntro = ref(''); 177 const familyIntro = ref('');
174 -const familySize = ref('3-5人'); 178 +const selectedDistrict = ref(null);
179 +const selectedDistrictText = ref('');
175 const familyMotto = ref(['', '', '', '']); 180 const familyMotto = ref(['', '', '', '']);
176 const familyMottoPlaceholder = ref(['孝', '敬', '和', '睦']); 181 const familyMottoPlaceholder = ref(['孝', '敬', '和', '睦']);
177 -const familySizes = ['2人', '3-5人', '6人+']; 182 +
183 +// 区域选择器相关
184 +const showDistrictPicker = ref(false);
185 +const districtValue = ref([]);
186 +const districtColumns = ref([
187 + { text: '黄浦区', value: 310101 },
188 + { text: '徐汇区', value: 310104 },
189 + { text: '长宁区', value: 310105 },
190 + { text: '静安区', value: 310106 },
191 + { text: '普陀区', value: 310107 },
192 + { text: '虹口区', value: 310109 },
193 + { text: '杨浦区', value: 310110 },
194 + { text: '闵行区', value: 310112 },
195 + { text: '宝山区', value: 310113 },
196 + { text: '嘉定区', value: 310114 },
197 + { text: '浦东新区', value: 310115 },
198 + { text: '金山区', value: 310116 },
199 + { text: '松江区', value: 310117 },
200 + { text: '青浦区', value: 310118 },
201 + { text: '奉贤区', value: 310120 },
202 + { text: '崇明区', value: 310151 }
203 +]);
178 const familyAvatar = ref(''); 204 const familyAvatar = ref('');
179 const focusedIndex = ref(-1); 205 const focusedIndex = ref(-1);
180 const inputRefs = ref([]); 206 const inputRefs = ref([]);
...@@ -183,10 +209,21 @@ const isFormValid = computed(() => { ...@@ -183,10 +209,21 @@ const isFormValid = computed(() => {
183 return ( 209 return (
184 familyName.value.trim() !== '' && 210 familyName.value.trim() !== '' &&
185 familyIntro.value.trim() !== '' && 211 familyIntro.value.trim() !== '' &&
212 + selectedDistrict.value !== null &&
186 familyMotto.value.every(char => char.trim() !== '') 213 familyMotto.value.every(char => char.trim() !== '')
187 ); 214 );
188 }); 215 });
189 216
217 +/**
218 + * @description 确认选择区域
219 + * @param {object} param0 - 包含 selectedValue 和 selectedOptions 的对象
220 + */
221 +const onDistrictConfirm = ({ selectedValue, selectedOptions }) => {
222 + selectedDistrict.value = selectedValue[0];
223 + selectedDistrictText.value = selectedOptions.map((option) => option.text).join('');
224 + showDistrictPicker.value = false;
225 +};
226 +
190 // 图片预览相关 227 // 图片预览相关
191 const previewVisible = ref(false); 228 const previewVisible = ref(false);
192 const previewImages = ref([]); 229 const previewImages = ref([]);
......