From bfb1c4f2a9423ac3dac8b62b503acfc89afa1ac5 Mon Sep 17 00:00:00 2001 From: DU Date: Fri, 16 Jan 2026 17:08:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=91=E7=9A=84=E9=A1=B5=E9=9D=A2=EF=BC=8C?= =?UTF-8?q?=20=E6=88=91=E7=9A=84=E9=A1=B5=E9=9D=A2=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=8C=E6=88=91=E7=9A=84=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=88=86=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cursorrules | 12 +- .gitignore | 2 + src/assets/icon/phototake.png | Bin 0 -> 10504 bytes src/custom-tab-bar/index.scss | 122 ++++-------- src/custom-tab-bar/index.tsx | 6 + src/pages/index/index.scss | 6 +- src/pages/message/index.scss | 8 +- src/pages/store/index.scss | 7 +- src/pages/store/index.tsx | 17 +- src/pages/user/index.scss | 2 +- src/pagesUser/editProfile/index.config.ts | 9 +- src/pagesUser/editProfile/index.scss | 209 ++++++++++++++++++++- src/pagesUser/editProfile/index.tsx | 219 +++++++++++++++++++++- src/store/app.ts | 30 +++ src/store/index.ts | 3 + 15 files changed, 539 insertions(+), 113 deletions(-) create mode 100644 src/assets/icon/phototake.png create mode 100644 src/store/app.ts diff --git a/.cursorrules b/.cursorrules index 751ce41..4ffe28b 100644 --- a/.cursorrules +++ b/.cursorrules @@ -65,8 +65,9 @@ import { HomeOutlined } from '@taroify/icons' - 使用 SCSS - designWidth 为 750 -- 使用 px,会自动转换为 rpx +- 使用 px单位,会自动转换为 rpx - 使用 BEM 命名规范 +- 非特殊说明,不要使用PX ## 常用命令 @@ -83,7 +84,14 @@ npm run build:h5 # 编译 H5 ## 注意事项 1. MobX 组件必须用 `observer` 包裹 -2. Taroify 样式已全局引入 +2. Taroify 样式已引入, +3: 组件优先查看 taroify ui 库是否支持,再根据设计ui样式进行微调可使用 mcp 检查taroify 组件和api: + ``` + - mcp_taroifymcp_list-components:查看所有可用组件 + - mcp_taroifymcp_get-component-docs:获取组件详细文档 + - mcp_taroifymcp_get-component-props:获取组件 Props 和 API + - mcp_taroifymcp_list-component-example:查看组件示例 + ``` 3. 修改 TabBar 需同时更新 `custom-tab-bar/` 和 `app.config.ts` 4. 状态持久化使用 `Taro.setStorageSync` diff --git a/.gitignore b/.gitignore index c295b89..1b541e2 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ Thumbs.db # 环境变量 .env .env.local + +docs/ diff --git a/src/assets/icon/phototake.png b/src/assets/icon/phototake.png new file mode 100644 index 0000000000000000000000000000000000000000..b21effc254d926f4c03a94f1a3c7abc004a69b86 GIT binary patch literal 10504 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 literal 0 HcmV?d00001 diff --git a/src/custom-tab-bar/index.scss b/src/custom-tab-bar/index.scss index 3e72670..576506e 100644 --- a/src/custom-tab-bar/index.scss +++ b/src/custom-tab-bar/index.scss @@ -1,9 +1,9 @@ /** * 自定义 TabBar 样式 - 中间凸起 - * 参考:https://developer.aliyun.com/article/1228635 - * 已适配安全区域(iPhone X 等刘海屏) - * - * 注意:Taro 中 px 会被转换为 rpx,使用 Px (大写P) 可避免转换 + * TabBar高度: 129px + * scan图标: 130px × 130px (凸出30px) + * 其他图标: 40px × 37px + * 文本字号: 20px */ .custom-tab-bar { position: fixed; @@ -11,35 +11,35 @@ left: 0; right: 0; width: 100%; - height: 100Px; /* 继续减小高度,给凸起留足空间 */ + height: 129px; /* TabBar总高度 */ z-index: 99; pointer-events: none; - // 背景白色层 #0E0D0D + // 背景层 .tab-bar-bg { position: absolute; - top: 50px; + top: 40px; bottom: 0; left: 0; right: 0; - // height: 10Px; /* TabBar 实际高度 */ + height: 129px; background: #0E0D0D; - box-shadow: 0 -2Px 6Px rgba(0, 0, 0, 0.05); + box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.05); z-index: 1; pointer-events: auto; } - // 中间凸起的圆形白色背景 + // 中间凸起的圆形背景(如需要可以启用) .tab-bar-center-bg { position: absolute; - bottom: 25Px; /* 凸起高度 - 确保顶部不被截取 */ + // bottom: 29px; /* scan按钮底部位置 */ left: 50%; transform: translateX(-50%); - width: 120Px; - height: 120Px; - background: #ffffff; + width: 130px; + height: 130px; + background: blue; + // background: #0E0D0D; border-radius: 50%; - // box-shadow: 0 -2Px 8Px rgba(0, 0, 0, 0.08); z-index: 2; pointer-events: auto; } @@ -50,13 +50,12 @@ bottom: 0; left: 0; right: 0; - // top: -60px; display: flex; align-items: flex-end; justify-content: space-around; - height: 100%; - padding-bottom: 5Px; - padding-bottom: calc(5Px + env(safe-area-inset-bottom)); + height: 129px; + padding-bottom: 10px; + padding-bottom: calc(10px + env(safe-area-inset-bottom)); z-index: 3; pointer-events: auto; overflow: visible; /* 重要:允许子元素溢出显示 */ @@ -69,9 +68,8 @@ flex-direction: column; align-items: center; justify-content: flex-end; - height: 70Px; /* 普通项高度 */ + height: 100%; position: relative; - top: 30px; pointer-events: auto; // 普通 Tab 项内容 @@ -80,19 +78,18 @@ flex-direction: column; align-items: center; justify-content: center; - padding-bottom: 4Px; + padding-bottom: 0; .tab-icon { - width: 41px; - height: 41px; - - margin-bottom: 2Px; + width: 40px; + height: 37px; + margin-bottom: 5px; } .tab-text { font-size: 20px; color: #999999; - // line-height: 28Px; + line-height: 1.2; } } @@ -111,25 +108,23 @@ .scan-wrapper { position: absolute; - bottom: 10Px; /* 调整位置让按钮向上凸起,同时留出底部空间 */ + bottom: -10px; /* 让130px高的scan按钮凸出30px: 129px - (130px - 30px) = 29px */ left: 50%; transform: translateX(-50%); z-index: 10; - .scan-button { - width: 129px; - height: 129px; + width: 130px; + height: 130px; border-radius: 50%; - // background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background-color: #0E0D0D; + display: flex; align-items: center; justify-content: center; - box-shadow: 0 4Px 12Px rgba(102, 126, 234, 0.4); - // border: 5Px solid #ffffff; .scan-icon { - width: 129px; - height: 129px; + width: 110px; + height: 110px; } } } @@ -140,61 +135,14 @@ // iPhone X 及以上设备特殊适配 @supports (bottom: env(safe-area-inset-bottom)) { .custom-tab-bar { - .tab-bar-bg { - // 使用 constant 作为 env 的降级方案(iOS 11.0-11.2) - height: calc(60Px + constant(safe-area-inset-bottom)); - height: calc(60Px + env(safe-area-inset-bottom)); - } - } -} - -// 适配不同屏幕尺寸 -@media screen and (max-width: 320Px) { - .custom-tab-bar { - height: 90Px; + height: calc(129px + env(safe-area-inset-bottom)); .tab-bar-bg { - height: 55Px; - } - - .tab-bar-center-bg { - width: 65Px; - height: 65Px; - bottom: 22Px; - } - - .tab-item { - height: 55Px; - - &.center .scan-wrapper { - bottom: 10Px; - - .scan-button { - width: 58Px; - height: 58Px; - border-width: 4Px; - - .scan-icon { - width: 34Px; - height: 34Px; - } - } - } - } - - .tab-item .tab-content { - .tab-icon { - width: 28Px; - height: 28Px; - } - - .tab-text { - font-size: 20px; - } + height: calc(129px + env(safe-area-inset-bottom)); } - .tab-item.active .tab-content .tab-text { - color: #ffffff; + .tab-bar-content { + height: calc(129px + env(safe-area-inset-bottom)); } } } diff --git a/src/custom-tab-bar/index.tsx b/src/custom-tab-bar/index.tsx index c195aa8..b3cea50 100644 --- a/src/custom-tab-bar/index.tsx +++ b/src/custom-tab-bar/index.tsx @@ -6,6 +6,7 @@ import { CoverView, CoverImage } from '@tarojs/components' import Taro from '@tarojs/taro' import { observer } from 'mobx-react' import { TAB_BAR_CONFIG } from '../constants/config' +import { appStore } from '../store' import './index.scss' // 导入图标资源 @@ -59,6 +60,11 @@ const CustomTabBar = observer(() => { return isActive ? icons.active : icons.normal } + // 如果 TabBar 被隐藏,则不渲染 + if (!appStore.showTabBar) { + return null + } + return ( {/* 背景白色层 */} diff --git a/src/pages/index/index.scss b/src/pages/index/index.scss index 9b6b36c..2241b19 100644 --- a/src/pages/index/index.scss +++ b/src/pages/index/index.scss @@ -4,10 +4,8 @@ */ .index-page { - // 高度为 100vh 减去 tabbar 高度(100Px + 安全区域) - height: calc(100vh - 40Px); - height: calc(100vh - 40Px - constant(safe-area-inset-bottom)); // iOS 11.0-11.2 - height: calc(100vh - 40Px - env(safe-area-inset-bottom)); // iOS 11.2+ + // 高度为 100vh 减去 tabbar 高度 (129px) + height: calc(100vh - 129px + 40px - env(safe-area-inset-bottom)); background-color: #121212; position: relative; overflow-x: hidden; diff --git a/src/pages/message/index.scss b/src/pages/message/index.scss index 7a0fb60..69afa02 100644 --- a/src/pages/message/index.scss +++ b/src/pages/message/index.scss @@ -45,13 +45,9 @@ // Tab 内容区域 - 关键:给 ScrollView 明确的高度 .tab-content { width: 100%; - // 高度 = 100vh - tabbar(40Px) - Tabs标签栏(约88px) - 安全区域 - height: calc(100vh - 40Px - 88px); - height: calc(100vh - 40Px - 88px - constant(safe-area-inset-bottom)); - height: calc(100vh - 40Px - 88px - env(safe-area-inset-bottom)); + // 高度 = 100vh - tabbar(129px) - Tabs标签栏(约88px) - 安全区域 + height: calc(100vh - 129px - 88px - env(safe-area-inset-bottom)); background: #F2F3F5; - - } // 空状态 diff --git a/src/pages/store/index.scss b/src/pages/store/index.scss index 915e1a5..b950282 100644 --- a/src/pages/store/index.scss +++ b/src/pages/store/index.scss @@ -4,10 +4,8 @@ */ .store-page { - // 高度为 100vh 减去 tabbar 高度 - height: calc(100vh - 40Px); - height: calc(100vh - 40Px - constant(safe-area-inset-bottom)); - height: calc(100vh - 40Px - env(safe-area-inset-bottom)); + // 高度为 100vh 减去 tabbar 高度 (129px) + height: calc(100vh - 129px + 40px - env(safe-area-inset-bottom)); background-color: #121212; position: relative; overflow-x: hidden; @@ -245,6 +243,7 @@ } /* 城市选择弹窗 */ +/* 城市选择弹窗样式 */ .city-picker { background: #fff; border-radius: 20px 20px 0 0; diff --git a/src/pages/store/index.tsx b/src/pages/store/index.tsx index 39706fc..1a23bd2 100644 --- a/src/pages/store/index.tsx +++ b/src/pages/store/index.tsx @@ -4,10 +4,11 @@ import { View, Text, Image, Input, ScrollView } from '@tarojs/components' import Taro, { useLoad } from '@tarojs/taro' import { observer } from 'mobx-react' -import { useState } from 'react' +import { useState, useEffect } from 'react' import { Popup, Toast, Tabs } from '@taroify/core' import { useCascader } from '@taroify/hooks' import { Arrow, Cross, Search } from '@taroify/icons' +import { appStore } from '../../store' import storeIcon from '../../assets/icon/storeIcon.png' import locationIcon from '../../assets/icon/locationIcon.png' import './index.scss' @@ -120,6 +121,20 @@ const StoreIndex = observer(() => { console.log('门店页面加载') }) + // 监听弹窗状态,控制TabBar显示/隐藏 + useEffect(() => { + if (cityPopupOpen) { + appStore.hideTabBar() + } else { + appStore.showTabBarFn() + } + + // 组件卸载时恢复TabBar显示 + return () => { + appStore.showTabBarFn() + } + }, [cityPopupOpen]) + // 打开城市选择 const handleOpenCityPicker = () => { setCityPopupOpen(true) diff --git a/src/pages/user/index.scss b/src/pages/user/index.scss index f9eb6a9..c361989 100644 --- a/src/pages/user/index.scss +++ b/src/pages/user/index.scss @@ -156,7 +156,7 @@ } .stat-label { - margin-top: 27px; + margin-top: 20px; font-size: 25rpx; color: #B8B8B8; } diff --git a/src/pagesUser/editProfile/index.config.ts b/src/pagesUser/editProfile/index.config.ts index bda938d..76c2c08 100644 --- a/src/pagesUser/editProfile/index.config.ts +++ b/src/pagesUser/editProfile/index.config.ts @@ -1,5 +1,8 @@ export default { - navigationBarTitleText: '编辑资料', - navigationBarBackgroundColor: '#FFFFFF', - navigationBarTextStyle: 'black', + navigationBarTitleText: '个人信息', + navigationBarBackgroundColor: '#121212', + // navigationBarTextStyle 同时控制标题和返回按钮的颜色,只能是 'black' 或 'white' + navigationBarTextStyle: 'white', + // 不可滚动 + disableScroll: true, } diff --git a/src/pagesUser/editProfile/index.scss b/src/pagesUser/editProfile/index.scss index 68cecc1..60571cb 100644 --- a/src/pagesUser/editProfile/index.scss +++ b/src/pagesUser/editProfile/index.scss @@ -1,5 +1,210 @@ .edit-profile-page { min-height: 100vh; - background-color: #F2F3F5; - padding: 30px; + background-color: #121212; + + // 自定义导航栏 + .custom-navbar { + height: 88px; + background-color: #121212; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 30px; + position: relative; + + .navbar-left { + width: 60px; + height: 100%; + display: flex; + align-items: center; + } + + .navbar-title { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + + text { + font-size: 33rpx; + color: #FFFFFF; + font-weight: 500; + } + } + + .navbar-right { + width: 60px; + } + } + + // 内容区域 + .content-area { + padding: 0 30px; + + // 头像区域 + .avatar-section { + width: 100%; + height: 166px; + margin: 100px 0 82px; + display: flex; + align-items: center; + justify-content: center; + + .avatar-wrapper { + position: relative; + width: 166px; + height: 166px; + + .avatar { + width: 100%; + height: 100%; + display: block; + } + + :global { + .taroify-image { + width: 100%; + height: 100%; + display: block; + } + + .taroify-image__img { + width: 100%; + height: 100%; + object-fit: cover; + } + } + + // 相机图标 + .camera-icon { + position: absolute; + right: 0; + bottom: 0; + width: 46px; + height: 46px; + background: #03C175; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + border: 4px solid #121212; + + .camera-img { + width: 24px; + height: 24px; + } + } + } + } + + // 表单区域 + .form-section { + .form-item { + height: 100px; + background-color: #21212A; + border-radius: 13px; + margin-bottom: 20px; + padding: 0 30px; + display: flex; + align-items: center; + justify-content: space-between; + + .form-label { + font-size: 31rpx; + color: #E6E6E6; + flex-shrink: 0; + } + + .form-input { + flex: 1; + text-align: right; + font-size: 31rpx; + color: #FFFFFF; + margin-left: 30px; + } + + .form-placeholder { + color: #666666; + font-size: 31rpx; + } + + .form-value { + display: flex; + align-items: center; + + text { + font-size: 31rpx; + color: #FFFFFF; + margin-right: 10px; + } + + .arrow-icon { + transform: rotate(180deg); + } + } + } + } + + // 保存按钮 + .save-button { + margin-top: 82px; + width: 100%; + height: 88px; + background-color: #03C175; + border-radius: 44px; + display: flex; + align-items: center; + justify-content: center; + font-size: 33rpx; + color: #FFFFFF; + font-weight: 500; + border: none; + + &::after { + border: none; + } + } + } + + // 头像选择菜单样式 + :global { + .taroify-action-sheet { + .taroify-action-sheet__action { + font-size: 32rpx; + color: #333333; + padding: 30rpx 0; + } + } + } + + .wechat-avatar-btn { + width: 100%; + background: transparent; + border: none; + font-size: 32rpx; + color: #333333; + padding: 30rpx 0; + display: flex; + align-items: center; + justify-content: center; + border-radius: 0; + line-height: 1.4; + + &::after { + border: none; + } + + .avatar-emoji { + margin-right: 10rpx; + font-size: 36rpx; + } + } + + .avatar-action-item { + &.cancel-action { + color: #999999; + margin-top: 20rpx; + border-top: 1PX solid #EEEEEE; + } + } } diff --git a/src/pagesUser/editProfile/index.tsx b/src/pagesUser/editProfile/index.tsx index 2b91266..5268dd7 100644 --- a/src/pagesUser/editProfile/index.tsx +++ b/src/pagesUser/editProfile/index.tsx @@ -1,18 +1,231 @@ /** * 编辑个人信息页 */ -import { View, Text } from '@tarojs/components' -import { useLoad } from '@tarojs/taro' +import { View, Text, Image, Input, Button as WxButton } from '@tarojs/components' +import Taro, { useLoad } from '@tarojs/taro' +import { useState } from 'react' +import { Image as TaroifyImage, DatetimePicker, Popup, Button, ActionSheet } from '@taroify/core' +import { ArrowLeft } from '@taroify/icons' +import myAvatar from '../../assets/icon/my_avatar.png' import './index.scss' const EditProfile = () => { + const [nickname, setNickname] = useState('旋转跳跃的球圣') + const [birthday, setBirthday] = useState(new Date('2025-01-01')) + const [datePickerOpen, setDatePickerOpen] = useState(false) + const [avatarActionOpen, setAvatarActionOpen] = useState(false) + const [avatarUrl, setAvatarUrl] = useState(myAvatar) + useLoad(() => { console.log('编辑个人信息页面加载') }) + // 返回上一页 + const handleBack = () => { + Taro.navigateBack() + } + + // 点击头像,打开选择菜单 + const handleAvatarClick = () => { + setAvatarActionOpen(true) + } + + // 使用微信头像 + const handleUseWechatAvatar = () => { + // 注意:button open-type="chooseAvatar" 需要在 button 组件上使用 + // 这里先关闭 ActionSheet,让用户点击特殊的 button + setAvatarActionOpen(false) + // 实际使用时需要通过 button open-type="chooseAvatar" 触发 + Taro.showToast({ + title: '请使用下方按钮选择微信头像', + icon: 'none', + duration: 2000 + }) + } + + // 从相册选择 + const handleChooseFromAlbum = () => { + setAvatarActionOpen(false) + Taro.chooseImage({ + count: 1, + sizeType: ['compressed'], + sourceType: ['album'], + success: (res) => { + console.log('选择头像', res.tempFilePaths[0]) + setAvatarUrl(res.tempFilePaths[0]) + // TODO: 上传头像到服务器 + } + }) + } + + // 拍照 + const handleTakePhoto = () => { + setAvatarActionOpen(false) + Taro.chooseImage({ + count: 1, + sizeType: ['compressed'], + sourceType: ['camera'], + success: (res) => { + console.log('拍照', res.tempFilePaths[0]) + setAvatarUrl(res.tempFilePaths[0]) + // TODO: 上传头像到服务器 + } + }) + } + + // 获取微信头像回调 + const handleChooseAvatar = (e: any) => { + console.log('微信头像', e.detail.avatarUrl) + setAvatarUrl(e.detail.avatarUrl) + // TODO: 上传头像到服务器 + } + + // 格式化日期显示 + const formatDate = (date: Date) => { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + return `${year}-${month}-${day}` + } + + // 确认选择日期 + const handleDateConfirm = (newValue: any) => { + setBirthday(newValue) + setDatePickerOpen(false) + } + + // 保存 + const handleSave = () => { + Taro.showToast({ + title: '保存成功', + icon: 'success', + duration: 2000 + }) + + setTimeout(() => { + Taro.navigateBack() + }, 2000) + } + return ( - 编辑个人信息 + {/* 自定义导航栏 */} + {/* + + + + + 个人信息 + + + */} + + {/* 内容区域 */} + + {/* 头像区域 */} + + + + {/* 相机图标 */} + + + + + + + {/* 表单区域 */} + + {/* 昵称 */} + + 昵称 + setNickname(e.detail.value)} + placeholder="请输入昵称" + placeholderClass="form-placeholder" + /> + + + {/* 生日 */} + setDatePickerOpen(true)}> + 生日 + + {formatDate(birthday)} + + + + + + {/* 保存按钮 */} + + + + {/* 日期选择器 */} + setDatePickerOpen(false)} + > + setDatePickerOpen(false)} + onConfirm={handleDateConfirm} + > + {/* + */} + + + + {/* 头像选择菜单 */} + {}} + onClose={() => setAvatarActionOpen(false)} + > + {/* 使用微信头像 - 需要特殊处理 */} + + 🤵 + 用微信头像 + + + + 从相册选择 + + + + 拍照 + + + + 取消 + + ) } diff --git a/src/store/app.ts b/src/store/app.ts new file mode 100644 index 0000000..c74e9c5 --- /dev/null +++ b/src/store/app.ts @@ -0,0 +1,30 @@ +/** + * App Store - 全局应用状态 + */ +import { makeAutoObservable } from 'mobx' + +class AppStore { + // 控制 TabBar 显示/隐藏 + showTabBar = true + + constructor() { + makeAutoObservable(this) + } + + // 设置 TabBar 显示状态 + setShowTabBar(show: boolean) { + this.showTabBar = show + } + + // 隐藏 TabBar(弹窗打开时) + hideTabBar() { + this.showTabBar = false + } + + // 显示 TabBar(弹窗关闭时) + showTabBarFn() { + this.showTabBar = true + } +} + +export const appStore = new AppStore() diff --git a/src/store/index.ts b/src/store/index.ts index af35042..4e94713 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -2,11 +2,14 @@ * Store 统一导出 - MobX */ import { userStore as _userStore } from './user' +import { appStore as _appStore } from './app' // 重新导出 export const userStore = _userStore +export const appStore = _appStore // 导出所有 store 的集合 export const stores = { userStore: _userStore, + appStore: _appStore, }