hookehuyr

feat(家庭创建): 完善创建家庭页面功能并优化样式

添加家训口令输入框和头像上传功能
实现图片预览和删除功能
优化表单验证和错误提示
更新页面导航标题和样式
移除无用代码并添加环境配置
...@@ -11,6 +11,10 @@ declare module 'vue' { ...@@ -11,6 +11,10 @@ declare module 'vue' {
11 BottomNav: typeof import('./src/components/BottomNav.vue')['default'] 11 BottomNav: typeof import('./src/components/BottomNav.vue')['default']
12 GlassCard: typeof import('./src/components/GlassCard.vue')['default'] 12 GlassCard: typeof import('./src/components/GlassCard.vue')['default']
13 NavBar: typeof import('./src/components/navBar.vue')['default'] 13 NavBar: typeof import('./src/components/navBar.vue')['default']
14 + NutImage: typeof import('@nutui/nutui-taro')['Image']
15 + NutImagePreview: typeof import('@nutui/nutui-taro')['ImagePreview']
16 + NutInput: typeof import('@nutui/nutui-taro')['Input']
17 + NutToast: typeof import('@nutui/nutui-taro')['Toast']
14 Picker: typeof import('./src/components/time-picker-data/picker.vue')['default'] 18 Picker: typeof import('./src/components/time-picker-data/picker.vue')['default']
15 PointsCollector: typeof import('./src/components/PointsCollector.vue')['default'] 19 PointsCollector: typeof import('./src/components/PointsCollector.vue')['default']
16 PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default'] 20 PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default']
......
1 <template> 1 <template>
2 - <view class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 flex justify-around py-2"> 2 + <view class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 flex justify-around py-2 z-50">
3 <view 3 <view
4 v-for="item in navItems" 4 v-for="item in navItems"
5 :key="item.path" 5 :key="item.path"
......
1 +/*
2 + * @Date: 2025-08-27 18:25:10
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-08-27 20:02:27
5 + * @FilePath: /lls_program/src/pages/CreateFamily/index.config.js
6 + * @Description: 文件描述
7 + */
1 export default { 8 export default {
2 - navigationBarTitleText: '首页' 9 + navigationBarTitleText: '创建家庭'
3 } 10 }
......
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-27 18:05:54 4 + * @LastEditTime: 2025-08-27 20:51:19
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-white">
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">
13 - <p class="text-gray-600 mb-6"> 13 + <view class="text-gray-600 mb-6">
14 请填写家庭信息,创建您的专属家庭空间 14 请填写家庭信息,创建您的专属家庭空间
15 - </p> 15 + </view>
16 <!-- Family Name --> 16 <!-- Family Name -->
17 <view class="mb-6"> 17 <view class="mb-6">
18 <view class="bg-white rounded-lg border border-gray-200 p-4"> 18 <view class="bg-white rounded-lg border border-gray-200 p-4">
19 - <label class="block text-lg font-medium mb-2">家庭名称</label> 19 + <view class="block text-lg font-medium mb-2">家庭名称</view>
20 <input 20 <input
21 type="text" 21 type="text"
22 v-model="familyName" 22 v-model="familyName"
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 <!-- Family Introduction --> 28 <!-- Family Introduction -->
29 <view class="mb-6"> 29 <view class="mb-6">
30 <view class="bg-white rounded-lg border border-gray-200 p-4"> 30 <view class="bg-white rounded-lg border border-gray-200 p-4">
31 - <label class="block text-lg font-medium mb-2">家庭介绍</label> 31 + <view class="block text-lg font-medium mb-2">家庭介绍</view>
32 <textarea 32 <textarea
33 v-model="familyIntro" 33 v-model="familyIntro"
34 class="w-full text-gray-600 focus:outline-none resize-none" 34 class="w-full text-gray-600 focus:outline-none resize-none"
...@@ -40,21 +40,21 @@ ...@@ -40,21 +40,21 @@
40 <!-- Family Size --> 40 <!-- Family Size -->
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 - <label class="block text-lg font-medium mb-4">家庭规模</label> 43 + <view class="block text-lg font-medium mb-4">家庭规模</view>
44 <view class="flex gap-2"> 44 <view class="flex gap-2">
45 - <button 45 + <view
46 v-for="size in familySizes" 46 v-for="size in familySizes"
47 :key="size" 47 :key="size"
48 @click="familySize = size" 48 @click="familySize = size"
49 :class="[ 49 :class="[
50 - 'flex-1 py-3 rounded-lg border', 50 + 'flex-1 py-3 rounded-lg border text-center',
51 familySize === size 51 familySize === size
52 ? 'border-blue-500 bg-blue-50 text-blue-500' 52 ? 'border-blue-500 bg-blue-50 text-blue-500'
53 : 'border-gray-200 text-gray-700' 53 : 'border-gray-200 text-gray-700'
54 ]" 54 ]"
55 > 55 >
56 {{ size }} 56 {{ size }}
57 - </button> 57 + </view>
58 </view> 58 </view>
59 </view> 59 </view>
60 </view> 60 </view>
...@@ -62,103 +62,286 @@ ...@@ -62,103 +62,286 @@
62 <view class="mb-6"> 62 <view class="mb-6">
63 <view class="bg-white rounded-lg border border-gray-200 p-4"> 63 <view class="bg-white rounded-lg border border-gray-200 p-4">
64 <view class="flex justify-between items-center mb-4"> 64 <view class="flex justify-between items-center mb-4">
65 - <label class="block text-lg font-medium">家训口令</label> 65 + <view class="block text-lg font-medium">家训口令</view>
66 - <button 66 + <!-- <view
67 @click="generateRandomMotto" 67 @click="generateRandomMotto"
68 class="px-3 py-1 bg-blue-100 text-blue-600 rounded-full text-sm" 68 class="px-3 py-1 bg-blue-100 text-blue-600 rounded-full text-sm"
69 > 69 >
70 随机生成 70 随机生成
71 - </button> 71 + </view> -->
72 </view> 72 </view>
73 <view class="flex gap-2 mb-4"> 73 <view class="flex gap-2 mb-4">
74 <view v-for="(char, index) in familyMotto" :key="index" class="flex-1"> 74 <view v-for="(char, index) in familyMotto" :key="index" class="flex-1">
75 + <view class="w-full aspect-square flex items-center justify-center bg-gray-100 rounded-lg">
75 <input 76 <input
76 type="text" 77 type="text"
77 v-model="familyMotto[index]" 78 v-model="familyMotto[index]"
79 + :placeholder="familyMottoPlaceholder[index]"
78 maxlength="1" 80 maxlength="1"
79 - class="w-full aspect-square flex items-center justify-center text-center text-xl bg-gray-100 rounded-lg" 81 + class="w-full h-full bg-transparent text-center"
82 + style="font-size: 38rpx;"
80 /> 83 />
81 </view> 84 </view>
82 - <view class="flex-1 flex items-center justify-center"> 85 + </view>
83 - <button class="w-full aspect-square flex items-center justify-center bg-gray-100 rounded-lg text-blue-500"> 86 + <!-- <view class="flex-1 flex items-center justify-center">
87 + <view class="w-full aspect-square flex items-center justify-center bg-gray-100 rounded-lg text-blue-500">
84 <Edit size="20" /> 88 <Edit size="20" />
85 - </button>
86 </view> 89 </view>
90 + </view> -->
87 </view> 91 </view>
88 <view class="flex items-center text-sm text-gray-600"> 92 <view class="flex items-center text-sm text-gray-600">
89 - <Bulb size="16" class="text-yellow-500 mr-2" /> 93 + <Tips size="16" class="text-yellow-500 mr-2" />
90 - <p>设置有意义的家训口令,便于家人记忆和加入</p> 94 + <view>设置有意义的家训口令,便于家人记忆和加入</view>
91 </view> 95 </view>
92 </view> 96 </view>
93 </view> 97 </view>
94 <!-- Family Avatar --> 98 <!-- Family Avatar -->
95 <view class="mb-10"> 99 <view class="mb-10">
96 <view class="bg-white rounded-lg border border-gray-200 p-4"> 100 <view class="bg-white rounded-lg border border-gray-200 p-4">
97 - <label class="block text-lg font-medium mb-2"> 101 + <view class="block text-lg font-medium mb-2">
98 家庭头像(选填) 102 家庭头像(选填)
99 - </label> 103 + </view>
104 + <!-- 已上传头像显示 -->
105 + <view v-if="familyAvatar" class="mb-4">
106 + <view class="relative inline-block">
107 + <image
108 + :src="familyAvatar"
109 + class="w-24 h-24 rounded-lg object-cover"
110 + mode="aspectFill"
111 + @tap="previewAvatar"
112 + />
100 <view 113 <view
114 + @click="deleteAvatar"
115 + class="absolute -top-2 -right-2 w-5 h-5 bg-red-500 rounded-full flex items-center justify-center"
116 + >
117 + <view class="text-white text-xs">×</view>
118 + </view>
119 + </view>
120 + </view>
121 + <!-- 上传区域 -->
122 + <view
123 + v-if="!familyAvatar"
101 class="border border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center" 124 class="border border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center"
102 @click="chooseImage" 125 @click="chooseImage"
103 > 126 >
104 <view class="text-gray-400 mb-2"> 127 <view class="text-gray-400 mb-2">
105 - <Image size="24" /> 128 + <Photograph size="24" />
129 + </view>
130 + <view class="text-center text-gray-400">点击上传图片</view>
131 + <view class="text-center text-gray-400 text-xs mt-1">
132 + 支持jpg、png格式,大小不超过10MB
106 </view> 133 </view>
107 - <p class="text-center text-gray-400">点击上传图片</p>
108 - <p class="text-center text-gray-400 text-xs mt-1">
109 - 支持jpg、png格式,大小不超过2MB
110 - </p>
111 </view> 134 </view>
112 </view> 135 </view>
113 </view> 136 </view>
114 </view> 137 </view>
115 <!-- Submit Button --> 138 <!-- Submit Button -->
116 - <button 139 + <view
117 @click="handleCreateFamily" 140 @click="handleCreateFamily"
118 - class="w-full py-4 bg-blue-500 text-white text-lg font-medium rounded-lg" 141 + class="w-full py-4 bg-blue-500 text-white text-lg font-medium rounded-lg flex items-center justify-center"
119 > 142 >
120 创建家庭 143 创建家庭
121 - </button>
122 </view> 144 </view>
123 </view> 145 </view>
146 +
147 +
148 +
149 + <!-- 图片预览 -->
150 + <nut-image-preview
151 + v-model:show="previewVisible"
152 + :images="previewImages"
153 + :init-no="previewIndex"
154 + @close="closePreview"
155 + />
156 + </view>
124 </template> 157 </template>
125 158
126 <script setup> 159 <script setup>
127 import { ref } from 'vue'; 160 import { ref } from 'vue';
128 import Taro from '@tarojs/taro'; 161 import Taro from '@tarojs/taro';
129 -import { Edit, Bulb, Image } from '@nutui/icons-vue-taro'; 162 +import { Edit, Tips, Photograph } from '@nutui/icons-vue-taro';
130 -import AppHeader from '../../components/AppHeader.vue'; 163 +// import AppHeader from '../../components/AppHeader.vue';
164 +import BASE_URL from '@/utils/config';
131 165
132 const familyName = ref(''); 166 const familyName = ref('');
133 const familyIntro = ref(''); 167 const familyIntro = ref('');
134 const familySize = ref('3-5人'); 168 const familySize = ref('3-5人');
135 -const familyMotto = ref(['孝', '敬', '和', '睦']); 169 +const familyMotto = ref(['', '', '', '']);
170 +const familyMottoPlaceholder = ref(['孝', '敬', '和', '睦']);
136 const familySizes = ['2人', '3-5人', '6人+']; 171 const familySizes = ['2人', '3-5人', '6人+'];
172 +const familyAvatar = ref('');
173 +
174 +
175 +
176 +// 图片预览相关
177 +const previewVisible = ref(false);
178 +const previewImages = ref([]);
179 +const previewIndex = ref(0);
180 +
181 +// const generateRandomMotto = () => {
182 +// // 在实际应用中,这里会生成随机家训
183 +// // 目前仅作为演示使用预设值
184 +// familyMotto.value = ['爱', '和', '勤', '俭'];
185 +// };
137 186
138 -const generateRandomMotto = () => { 187 +/**
139 - // 在实际应用中,这里会生成随机家训 188 + * 显示提示信息
140 - // 目前仅作为演示使用预设值 189 + */
141 - familyMotto.value = ['爱', '和', '勤', '俭']; 190 +const showToast = (message, type = 'success') => {
191 + const icon = type === 'error' ? 'error' : 'success';
192 + Taro.showToast({
193 + title: message,
194 + icon: icon,
195 + duration: 2000
196 + });
142 }; 197 };
143 198
199 +/**
200 + * 选择图片
201 + */
144 const chooseImage = () => { 202 const chooseImage = () => {
145 Taro.chooseImage({ 203 Taro.chooseImage({
146 count: 1, 204 count: 1,
147 sizeType: ['compressed'], 205 sizeType: ['compressed'],
148 sourceType: ['album', 'camera'], 206 sourceType: ['album', 'camera'],
149 - success: (res) => { 207 + success: function (res) {
150 - const tempFilePaths = res.tempFilePaths; 208 + const tempFilePath = res.tempFilePaths[0];
151 - // 在实际应用中,这里会上传图片到服务器 209 +
152 - console.log('选择的图片路径:', tempFilePaths); 210 + // 检查文件大小(10MB = 10 * 1024 * 1024 bytes)
211 + Taro.getFileInfo({
212 + filePath: tempFilePath,
213 + success: function (fileInfo) {
214 + if (fileInfo.size > 10 * 1024 * 1024) {
215 + showToast('图片大小不能超过10MB', 'error');
216 + return;
217 + }
218 + uploadImage(tempFilePath);
219 + },
220 + fail: function () {
221 + // 如果获取文件信息失败,直接上传
222 + uploadImage(tempFilePath);
223 + }
224 + });
225 + },
226 + fail: function () {
227 + showToast('选择图片失败', 'error');
153 } 228 }
154 }); 229 });
155 }; 230 };
156 231
232 +/**
233 + * 上传图片到服务器
234 + */
235 +const uploadImage = (filePath) => {
236 + // 显示上传中提示
237 + Taro.showLoading({
238 + title: '上传中',
239 + mask: true
240 + });
241 +
242 + wx.uploadFile({
243 + url: BASE_URL + '/admin/?m=srv&a=upload',
244 + filePath,
245 + name: 'file',
246 + header: {
247 + 'content-type': 'multipart/form-data',
248 + },
249 + success: function (res) {
250 + let upload_data = JSON.parse(res.data);
251 + Taro.hideLoading({
252 + success: () => {
253 + if (res.statusCode === 200) {
254 + familyAvatar.value = upload_data.data.src;
255 + showToast('上传成功', 'success');
256 + } else {
257 + showToast('服务器错误,稍后重试!', 'error');
258 + }
259 + },
260 + });
261 + },
262 + fail: function (res) {
263 + Taro.hideLoading({
264 + success: () => {
265 + showToast('上传失败,稍后重试!', 'error');
266 + }
267 + });
268 + }
269 + });
270 +};
271 +
272 +/**
273 + * 预览头像
274 + */
275 +const previewAvatar = () => {
276 + if (!familyAvatar.value) {
277 + showToast('暂无图片可预览', 'error');
278 + return;
279 + }
280 + previewImages.value = [{ src: familyAvatar.value }];
281 + previewIndex.value = 0;
282 + previewVisible.value = true;
283 +};
284 +
285 +/**
286 + * 删除头像
287 + */
288 +const deleteAvatar = () => {
289 + familyAvatar.value = '';
290 + showToast('头像已删除', 'success');
291 +};
292 +
293 +/**
294 + * 关闭预览
295 + */
296 +const closePreview = () => {
297 + previewVisible.value = false;
298 +};
299 +
300 +/**
301 + * 表单验证
302 + */
303 +const validateForm = () => {
304 + if (!familyName.value.trim()) {
305 + showToast('请输入家庭名称', 'error');
306 + return false;
307 + }
308 +
309 + if (!familyIntro.value.trim()) {
310 + showToast('请输入家庭介绍', 'error');
311 + return false;
312 + }
313 +
314 + if (!familySize.value) {
315 + showToast('请选择家庭规模', 'error');
316 + return false;
317 + }
318 +
319 + // 检查家训口令是否完整填写
320 + const mottoComplete = familyMotto.value.every(char => char.trim() !== '');
321 + if (!mottoComplete) {
322 + showToast('请完整填写家训口令', 'error');
323 + return false;
324 + }
325 +
326 + return true;
327 +};
328 +
329 +/**
330 + * 创建家庭
331 + */
157 const handleCreateFamily = () => { 332 const handleCreateFamily = () => {
333 + if (!validateForm()) {
334 + return;
335 + }
336 +
158 // 在实际应用中,这里会调用API创建家庭 337 // 在实际应用中,这里会调用API创建家庭
159 // 目前仅作为演示跳转到仪表盘页面 338 // 目前仅作为演示跳转到仪表盘页面
339 + showToast('家庭创建成功', 'success');
340 +
341 + setTimeout(() => {
160 Taro.navigateTo({ 342 Taro.navigateTo({
161 url: '/pages/Dashboard/index' 343 url: '/pages/Dashboard/index'
162 }); 344 });
345 + }, 1500);
163 }; 346 };
164 </script> 347 </script>
......
1 +/*
2 + * @Date: 2025-08-27 18:25:54
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-08-27 19:58:26
5 + * @FilePath: /lls_program/src/pages/Welcome/index.config.js
6 + * @Description: 文件描述
7 + */
1 export default { 8 export default {
2 - navigationBarTitleText: '首页' 9 + navigationBarTitleText: '老来赛',
10 + navigationBarBackgroundColor: '#fff',
11 + navigationBarTextStyle: 'black'
3 } 12 }
......
1 <!-- 1 <!--
2 * @Date: 2025-08-27 17:43:45 2 * @Date: 2025-08-27 17:43:45
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-08-27 18:21:32 4 + * @LastEditTime: 2025-08-27 19:58:08
5 * @FilePath: /lls_program/src/pages/Welcome/index.vue 5 * @FilePath: /lls_program/src/pages/Welcome/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-white">
10 <!-- Header --> 10 <!-- Header -->
11 - <header class="py-5 text-center"> 11 + <!-- <header class="py-5 text-center">
12 <h1 class="text-xl font-bold">老来赛</h1> 12 <h1 class="text-xl font-bold">老来赛</h1>
13 - </header> 13 + </header> -->
14 <!-- Main content --> 14 <!-- Main content -->
15 <view class="flex-1 flex flex-col px-4 pb-20"> 15 <view class="flex-1 flex flex-col px-4 pb-20">
16 <!-- Hero Image --> 16 <!-- Hero Image -->
...@@ -61,12 +61,12 @@ ...@@ -61,12 +61,12 @@
61 </view> 61 </view>
62 <!-- Action Buttons --> 62 <!-- Action Buttons -->
63 <view class="space-y-4 mt-auto"> 63 <view class="space-y-4 mt-auto">
64 - <button @click="navigateTo('/pages/CreateFamily/index')" class="w-full py-3.5 bg-blue-500 text-white text-lg font-medium rounded-full"> 64 + <view @click="navigateTo('/pages/CreateFamily/index')" class="w-full py-3.5 bg-blue-500 text-white text-lg font-medium rounded-full text-center">
65 创建家庭 65 创建家庭
66 - </button> 66 + </view>
67 - <button @click="navigateTo('/pages/JoinFamily/index')" class="w-full py-3.5 bg-white text-gray-800 text-lg font-medium rounded-full border border-gray-300"> 67 + <view @click="navigateTo('/pages/JoinFamily/index')" class="w-full py-3.5 bg-white text-gray-800 text-lg font-medium rounded-full border border-gray-300 text-center">
68 加入家庭 68 加入家庭
69 - </button> 69 + </view>
70 </view> 70 </view>
71 </view> 71 </view>
72 <!-- Bottom Navigation --> 72 <!-- Bottom Navigation -->
......
1 -<template>
2 - <view class="min-h-screen flex flex-col bg-white">
3 - <AppHeader title="创建家庭" />
4 - <view class="flex-1 px-4 py-6 overflow-auto">
5 - <view class="mb-6">
6 - <p class="text-gray-600 mb-6">
7 - 请填写家庭信息,创建您的专属家庭空间
8 - </p>
9 - <!-- Family Name -->
10 - <view class="mb-6">
11 - <view class="bg-white rounded-lg border border-gray-200 p-4">
12 - <label class="block text-lg font-medium mb-2">家庭名称</label>
13 - <input
14 - type="text"
15 - v-model="familyName"
16 - class="w-full text-gray-600 focus:outline-none"
17 - placeholder="请输入家庭名称"
18 - />
19 - </view>
20 - </view>
21 - <!-- Family Introduction -->
22 - <view class="mb-6">
23 - <view class="bg-white rounded-lg border border-gray-200 p-4">
24 - <label class="block text-lg font-medium mb-2">家庭介绍</label>
25 - <textarea
26 - v-model="familyIntro"
27 - class="w-full text-gray-600 focus:outline-none resize-none"
28 - placeholder="请输入您家庭的特色、成员特点等家庭标签"
29 - :rows="2"
30 - />
31 - </view>
32 - </view>
33 - <!-- Family Size -->
34 - <view class="mb-6">
35 - <view class="bg-white rounded-lg border border-gray-200 p-4">
36 - <label class="block text-lg font-medium mb-4">家庭规模</label>
37 - <view class="flex gap-2">
38 - <button
39 - v-for="size in familySizes"
40 - :key="size"
41 - @click="familySize = size"
42 - :class="[
43 - 'flex-1 py-3 rounded-lg border',
44 - familySize === size
45 - ? 'border-blue-500 bg-blue-50 text-blue-500'
46 - : 'border-gray-200 text-gray-700'
47 - ]"
48 - >
49 - {{ size }}
50 - </button>
51 - </view>
52 - </view>
53 - </view>
54 - <!-- Family Motto -->
55 - <view class="mb-6">
56 - <view class="bg-white rounded-lg border border-gray-200 p-4">
57 - <view class="flex justify-between items-center mb-4">
58 - <label class="block text-lg font-medium">家训口令</label>
59 - <button
60 - @click="generateRandomMotto"
61 - class="px-3 py-1 bg-blue-100 text-blue-600 rounded-full text-sm"
62 - >
63 - 随机生成
64 - </button>
65 - </view>
66 - <view class="flex gap-2 mb-4">
67 - <view v-for="(char, index) in familyMotto" :key="index" class="flex-1">
68 - <input
69 - type="text"
70 - v-model="familyMotto[index]"
71 - maxlength="1"
72 - class="w-full aspect-square flex items-center justify-center text-center text-xl bg-gray-100 rounded-lg"
73 - />
74 - </view>
75 - <view class="flex-1 flex items-center justify-center">
76 - <button class="w-full aspect-square flex items-center justify-center bg-gray-100 rounded-lg text-blue-500">
77 - <Edit size="20" />
78 - </button>
79 - </view>
80 - </view>
81 - <view class="flex items-center text-sm text-gray-600">
82 - <Bulb size="16" class="text-yellow-500 mr-2" />
83 - <p>设置有意义的家训口令,便于家人记忆和加入</p>
84 - </view>
85 - </view>
86 - </view>
87 - <!-- Family Avatar -->
88 - <view class="mb-10">
89 - <view class="bg-white rounded-lg border border-gray-200 p-4">
90 - <label class="block text-lg font-medium mb-2">
91 - 家庭头像(选填)
92 - </label>
93 - <view
94 - class="border border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center"
95 - @click="chooseImage"
96 - >
97 - <view class="text-gray-400 mb-2">
98 - <Image size="24" />
99 - </view>
100 - <p class="text-center text-gray-400">点击上传图片</p>
101 - <p class="text-center text-gray-400 text-xs mt-1">
102 - 支持jpg、png格式,大小不超过2MB
103 - </p>
104 - </view>
105 - </view>
106 - </view>
107 - </view>
108 - <!-- Submit Button -->
109 - <button
110 - @click="handleCreateFamily"
111 - class="w-full py-4 bg-blue-500 text-white text-lg font-medium rounded-lg"
112 - >
113 - 创建家庭
114 - </button>
115 - </view>
116 - </view>
117 -</template>
118 -
119 -<script setup>
120 -import { ref } from 'vue';
121 -import Taro from '@tarojs/taro';
122 -import { Edit, Bulb, Image } from '@nutui/icons-vue-taro';
123 -import AppHeader from '../../components/AppHeader.vue';
124 -
125 -const familyName = ref('');
126 -const familyIntro = ref('');
127 -const familySize = ref('3-5人');
128 -const familyMotto = ref(['孝', '敬', '和', '睦']);
129 -const familySizes = ['2人', '3-5人', '6人+'];
130 -
131 -const generateRandomMotto = () => {
132 - // 在实际应用中,这里会生成随机家训
133 - // 目前仅作为演示使用预设值
134 - familyMotto.value = ['爱', '和', '勤', '俭'];
135 -};
136 -
137 -const chooseImage = () => {
138 - Taro.chooseImage({
139 - count: 1,
140 - sizeType: ['compressed'],
141 - sourceType: ['album', 'camera'],
142 - success: (res) => {
143 - const tempFilePaths = res.tempFilePaths;
144 - // 在实际应用中,这里会上传图片到服务器
145 - console.log('选择的图片路径:', tempFilePaths);
146 - }
147 - });
148 -};
149 -
150 -const handleCreateFamily = () => {
151 - // 在实际应用中,这里会调用API创建家庭
152 - // 目前仅作为演示跳转到仪表盘页面
153 - Taro.navigateTo({
154 - url: '/pages/demo/Dashboard'
155 - });
156 -};
157 -</script>
1 /* 1 /*
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-01-15 17:07:14 4 + * @LastEditTime: 2025-08-27 20:41:05
5 - * @FilePath: /meihuaApp/src/utils/config.js 5 + * @FilePath: /lls_program/src/utils/config.js
6 - * @Description: 文件描述 6 + * @Description: 环境配置文件 - 根据小程序运行环境自动切换API地址
7 */ 7 */
8 -// TAG:服务器环境配置
9 -// const BASE_URL = "https://oa-dev.onwall.cn"; // 测试服务器
10 -const BASE_URL = "https://oa.onwall.cn"; // 正式服务器
11 8
12 -export default BASE_URL 9 +/**
10 + * 获取当前小程序运行环境对应的API地址
11 + * @returns {string} 对应环境的API基础地址
12 + */
13 +function getBaseUrl() {
14 + // 获取当前小程序的运行环境
15 + const accountInfo = wx.getAccountInfoSync();
16 + const envVersion = accountInfo.miniProgram.envVersion;
17 +
18 + // 定义不同环境的服务器地址
19 + let baseUrl = '';
20 + switch (envVersion) {
21 + case 'develop': // 开发版
22 + baseUrl = 'https://oa-dev.onwall.cn';
23 + break;
24 + case 'trial': // 体验版
25 + baseUrl = 'https://oa-dev.onwall.cn'; // 体验版暂时使用开发环境
26 + break;
27 + case 'release': // 正式版
28 + baseUrl = 'https://jiangedianlv.onwall.cn';
29 + break;
30 + default: // 未知环境,默认使用正式版地址
31 + baseUrl = 'https://jiangedianlv.onwall.cn';
32 + }
33 +
34 + // eslint-disable-next-line no-console
35 + console.log(`当前小程序环境: ${envVersion}, 使用API地址: ${baseUrl}`);
36 + return baseUrl;
37 +}
38 +
39 +// 导出API基础地址
40 +const BASE_URL = getBaseUrl();
41 +export default BASE_URL;
42 +
43 +// 默认封面图片地址
44 +export const DEFAULT_COVER_IMG = 'https://images.unsplash.com/photo-1558981806-ec527fa84c39?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'
......