feat(家庭创建): 完善创建家庭页面功能并优化样式
添加家训口令输入框和头像上传功能 实现图片预览和删除功能 优化表单验证和错误提示 更新页面导航标题和样式 移除无用代码并添加环境配置
Showing
8 changed files
with
292 additions
and
214 deletions
| ... | @@ -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' | ... | ... |
-
Please register or login to post a comment