diff --git a/src/api/cms/cmsAd/index.ts b/src/api/cms/cmsAd/index.ts index a9b1ca7..37dae87 100644 --- a/src/api/cms/cmsAd/index.ts +++ b/src/api/cms/cmsAd/index.ts @@ -102,7 +102,7 @@ export async function getCmsAd(id: number) { } /** - * 根据id查询广告位 + * 根据code查询广告位 */ export async function getCmsAdByCode(code: string) { const res = await request.get>( diff --git a/src/api/cms/cmsAd/model/index.ts b/src/api/cms/cmsAd/model/index.ts index 76fd9a4..3f900a7 100644 --- a/src/api/cms/cmsAd/model/index.ts +++ b/src/api/cms/cmsAd/model/index.ts @@ -1,4 +1,4 @@ -import type { PageParam } from '@/api/index'; +import type { PageParam } from '@/api'; /** * 广告位 diff --git a/src/api/cms/cmsArticle/index.ts b/src/api/cms/cmsArticle/index.ts index 7bc2c44..94339ec 100644 --- a/src/api/cms/cmsArticle/index.ts +++ b/src/api/cms/cmsArticle/index.ts @@ -1,5 +1,5 @@ import request from '@/utils/request'; -import type {ApiResult, PageResult} from '@/api/index'; +import type {ApiResult, PageResult} from '@/api'; import type {CmsArticle, CmsArticleParam} from './model'; /** @@ -204,3 +204,15 @@ export async function getByIds(params?: CmsArticleParam) { return Promise.reject(new Error(res.message)); } +/** + * 根据code查询文章 + */ +export async function getCmsArticleByCode(code: string) { + const res = await request.get>( + '/cms/cms-article/getByCode/' + code + ); + if (res.code === 0 && res.data) { + return res.data; + } + return Promise.reject(new Error(res.message)); +} diff --git a/src/api/cms/cmsWebsiteField/model/index.ts b/src/api/cms/cmsWebsiteField/model/index.ts index d757a89..f5b6571 100644 --- a/src/api/cms/cmsWebsiteField/model/index.ts +++ b/src/api/cms/cmsWebsiteField/model/index.ts @@ -55,4 +55,6 @@ export interface Config { email?: string; loginTitle?: string; sysLogo?: string; + vipText?: string; + vipComments?: string; } diff --git a/src/app.config.ts b/src/app.config.ts index 3f56943..63cda8d 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -111,14 +111,14 @@ export default { list: [ { pagePath: "pages/index/index", - iconPath: "assets/tabbar/logo.png", - selectedIconPath: "assets/tabbar/logo.png", + iconPath: "assets/tabbar/home.png", + selectedIconPath: "assets/tabbar/home-active.png", text: "首页", }, { pagePath: "pages/cms/category/index", - iconPath: "assets/tabbar/tv.png", - selectedIconPath: "assets/tabbar/tv-active.png", + iconPath: "assets/tabbar/category.png", + selectedIconPath: "assets/tabbar/category-active.png", text: "基地生活", }, { diff --git a/src/assets/tabbar/category-active.png b/src/assets/tabbar/category-active.png new file mode 100644 index 0000000..a7431dc Binary files /dev/null and b/src/assets/tabbar/category-active.png differ diff --git a/src/assets/tabbar/category.png b/src/assets/tabbar/category.png new file mode 100644 index 0000000..cc56063 Binary files /dev/null and b/src/assets/tabbar/category.png differ diff --git a/src/assets/tabbar/tv-active.png b/src/assets/tabbar/tv-active.png deleted file mode 100644 index 4852b4f..0000000 Binary files a/src/assets/tabbar/tv-active.png and /dev/null differ diff --git a/src/assets/tabbar/tv.png b/src/assets/tabbar/tv.png deleted file mode 100644 index 2dd6bd0..0000000 Binary files a/src/assets/tabbar/tv.png and /dev/null differ diff --git a/src/components/UnifiedQRButton.tsx b/src/components/UnifiedQRButton.tsx index 18fee99..6c019d5 100644 --- a/src/components/UnifiedQRButton.tsx +++ b/src/components/UnifiedQRButton.tsx @@ -29,7 +29,7 @@ export interface UnifiedQRButtonProps { * 支持登录和核销两种类型的二维码扫描 */ const UnifiedQRButton: React.FC = ({ - type = 'default', + type = 'danger', size = 'small', text = '扫码', showIcon = true, diff --git a/src/pages/index/Banner.tsx b/src/pages/index/Banner.tsx index 35a1a91..d31d4ec 100644 --- a/src/pages/index/Banner.tsx +++ b/src/pages/index/Banner.tsx @@ -3,36 +3,35 @@ import {View} from '@tarojs/components' import {Swiper} from '@nutui/nutui-react-taro' import {CmsAd} from "@/api/cms/cmsAd/model"; import {Image} from '@nutui/nutui-react-taro' -import {getCmsAd} from "@/api/cms/cmsAd"; +import {getCmsAdByCode} from "@/api/cms/cmsAd"; import navTo from "@/utils/common"; -import {ShopGoods} from "@/api/shop/shopGoods/model"; -import {listShopGoods} from "@/api/shop/shopGoods"; +import {pageCmsArticle} from "@/api/cms/cmsArticle"; +import {CmsArticle} from "@/api/cms/cmsArticle/model"; const MyPage = () => { const [carouselData, setCarouselData] = useState() - // const [hotToday, setHotToday] = useState() - // const [groupBuy, setGroupBuy] = useState() - const [hotGoods, setHotGoods] = useState([]) + const [hotToday, setHotToday] = useState() + const [item, setItem] = useState() // 加载数据 - const loadData = () => { + const loadData = async () => { // 轮播图 - getCmsAd(439).then(data => { - setCarouselData(data) - }) - // 今日热卖素材(上层图片) - // getCmsAd(444).then(data => { - // setHotToday(data) - // }) - // 社区拼团素材(下层图片) - // getCmsAd(445).then(data => { - // setGroupBuy(data) - // }) + const flash = await getCmsAdByCode('flash') // 今日热卖 - listShopGoods({categoryId: 4424, limit: 2}).then(data => { - setHotGoods(data) - }) + const hotToday = await getCmsAdByCode('hot_today') + // 时里动态 + const news = await pageCmsArticle({limit:1,recommend:1}) + // 赋值 + if(flash){ + setCarouselData(flash) + } + if(hotToday){ + setHotToday(hotToday) + } + if(news && news.list.length > 0){ + setItem(news.list[0]) + } } useEffect(() => { @@ -77,12 +76,12 @@ const MyPage = () => { height: '110px' }}> { - hotGoods.map(item => ( + hotToday?.imageList?.map(item => ( { }} onClick={() => navTo('/shop/category/index?id=4424')} /> - 到手价¥{item.price} + {item.title || '到手价¥9.9'} )) } @@ -103,14 +102,14 @@ const MyPage = () => { navTo('cms/detail/index?id=10109')} + onClick={() => navTo('cms/detail/index?id=' + item?.articleId)} /> diff --git a/src/pages/index/BestSellers.scss b/src/pages/index/BestSellers.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/index/BestSellers.tsx b/src/pages/index/BestSellers.tsx index 7c2c898..109d200 100644 --- a/src/pages/index/BestSellers.tsx +++ b/src/pages/index/BestSellers.tsx @@ -1,70 +1,37 @@ import {useEffect, useState} from "react"; -import {Image, Swiper, SwiperItem, Empty} from '@nutui/nutui-react-taro' +import {Image} from '@nutui/nutui-react-taro' import {Share} from '@nutui/icons-react-taro' import {View, Text} from '@tarojs/components'; import Taro from "@tarojs/taro"; -import {Tabs} from '@nutui/nutui-react-taro' import {ShopGoods} from "@/api/shop/shopGoods/model"; import {pageShopGoods} from "@/api/shop/shopGoods"; - const BestSellers = () => { - const [tab1value, setTab1value] = useState('0') const [list, setList] = useState([]) - const [goods, setGoods] = useState(null) - // 轮播图固定高度,可根据需求调整 - const SWIPER_HEIGHT = 180; + const [goods, setGoods] = useState() const reload = () => { pageShopGoods({}).then(res => { - const processGoodsItem = (item: ShopGoods) => { - const pics: string[] = []; - // 添加主图 - if (item.image) { - pics.push(item.image); - } - // 处理附加图片 - if (item.files) { - try { - // 解析文件字符串为对象 - const files = typeof item.files === "string" - ? JSON.parse(item.files) - : item.files; - - // 收集所有图片URL - Object.values(files).forEach(file => { - if (file?.url) { - pics.push(file.url); - } - }); - } catch (error) { - console.error('解析文件失败:', error); - } - } - // 返回新对象,避免直接修改原对象 - return {...item, pics}; - }; - - // 处理商品列表 - const goods = (res?.list || []).map(processGoodsItem); - setList(goods); - }).catch(err => { - console.error('获取商品列表失败:', err); - }); + setList(res?.list || []); + }) } // 处理分享点击 const handleShare = (item: ShopGoods) => { setGoods(item); + console.log(goods) + // 显示分享选项菜单 Taro.showActionSheet({ itemList: ['分享给好友'], success: (res) => { if (res.tapIndex === 0) { + // 分享给好友 - 触发转发 Taro.showShareMenu({ withShareTicket: true, success: () => { + // 提示用户点击右上角分享 Taro.showToast({ title: '请点击右上角分享给好友', icon: 'none', @@ -81,135 +48,56 @@ const BestSellers = () => { } useEffect(() => { - reload(); - }, []); + reload() + }, []) - // 配置分享内容 - Taro.useShareAppMessage(() => { - if (goods) { - return { - title: goods.name, - path: `/shop/goodsDetail/index?id=${goods.goodsId}`, - imageUrl: goods.image || '' - }; - } - return { - title: '热销商品', - path: '/pages/index/index' - }; - }); + // 注意:不在这里配置分享,避免与首页分享冲突 + // 商品分享应该在商品详情页处理,首页分享应该分享首页本身 return ( - - - { - setTab1value(value) - }} - style={{ - backgroundColor: '#fff', - }} - activeType="smile" - > - - - - - - - - - {tab1value == '0' && list?.map((item) => ( - - {/* 轮播图组件 */} - {item.pics && item.pics.length > 0 ? ( - - {item.pics.map((pic, picIndex) => ( - - Taro.navigateTo({ - url: `/shop/goodsDetail/index?id=${item.goodsId}` - })} - className="swiper-image" - /> - - ))} - - ) : ( - // 没有图片时显示占位图 - - 暂无图片 - - )} - - - - {item.name} - - {item.comments} - 已售 {item.sales} - - - - - {item.price} - - - - handleShare(item)} - > - + <> + + + {list?.map((item, index) => { + return ( + + Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}/> + + + {item.name} + + {item.comments} + 已售 {item.sales} + + + + + {item.price} + + + + handleShare(item)} + > + + + + Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}>购买 + - Taro.navigateTo({ - url: `/shop/goodsDetail/index?id=${item.goodsId}` - })} - > - 购买 - - - - ))} - - { - tab1value == '1' && - } - - { - tab1value == '2' && - } - + ) + })} + - + ) } - export default BestSellers diff --git a/src/pages/user/components/IsDealer.tsx b/src/pages/user/components/IsDealer.tsx index f8315aa..ec9302f 100644 --- a/src/pages/user/components/IsDealer.tsx +++ b/src/pages/user/components/IsDealer.tsx @@ -3,15 +3,23 @@ import navTo from "@/utils/common"; import {View, Text} from '@tarojs/components' import {ArrowRight, Reward, Setting} from '@nutui/icons-react-taro' import {useUser} from '@/hooks/useUser' -import {useEffect} from "react"; +import {useEffect, useState} from "react"; import {useDealerUser} from "@/hooks/useDealerUser"; +import {useThemeStyles} from "@/hooks/useTheme"; +import {configWebsiteField} from "@/api/cms/cmsWebsiteField"; +import {Config} from "@/api/cms/cmsWebsiteField/model"; -const UserCell = () => { +const IsDealer = () => { + const themeStyles = useThemeStyles(); + const [config, setConfig] = useState() const {isSuperAdmin} = useUser(); const {dealerUser} = useDealerUser() useEffect(() => { - + configWebsiteField().then(data => { + console.log(data) + setConfig(data) + }) }, []) /** @@ -20,12 +28,10 @@ const UserCell = () => { if (isSuperAdmin()) { return ( <> - + @@ -46,17 +52,15 @@ const UserCell = () => { if (dealerUser) { return ( <> - + 分销中心 + className={'pl-3 text-orange-100 font-medium'}>{config?.vipText || '入驻申请'} {/*门店核销*/} } @@ -73,17 +77,15 @@ const UserCell = () => { */ return ( <> - + - 开通VIP - 享优惠 + {config?.vipText || '开通VIP'} + {config?.vipComments || '享优惠'} } extra={} @@ -93,4 +95,4 @@ const UserCell = () => { ) } -export default UserCell +export default IsDealer diff --git a/src/pages/user/components/UserCard.tsx b/src/pages/user/components/UserCard.tsx index 164fa72..ccda8ed 100644 --- a/src/pages/user/components/UserCard.tsx +++ b/src/pages/user/components/UserCard.tsx @@ -1,5 +1,5 @@ -import {Avatar, Tag, Space, Button} from '@nutui/nutui-react-taro' -import {View, Text, Image} from '@tarojs/components' +import {Avatar, Tag, Space} from '@nutui/nutui-react-taro' +import {View, Text} from '@tarojs/components' import {getUserInfo, getWxOpenId} from '@/api/layout'; import Taro from '@tarojs/taro'; import {useEffect, useState, forwardRef, useImperativeHandle} from "react"; @@ -10,6 +10,7 @@ import {useUser} from "@/hooks/useUser"; import {useUserData} from "@/hooks/useUserData"; import {getStoredInviteParams} from "@/utils/invite"; import UnifiedQRButton from "@/components/UnifiedQRButton"; +import {useThemeStyles} from "@/hooks/useTheme"; const UserCard = forwardRef((_, ref) => { const {data, refresh} = useUserData() @@ -17,6 +18,8 @@ const UserCard = forwardRef((_, ref) => { const [IsLogin, setIsLogin] = useState(false) const [userInfo, setUserInfo] = useState() + const themeStyles = useThemeStyles(); + // 下拉刷新 const handleRefresh = async () => { await refresh() @@ -95,7 +98,6 @@ const UserCard = forwardRef((_, ref) => { }); }; - const openSetting = () => { // Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。 Taro.openSetting({ @@ -118,6 +120,11 @@ const UserCard = forwardRef((_, ref) => { const handleGetPhoneNumber = ({detail}: { detail: { code?: string, encryptedData?: string, iv?: string } }) => { const {code, encryptedData, iv} = detail + // 判断用户是否已登录 + if(IsLogin){ + return navTo(`/user/profile/profile`) + } + // 获取存储的邀请参数 const inviteParams = getStoredInviteParams() const refereeId = inviteParams?.inviter ? parseInt(inviteParams.inviter) : 0 @@ -165,34 +172,19 @@ const UserCard = forwardRef((_, ref) => { } return ( - - + {/* 使用相对定位容器,让个人资料图片可以绝对定位在右上角 */} - + - - { - IsLogin ? ( - - ) : ( - - ) - } + + - {getDisplayName()} + {getDisplayName()} {IsLogin ? ( @@ -210,7 +202,7 @@ const UserCard = forwardRef((_, ref) => { }}> {/*统一扫码入口 - 支持登录和核销*/} { console.log('统一扫码成功:', result); @@ -229,47 +221,31 @@ const UserCard = forwardRef((_, ref) => { /> - - navTo('/user/wallet/wallet', true)}> - 余额 - {data?.balance || '0.00'} - - - 积分 - {data?.points || 0} - - navTo('/user/coupon/index', true)}> - 优惠券 - {data?.coupons || 0} - - navTo('/user/gift/index', true)}> - 礼品卡 - {data?.giftCards || 0} + + + navTo('/user/wallet/wallet', true)}> + 余额 + {data?.balance || '0.00'} + + + 积分 + {data?.points || 0} + + navTo('/user/coupon/index', true)}> + 优惠券 + {data?.coupons || 0} + + navTo('/user/gift/index', true)}> + 礼品卡 + {data?.giftCards || 0} + - - {/* 个人资料图片,定位在右上角 */} - navTo('/user/profile/profile', true)} - > - - - ) }) diff --git a/src/pages/user/components/UserCell.tsx b/src/pages/user/components/UserCell.tsx index 7aa218d..46a0882 100644 --- a/src/pages/user/components/UserCell.tsx +++ b/src/pages/user/components/UserCell.tsx @@ -26,7 +26,7 @@ const UserCell = () => { return ( <> - + diff --git a/src/pages/user/components/UserGrid.tsx b/src/pages/user/components/UserGrid.tsx index 5c3e5da..faee87e 100644 --- a/src/pages/user/components/UserGrid.tsx +++ b/src/pages/user/components/UserGrid.tsx @@ -138,6 +138,53 @@ const UserCell = () => { + {/**/} + {/* 账号管理*/} + {/* */} + {/* */} + {/* navTo('/user/profile/profile', true)}>*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + + {/* navTo('/user/theme/index', true)}>*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + + {/* navTo('/user/about/index')}>*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + + {/* */} + {/* */} + {/**/} ) } diff --git a/src/pages/user/components/UserOrder.tsx b/src/pages/user/components/UserOrder.tsx index cc0f58d..0a17847 100644 --- a/src/pages/user/components/UserOrder.tsx +++ b/src/pages/user/components/UserOrder.tsx @@ -14,7 +14,7 @@ function UserOrder() { return ( <> - + () + const themeStyles = useThemeStyles(); // 下拉刷新处理 const handleRefresh = async () => { @@ -30,15 +33,30 @@ function User() { onRefresh={handleRefresh} headHeight={60} > -
- - - - - -
+ {/* 装饰性背景 */} + + {/* 装饰性背景元素 - 小程序兼容版本 */} + + + + + + + + + ) } diff --git a/src/pages/user_bak/components/IsDealer.tsx b/src/pages/user_bak/components/IsDealer.tsx new file mode 100644 index 0000000..c154f6d --- /dev/null +++ b/src/pages/user_bak/components/IsDealer.tsx @@ -0,0 +1,102 @@ +import {Cell} from '@nutui/nutui-react-taro' +import navTo from "@/utils/common"; +import {View, Text} from '@tarojs/components' +import {ArrowRight, Reward, Setting} from '@nutui/icons-react-taro' +import {useUser} from '@/hooks/useUser' +import {useEffect, useState} from "react"; +import {useDealerUser} from "@/hooks/useDealerUser"; +import {configWebsiteField} from "@/api/cms/cmsWebsiteField"; +import {Config} from "@/api/cms/cmsWebsiteField/model"; + +const UserCell = () => { + const {isSuperAdmin} = useUser(); + const {dealerUser} = useDealerUser() + const [config, setConfig] = useState() + + useEffect(() => { + configWebsiteField().then(data => { + console.log(data) + setConfig(data) + }) + }, []) + + /** + * 管理中心 + */ + if (isSuperAdmin()) { + return ( + <> + + + + 管理中心 + + } + extra={} + onClick={() => navTo('/admin/index', true)} + /> +
+ + ) + } + + /** + * 分销中心 + */ + if (dealerUser) { + return ( + <> + + + + 分销中心 + {/*门店核销*/} + + } + extra={} + onClick={() => navTo('/dealer/index', true)} + /> +
+ + ) + } + + /** + * 普通用户 + */ + return ( + <> + + + + {config?.vipText}开通VIP + {config?.vipComments}享优惠 + + } + extra={} + onClick={() => navTo('/dealer/apply/add', true)} + /> +
+ + ) +} +export default UserCell diff --git a/src/pages/user_bak/components/UserCard.tsx b/src/pages/user_bak/components/UserCard.tsx new file mode 100644 index 0000000..164fa72 --- /dev/null +++ b/src/pages/user_bak/components/UserCard.tsx @@ -0,0 +1,277 @@ +import {Avatar, Tag, Space, Button} from '@nutui/nutui-react-taro' +import {View, Text, Image} from '@tarojs/components' +import {getUserInfo, getWxOpenId} from '@/api/layout'; +import Taro from '@tarojs/taro'; +import {useEffect, useState, forwardRef, useImperativeHandle} from "react"; +import {User} from "@/api/system/user/model"; +import navTo from "@/utils/common"; +import {TenantId} from "@/config/app"; +import {useUser} from "@/hooks/useUser"; +import {useUserData} from "@/hooks/useUserData"; +import {getStoredInviteParams} from "@/utils/invite"; +import UnifiedQRButton from "@/components/UnifiedQRButton"; + +const UserCard = forwardRef((_, ref) => { + const {data, refresh} = useUserData() + const {getDisplayName, getRoleName} = useUser(); + const [IsLogin, setIsLogin] = useState(false) + const [userInfo, setUserInfo] = useState() + + // 下拉刷新 + const handleRefresh = async () => { + await refresh() + Taro.showToast({ + title: '刷新成功', + icon: 'success' + }) + } + + // 暴露方法给父组件 + useImperativeHandle(ref, () => ({ + handleRefresh + })) + + useEffect(() => { + // Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。 + Taro.getSetting({ + success: (res) => { + if (res.authSetting['scope.userInfo']) { + // 用户已经授权过,可以直接获取用户信息 + console.log('用户已经授权过,可以直接获取用户信息') + reload(); + } else { + // 用户未授权,需要弹出授权窗口 + console.log('用户未授权,需要弹出授权窗口') + showAuthModal(); + } + } + }); + }, []); + + const reload = () => { + Taro.getUserInfo({ + success: (res) => { + const avatar = res.userInfo.avatarUrl; + setUserInfo({ + avatar, + nickname: res.userInfo.nickName, + sexName: res.userInfo.gender == 1 ? '男' : '女' + }) + getUserInfo().then((data) => { + if (data) { + setUserInfo(data) + setIsLogin(true); + Taro.setStorageSync('UserId', data.userId) + + // 获取openId + if (!data.openid) { + Taro.login({ + success: (res) => { + getWxOpenId({code: res.code}).then(() => { + }) + } + }) + } + } + }).catch(() => { + console.log('未登录') + }); + } + }); + }; + + const showAuthModal = () => { + Taro.showModal({ + title: '授权提示', + content: '需要获取您的用户信息', + confirmText: '去授权', + cancelText: '取消', + success: (res) => { + if (res.confirm) { + // 用户点击确认,打开授权设置页面 + openSetting(); + } + } + }); + }; + + + const openSetting = () => { + // Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。 + Taro.openSetting({ + success: (res) => { + if (res.authSetting['scope.userInfo']) { + // 用户授权成功,可以获取用户信息 + reload(); + } else { + // 用户拒绝授权,提示授权失败 + Taro.showToast({ + title: '授权失败', + icon: 'none' + }); + } + } + }); + }; + + /* 获取用户手机号 */ + const handleGetPhoneNumber = ({detail}: { detail: { code?: string, encryptedData?: string, iv?: string } }) => { + const {code, encryptedData, iv} = detail + + // 获取存储的邀请参数 + const inviteParams = getStoredInviteParams() + const refereeId = inviteParams?.inviter ? parseInt(inviteParams.inviter) : 0 + + Taro.login({ + success: function () { + if (code) { + Taro.request({ + url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone', + method: 'POST', + data: { + code, + encryptedData, + iv, + notVerifyPhone: true, + refereeId: refereeId, // 使用解析出的推荐人ID + sceneType: 'save_referee', + tenantId: TenantId + }, + header: { + 'content-type': 'application/json', + TenantId + }, + success: function (res) { + if (res.data.code == 1) { + Taro.showToast({ + title: res.data.message, + icon: 'error', + duration: 2000 + }) + return false; + } + // 登录成功 + Taro.setStorageSync('access_token', res.data.data.access_token) + Taro.setStorageSync('UserId', res.data.data.user.userId) + setUserInfo(res.data.data.user) + setIsLogin(true) + } + }) + } else { + console.log('登录失败!') + } + } + }) + } + + return ( + + + {/* 使用相对定位容器,让个人资料图片可以绝对定位在右上角 */} + + + + + { + IsLogin ? ( + + ) : ( + + ) + } + + {getDisplayName()} + {IsLogin ? ( + + + + {getRoleName()} + + + + ) : ''} + + + + {/*统一扫码入口 - 支持登录和核销*/} + { + console.log('统一扫码成功:', result); + // 根据扫码类型给出不同的提示 + if (result.type === 'verification') { + // 核销成功,可以显示更多信息或跳转到详情页 + Taro.showModal({ + title: '核销成功', + content: `已成功核销的品类:${result.data.goodsName || '礼品卡'},面值¥${result.data.faceValue}` + }); + } + }} + onError={(error) => { + console.error('统一扫码失败:', error); + }} + /> + + + + navTo('/user/wallet/wallet', true)}> + 余额 + {data?.balance || '0.00'} + + + 积分 + {data?.points || 0} + + navTo('/user/coupon/index', true)}> + 优惠券 + {data?.coupons || 0} + + navTo('/user/gift/index', true)}> + 礼品卡 + {data?.giftCards || 0} + + + + + {/* 个人资料图片,定位在右上角 */} + navTo('/user/profile/profile', true)} + > + + + + + + ) +}) + +export default UserCard; diff --git a/src/pages/user_bak/components/UserCell.tsx b/src/pages/user_bak/components/UserCell.tsx new file mode 100644 index 0000000..7aa218d --- /dev/null +++ b/src/pages/user_bak/components/UserCell.tsx @@ -0,0 +1,144 @@ +import {Cell} from '@nutui/nutui-react-taro' +import navTo from "@/utils/common"; +import Taro from '@tarojs/taro' +import {View, Text} from '@tarojs/components' +import {ArrowRight, ShieldCheck, LogisticsError, Location, Tips, Ask} from '@nutui/icons-react-taro' +import {useUser} from '@/hooks/useUser' + +const UserCell = () => { + const {logoutUser, isCertified} = useUser(); + + const onLogout = () => { + Taro.showModal({ + title: '提示', + content: '确定要退出登录吗?', + success: function (res) { + if (res.confirm) { + // 使用 useUser hook 的 logoutUser 方法 + logoutUser(); + Taro.reLaunch({ + url: '/pages/index/index' + }) + } + } + }) + } + + return ( + <> + + + + 我的服务 + + }> + + + 我的钱包 +
+ } + align="center" + extra={} + onClick={() => { + navTo('/user/wallet/index', true) + }} + /> + + + 收货地址 +
+ } + align="center" + extra={} + onClick={() => { + navTo('/user/address/index', true) + }} + /> + + + 实名认证 + {isCertified() && ( + 已认证 + )} +
+ } + align="center" + extra={} + onClick={() => { + navTo('/user/userVerify/index', true) + }} + /> + + + 常见问题 +
+ } + align="center" + extra={} + onClick={() => { + navTo('/user/help/index') + }} + /> + + + 关于我们 +
+ } + align="center" + extra={} + onClick={() => { + navTo('/user/about/index') + }} + /> + + + 账号管理 +
+ }> + } + onClick={() => navTo('/user/profile/profile', true)} + /> + } + onClick={() => navTo('/user/theme/index', true)} + /> + } + onClick={onLogout} + /> + +
+ + ) +} +export default UserCell diff --git a/src/pages/user_bak/components/UserFooter.tsx b/src/pages/user_bak/components/UserFooter.tsx new file mode 100644 index 0000000..fb74b71 --- /dev/null +++ b/src/pages/user_bak/components/UserFooter.tsx @@ -0,0 +1,102 @@ +import {loginBySms} from "@/api/passport/login"; +import {useState} from "react"; +import Taro from '@tarojs/taro' +import {Popup} from '@nutui/nutui-react-taro' +import {UserParam} from "@/api/system/user/model"; +import {Button} from '@nutui/nutui-react-taro' +import {Form, Input} from '@nutui/nutui-react-taro' +import {Copyright, Version} from "@/config/app"; +const UserFooter = () => { + const [openLoginByPhone, setOpenLoginByPhone] = useState(false) + const [clickNum, setClickNum] = useState(0) + const [FormData, setFormData] = useState( + { + phone: undefined, + password: undefined + } + ) + + const onLoginByPhone = () => { + setFormData({}) + setClickNum(clickNum + 1); + if (clickNum > 10) { + setOpenLoginByPhone(true); + } + } + + const closeLoginByPhone = () => { + setClickNum(0) + setOpenLoginByPhone(false) + } + + // 提交表单 + const submitByPhone = (values: any) => { + loginBySms({ + phone: values.phone, + code: values.code + }).then(() => { + setOpenLoginByPhone(false); + setTimeout(() => { + Taro.reLaunch({ + url: '/pages/index/index' + }) + },1000) + }) + } + + return ( + <> +
+
当前版本:{Version}
+
Copyright © { new Date().getFullYear() } {Copyright}
+
+ + +
submitByPhone(values)} + footer={ +
+ +
+ } + > + + + + + + +
+
+ + ) +} +export default UserFooter diff --git a/src/pages/user_bak/components/UserGrid.tsx b/src/pages/user_bak/components/UserGrid.tsx new file mode 100644 index 0000000..5c3e5da --- /dev/null +++ b/src/pages/user_bak/components/UserGrid.tsx @@ -0,0 +1,145 @@ +import {Grid, ConfigProvider} from '@nutui/nutui-react-taro' +import navTo from "@/utils/common"; +import Taro from '@tarojs/taro' +import {View, Button} from '@tarojs/components' +import { + ShieldCheck, + Location, + Tips, + Ask, + // Dongdong, + People, + // AfterSaleService, + Logout, + ShoppingAdd, + Service +} from '@nutui/icons-react-taro' +import {useUser} from "@/hooks/useUser"; + +const UserCell = () => { + const {logoutUser} = useUser(); + + const onLogout = () => { + Taro.showModal({ + title: '提示', + content: '确定要退出登录吗?', + success: function (res) { + if (res.confirm) { + // 使用 useUser hook 的 logoutUser 方法 + logoutUser(); + Taro.reLaunch({ + url: '/pages/index/index' + }) + } + } + }) + } + + return ( + <> + + 我的服务 + + + navTo('/user/poster/poster', true)}> + + + + + + + + {/* 修改联系我们为微信客服 */} + + + + + navTo('/user/address/index', true)}> + + + + + + + + navTo('/user/userVerify/index', true)}> + + + + + + + + navTo('/dealer/team/index', true)}> + + + + + + + + {/* navTo('/dealer/qrcode/index', true)}>*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/**/} + + {/* navTo('/admin/index', true)}>*/} + {/* */} + {/* */} + {/* */} + {/* */} + {/* */} + {/**/} + + navTo('/user/help/index')}> + + + + + + + + navTo('/user/about/index')}> + + + + + + + + + + + + + + + + + + + + ) +} +export default UserCell + diff --git a/src/pages/user_bak/components/UserOrder.tsx b/src/pages/user_bak/components/UserOrder.tsx new file mode 100644 index 0000000..cc0f58d --- /dev/null +++ b/src/pages/user_bak/components/UserOrder.tsx @@ -0,0 +1,122 @@ +import navTo from "@/utils/common"; +import {View, Text} from '@tarojs/components'; +import {Badge} from '@nutui/nutui-react-taro'; +import {ArrowRight, Wallet, Comment, Transit, Refund, Package} from '@nutui/icons-react-taro'; +import {useOrderStats} from "@/hooks/useOrderStats"; + +function UserOrder() { + const { orderStats, refreshOrderStats } = useOrderStats(); + + // 处理长按刷新 + const handleLongPress = () => { + refreshOrderStats(); + }; + + return ( + <> + + + + 我的订单 + navTo('/user/order/order', true)} + onLongPress={handleLongPress} + > + 全部订单 + + + + + {/* 待付款 */} + {orderStats.pending > 0 ? ( + + + navTo('/user/order/order?statusFilter=0', true)}/> + 待付款 + + + ) : ( + navTo('/user/order/order?statusFilter=0', true)}> + + 待付款 + + )} + + {/* 待发货 */} + {orderStats.paid > 0 ? ( + + navTo('/user/order/order?statusFilter=1', true)}> + + 待发货 + + + ) : ( + navTo('/user/order/order?statusFilter=1', true)}> + + 待发货 + + )} + + {/* 待收货 */} + {orderStats.shipped > 0 ? ( + + navTo('/user/order/order?statusFilter=3', true)}> + + 待收货 + + + ) : ( + navTo('/user/order/order?statusFilter=3', true)}> + + 待收货 + + )} + + {/* 已完成 - 不显示badge */} + navTo('/user/order/order?statusFilter=5', true)}> + + 已完成 + + + {/* 退货/售后 */} + {orderStats.refund > 0 ? ( + + navTo('/user/order/order?statusFilter=6', true)}> + + 退货/售后 + + + ) : ( + navTo('/user/order/order?statusFilter=6', true)}> + + 退货/售后 + + )} + + + + + + ) +} + +export default UserOrder; diff --git a/src/pages/user_bak/user.config.ts b/src/pages/user_bak/user.config.ts new file mode 100644 index 0000000..31e4776 --- /dev/null +++ b/src/pages/user_bak/user.config.ts @@ -0,0 +1,5 @@ +export default definePageConfig({ + navigationBarTitleText: '我的', + navigationStyle: 'custom', + navigationBarBackgroundColor: '#e9fff2' +}) diff --git a/src/pages/user_bak/user.scss b/src/pages/user_bak/user.scss new file mode 100644 index 0000000..a01d79c --- /dev/null +++ b/src/pages/user_bak/user.scss @@ -0,0 +1,9 @@ +.header-bg{ + //background: url('https://oss.wsdns.cn/20250621/edb5d4da976b4d97ba185cb7077d2858.jpg') no-repeat top center; + background: linear-gradient(to bottom, #03605c, #18ae4f); + background-size: 100%; +} + +.my-bg{ + background: url('https://oss.wsdns.cn/20250913/5ae575a50dbb4ccaab086c3679c5e2c3.png') no-repeat top center; +} diff --git a/src/pages/user_bak/user.tsx b/src/pages/user_bak/user.tsx new file mode 100644 index 0000000..2ad1f98 --- /dev/null +++ b/src/pages/user_bak/user.tsx @@ -0,0 +1,46 @@ +import {useEffect, useRef} from 'react' +import {PullToRefresh} from '@nutui/nutui-react-taro' +import UserCard from "./components/UserCard"; +import UserOrder from "./components/UserOrder"; +import UserFooter from "./components/UserFooter"; +import {useUserData} from "@/hooks/useUserData"; +import './user.scss' +import IsDealer from "./components/IsDealer"; +import UserGrid from "@/pages/user/components/UserGrid"; + +function User() { + + const { refresh } = useUserData() + const userCardRef = useRef() + + // 下拉刷新处理 + const handleRefresh = async () => { + await refresh() + // 如果 UserCard 组件有自己的刷新方法,也可以调用 + if (userCardRef.current?.handleRefresh) { + await userCardRef.current.handleRefresh() + } + } + + useEffect(() => { + }, []); + + return ( + +
+ + + + + +
+
+ ) +} + +export default User diff --git a/src/styles/gradients.ts b/src/styles/gradients.ts index 2ad1cb4..11ab23a 100644 --- a/src/styles/gradients.ts +++ b/src/styles/gradients.ts @@ -40,9 +40,9 @@ export const gradientThemes: GradientTheme[] = [ }, { name: 'nature', - primary: '#43e97b', - secondary: '#38f9d7', - background: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)', + primary: '#03605c', + secondary: '#18ae4f', + background: 'linear-gradient(135deg, #03605c 0%, #18ae4f 100%)', textColor: '#ffffff', description: '自然绿青 - 生机与成长' }, diff --git a/tailwind.config.js b/tailwind.config.js index d257697..55ac80c 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -20,7 +20,7 @@ module.exports = { divideStyle: false, divideOpacity: false, // 新增禁用项,解决微信小程序兼容性问题 - gap: false, // 禁用 gap 类,因为微信小程序不支持 gap 属性 + gap: true, // 禁用 gap 类,因为微信小程序不支持 gap 属性 lineClamp: false, // 禁用 line-clamp 类,微信小程序不支持 textIndent: false, // 禁用 text-indent writingMode: false, // 禁用 writing-mode