diff --git a/src/api/cms/cmsWebsiteField/model/index.ts b/src/api/cms/cmsWebsiteField/model/index.ts index f5b6571..ec5967c 100644 --- a/src/api/cms/cmsWebsiteField/model/index.ts +++ b/src/api/cms/cmsWebsiteField/model/index.ts @@ -57,4 +57,7 @@ export interface Config { sysLogo?: string; vipText?: string; vipComments?: string; + deliveryText?: string; + guaranteeText?: string; + openComments?: string; } diff --git a/src/app.config.ts b/src/app.config.ts index 6ecb75a..78df1ad 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -87,6 +87,7 @@ export default { 'goodsDetail/index', 'orderConfirm/index', 'orderConfirmCart/index', + 'comments/index', 'search/index'] }, { diff --git a/src/app.ts b/src/app.ts index 7701b4a..94746fc 100644 --- a/src/app.ts +++ b/src/app.ts @@ -7,9 +7,11 @@ import {loginByOpenId} from "@/api/layout"; import {TenantId} from "@/config/app"; import {saveStorageByLoginUser} from "@/utils/server"; import {parseInviteParams, saveInviteParams, trackInviteSource, handleInviteRelation} from "@/utils/invite"; -import {configWebsiteField} from "@/api/cms/cmsWebsiteField"; +import { useConfig } from "@/hooks/useConfig"; // 引入新的自定义Hook function App(props: { children: any; }) { + const { refetch: handleTheme } = useConfig(); // 使用新的Hook + const reload = () => { Taro.login({ success: (res) => { @@ -38,7 +40,7 @@ function App(props: { children: any; }) { }; // 可以使用所有的 React Hooks useEffect(() => { - // 设置主题 + // 设置主题 (现在由useConfig Hook处理) handleTheme() // Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。 Taro.getSetting({ @@ -60,7 +62,7 @@ function App(props: { children: any; }) { // 处理启动参数 const handleLaunchOptions = (options: any) => { try { - console.log('=== 小程序启动参数处理开始 ===') + console.log('=== 小程 序启动参数处理开始 ===') console.log('完整启动参数:', JSON.stringify(options, null, 2)) // 解析邀请参数 @@ -93,15 +95,6 @@ function App(props: { children: any; }) { } } - const handleTheme = () => { - configWebsiteField().then(data => { - // 设置主题 - if(data.theme && !Taro.getStorageSync('user_theme')){ - Taro.setStorageSync('user_theme', data.theme) - } - }) - } - // 对应 onHide useDidHide(() => { }) @@ -109,4 +102,4 @@ function App(props: { children: any; }) { return props.children } -export default App +export default App \ No newline at end of file diff --git a/src/cms/category/components/ArticleList.tsx b/src/cms/category/components/ArticleList.tsx index 3f46857..cde08b4 100644 --- a/src/cms/category/components/ArticleList.tsx +++ b/src/cms/category/components/ArticleList.tsx @@ -1,12 +1,13 @@ import {Image, Cell} from '@nutui/nutui-react-taro' import Taro from '@tarojs/taro' +import {CmsArticle} from "@/api/cms/cmsArticle/model"; const ArticleList = (props: any) => { return ( <>
- {props.data.map((item, index) => { + {props.data.map((item: CmsArticle, index: number) => { return ( { + const [config, setConfig] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchConfig = async () => { + try { + setLoading(true); + const data = await configWebsiteField(); + setConfig(data); + Taro.setStorageSync('config', data); + + // 设置主题 + if (data.theme && !Taro.getStorageSync('user_theme')) { + Taro.setStorageSync('user_theme', data.theme); + } + } catch (err) { + setError(err instanceof Error ? err : new Error('获取配置失败')); + console.error('获取网站配置失败:', err); + } finally { + setLoading(false); + } + }; + + fetchConfig(); + }, []); + + return { config, loading, error, refetch: () => { + setLoading(true); + setError(null); + configWebsiteField().then(data => { + setConfig(data); + Taro.setStorageSync('config', data); + setLoading(false); + }).catch(err => { + setError(err instanceof Error ? err : new Error('获取配置失败')); + setLoading(false); + }); + }}; +}; \ No newline at end of file diff --git a/src/pages/index/Banner.tsx b/src/pages/index/Banner.tsx index 0d2a214..7cc44fc 100644 --- a/src/pages/index/Banner.tsx +++ b/src/pages/index/Banner.tsx @@ -46,8 +46,8 @@ const MyPage = () => { loadData() }, []) - // 轮播图高度,默认200px - const carouselHeight = carouselData?.height || 200; + // 轮播图高度,默认300px + const carouselHeight = carouselData?.height || 300; // 骨架屏组件 const BannerSkeleton = () => ( @@ -139,7 +139,7 @@ const MyPage = () => { }}> { hotToday?.imageList?.map(item => ( - + { const themeStyles = useThemeStyles(); - const [config, setConfig] = useState() + const { config } = useConfig(); // 使用新的Hook const {isSuperAdmin} = useUser(); const {dealerUser} = useDealerUser() - useEffect(() => { - configWebsiteField().then(data => { - console.log(data) - setConfig(data) - }) - }, []) - console.log(dealerUser,'dealerUserdealerUserdealerUserdealerUserdealerUser') /** * 管理中心 */ diff --git a/src/pages/user_bak/components/IsDealer.tsx b/src/pages/user_bak/components/IsDealer.tsx deleted file mode 100644 index c154f6d..0000000 --- a/src/pages/user_bak/components/IsDealer.tsx +++ /dev/null @@ -1,102 +0,0 @@ -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 deleted file mode 100644 index 164fa72..0000000 --- a/src/pages/user_bak/components/UserCard.tsx +++ /dev/null @@ -1,277 +0,0 @@ -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 deleted file mode 100644 index 7aa218d..0000000 --- a/src/pages/user_bak/components/UserCell.tsx +++ /dev/null @@ -1,144 +0,0 @@ -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 deleted file mode 100644 index fb74b71..0000000 --- a/src/pages/user_bak/components/UserFooter.tsx +++ /dev/null @@ -1,102 +0,0 @@ -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 deleted file mode 100644 index 5c3e5da..0000000 --- a/src/pages/user_bak/components/UserGrid.tsx +++ /dev/null @@ -1,145 +0,0 @@ -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 deleted file mode 100644 index cc0f58d..0000000 --- a/src/pages/user_bak/components/UserOrder.tsx +++ /dev/null @@ -1,122 +0,0 @@ -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 deleted file mode 100644 index 31e4776..0000000 --- a/src/pages/user_bak/user.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default definePageConfig({ - navigationBarTitleText: '我的', - navigationStyle: 'custom', - navigationBarBackgroundColor: '#e9fff2' -}) diff --git a/src/pages/user_bak/user.scss b/src/pages/user_bak/user.scss deleted file mode 100644 index a01d79c..0000000 --- a/src/pages/user_bak/user.scss +++ /dev/null @@ -1,9 +0,0 @@ -.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 deleted file mode 100644 index 2ad1f98..0000000 --- a/src/pages/user_bak/user.tsx +++ /dev/null @@ -1,46 +0,0 @@ -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/shop/comments/index.config.ts b/src/shop/comments/index.config.ts new file mode 100644 index 0000000..6d901e3 --- /dev/null +++ b/src/shop/comments/index.config.ts @@ -0,0 +1,4 @@ +export default definePageConfig({ + navigationBarTitleText: '全部评论', + navigationBarTextStyle: 'black' +}) diff --git a/src/shop/comments/index.tsx b/src/shop/comments/index.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/shop/goodsDetail/index.scss b/src/shop/goodsDetail/index.scss index 753f6ab..aa22055 100644 --- a/src/shop/goodsDetail/index.scss +++ b/src/shop/goodsDetail/index.scss @@ -15,3 +15,11 @@ rich-text img { .no-margin { margin: 0 !important; /* 使用 !important 来确保覆盖默认样式 */ } + +/* 文本截断样式 */ +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: inline-block; +} \ No newline at end of file diff --git a/src/shop/goodsDetail/index.tsx b/src/shop/goodsDetail/index.tsx index 5bedda4..17715b2 100644 --- a/src/shop/goodsDetail/index.tsx +++ b/src/shop/goodsDetail/index.tsx @@ -1,8 +1,8 @@ import {useEffect, useState} from "react"; -import {Image, Divider, Badge} from "@nutui/nutui-react-taro"; -import {ArrowLeft, Headphones, Share, Cart} from "@nutui/icons-react-taro"; +import {Image, Badge, Popup, CellGroup, Cell} from "@nutui/nutui-react-taro"; +import {ArrowLeft, Headphones, Share, Cart, ArrowRight} from "@nutui/icons-react-taro"; import Taro, {useShareAppMessage} from "@tarojs/taro"; -import {RichText, View} from '@tarojs/components' +import {RichText, View, Text} from '@tarojs/components' import {ShopGoods} from "@/api/shop/shopGoods/model"; import {getShopGoods} from "@/api/shop/shopGoods"; import {listShopGoodsSpec} from "@/api/shop/shopGoodsSpec"; @@ -14,21 +14,30 @@ import navTo, {wxParse} from "@/utils/common"; import SpecSelector from "@/components/SpecSelector"; import "./index.scss"; import {useCart} from "@/hooks/useCart"; +import {useConfig} from "@/hooks/useConfig"; const GoodsDetail = () => { + const [statusBarHeight, setStatusBarHeight] = useState(44); + const [windowWidth, setWindowWidth] = useState(390) const [goods, setGoods] = useState(null); const [files, setFiles] = useState([]); const [specs, setSpecs] = useState([]); const [skus, setSkus] = useState([]); const [showSpecSelector, setShowSpecSelector] = useState(false); const [specAction, setSpecAction] = useState<'cart' | 'buy'>('cart'); + const [showBottom, setShowBottom] = useState(false) + const [bottomItem, setBottomItem] = useState({ + title: '', + content: '' + }) // const [selectedSku, setSelectedSku] = useState(null); const [loading, setLoading] = useState(false); const router = Taro.getCurrentInstance().router; const goodsId = router?.params?.id; // 使用购物车Hook - const {cartCount, addToCart} = useCart(); + const {cartCount, addToCart} = useCart() + const {config} = useConfig() // 处理加入购物车 const handleAddToCart = () => { @@ -117,7 +126,21 @@ const GoodsDetail = () => { } }; + const openBottom = (title: string, content: string) => { + setBottomItem({ + title, + content + }) + setShowBottom(true) + } + useEffect(() => { + Taro.getSystemInfo({ + success: (res) => { + setWindowWidth(res.windowWidth) + setStatusBarHeight(Number(res.statusBarHeight) + 5) + }, + }); if (goodsId) { setLoading(true); @@ -187,12 +210,12 @@ const GoodsDetail = () => { }); if (!goods || loading) { - return
加载中...
; + return 加载中...; } return ( -
-
+ { borderRadius: "100%", width: "32px", height: "32px", - top: "50px", + top: statusBarHeight + 'px', left: "10px", }} onClick={() => Taro.navigateBack()} > -
-
+ Taro.switchTab({url: `/pages/cart/cart`})}> + style={{ + borderRadius: "100%", + width: "32px", + height: "32px", + top: statusBarHeight + 'px', + right: "110px", + }} + onClick={() => Taro.switchTab({url: `/pages/cart/cart`})}> -
+ -
+
-
+ { files.length > 0 && ( - + {files.map((item) => ( - + ))} @@ -245,69 +268,116 @@ const GoodsDetail = () => { /> ) } -
-
-
+ <> -
-
+ + {goods.price} -
+ 已售 {goods.sales} -
-
-
-
+ + + + {goods.name} -
-
+ + {goods.comments} -
-
+ + -
+
-
-
-
- 商品详情 + + + + { + config?.deliveryText && ( + + + {config?.deliveryText || '14:30下单,明天配送'} + + + } onClick={() => openBottom('配送', `${config?.deliveryText}`)}/> + + {config?.guaranteeText || '支持7天无理由退货'} + + + } onClick={() => openBottom('保障', `${config?.guaranteeText}`)}/> + + ) + } + {config?.openComments == '1' && ( + + + 查看全部 + + + } onClick={() => navTo(`/shop/comments/index`)}/> + + 暂无评价 + + + )} + + -
-
+ + + + {/*底部弹窗*/} + { + setShowBottom(false) + }} + lockScroll + > + + {bottomItem.title} + {bottomItem.content} + + {/*底部购买按钮*/} -
+ -
+ -
-
-
handleAddToCart()}>加入购物车 -
-
handleBuyNow()}>立即购买 -
-
+
+ + handleAddToCart()}>加入购物车 + + handleBuyNow()}>立即购买 + +
-
+ {/* 规格选择器 */} {showSpecSelector && ( @@ -320,7 +390,7 @@ const GoodsDetail = () => { onClose={() => setShowSpecSelector(false)} /> )} -
+ ); }; diff --git a/src/shop/orderConfirm/index.tsx b/src/shop/orderConfirm/index.tsx index 58fe1c1..830e02f 100644 --- a/src/shop/orderConfirm/index.tsx +++ b/src/shop/orderConfirm/index.tsx @@ -74,20 +74,20 @@ const OrderConfirm = () => { const getGoodsTotal = () => { if (!goods) return 0 const price = parseFloat(goods.price || '0') - const total = price * quantity + // const total = price * quantity // 🔍 详细日志,用于排查数值精度问题 - console.log('💵 商品总价计算:', { - goodsPrice: goods.price, - goodsPriceType: typeof goods.price, - parsedPrice: price, - quantity: quantity, - total: total, - totalFixed2: total.toFixed(2), - totalString: total.toString() - }) - - return total + // console.log('💵 商品总价计算:', { + // goodsPrice: goods.price, + // goodsPriceType: typeof goods.price, + // parsedPrice: price, + // quantity: quantity, + // total: total, + // totalFixed2: total.toFixed(2), + // totalString: total.toString() + // }) + + return price * quantity } // 计算优惠券折扣 @@ -418,9 +418,9 @@ const OrderConfirm = () => { couponId: parseInt(String(bestCoupon.id), 10) } ); - + console.log('🎯 使用推荐优惠券的订单数据:', updatedOrderData); - + // 执行支付 await PaymentHandler.pay(updatedOrderData, currentPaymentType); return; // 提前返回,避免重复执行支付 diff --git a/src/user/about/index.tsx b/src/user/about/index.tsx index fec73d9..5011331 100644 --- a/src/user/about/index.tsx +++ b/src/user/about/index.tsx @@ -9,15 +9,14 @@ import {listCmsNavigation} from "@/api/cms/cmsNavigation"; import {View, RichText} from '@tarojs/components' import {listCmsDesign} from "@/api/cms/cmsDesign"; import {CmsDesign} from "@/api/cms/cmsDesign/model"; -import {type Config} from "@/api/cms/cmsWebsiteField/model"; -import {configWebsiteField} from "@/api/cms/cmsWebsiteField"; +import { useConfig } from "@/hooks/useConfig"; // 使用新的自定义Hook const Helper = () => { const [nav, setNav] = useState() const [design, setDesign] = useState() const [category, setCategory] = useState([]) - const [config, setConfig] = useState() + const { config } = useConfig(); // 使用新的Hook const reload = async () => { const navs = await listCmsNavigation({model: 'page', parentId: 0}); @@ -33,9 +32,7 @@ const Helper = () => { category[index].articles = await listCmsArticle({categoryId: item.navigationId}); }) setCategory(category) - // 查询字段 - const configInfo = await configWebsiteField({}) - setConfig(configInfo) + // 注意:config 现在通过 useConfig Hook 获取,不再在这里调用 configWebsiteField } }