From 7b7bf80bc5ca2f934efeccfea595ce3104080c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Sun, 5 Oct 2025 09:45:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(pages):=20=E5=AE=9E=E7=8E=B0=E5=95=86?= =?UTF-8?q?=E5=93=81=E5=88=86=E7=B1=BB=E9=A1=B5=E9=9D=A2=E5=8F=8A=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=BD=AE=E6=92=AD=E5=9B=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增商品分类页面,包含左侧导航和右侧商品列表 - 实现分类切换和商品展示功能 - 添加骨架屏加载效果和空状态处理 - 优化首页轮播图组件,支持自动播放和触摸滑动 - 调整轮播图高度默认值为300px- 移除旧的热卖商品逻辑,改为获取推荐文章 - 修复医生申请页面用户类型选择功能 - 更新页面标题文本内容 - 添加网站配置获取hook --- src/api/cms/cmsWebsiteField/model/index.ts | 1 + src/api/system/dict/index.ts | 4 +- src/app.config.ts | 8 +- src/app.ts | 26 +- src/assets/tabbar/category-active.png | Bin 0 -> 3321 bytes src/assets/tabbar/category.png | Bin 0 -> 3158 bytes src/cms/category/components/ArticleList.tsx | 18 +- src/doctor/apply/add.config.ts | 2 +- src/doctor/apply/add.tsx | 128 ++++-- src/doctor/customer/index.tsx | 4 +- src/hooks/useConfig.ts | 50 +++ src/pages/category/category.config.ts | 3 + src/pages/category/category.scss | 425 ++++++++++++++++++ src/pages/category/category.tsx | 270 +++++++++++ src/pages/category/components/ArticleList.tsx | 35 ++ src/pages/category/components/ArticleTabs.tsx | 59 +++ src/pages/category/components/Banner.tsx | 31 ++ src/pages/index/Banner.tsx | 155 +++++-- src/pages/order/order.scss | 4 - src/pages/user/components/IsDealer.tsx | 24 +- src/utils/request.ts | 29 +- 21 files changed, 1153 insertions(+), 123 deletions(-) create mode 100644 src/assets/tabbar/category-active.png create mode 100644 src/assets/tabbar/category.png create mode 100644 src/hooks/useConfig.ts create mode 100644 src/pages/category/category.config.ts create mode 100644 src/pages/category/category.scss create mode 100644 src/pages/category/category.tsx create mode 100644 src/pages/category/components/ArticleList.tsx create mode 100644 src/pages/category/components/ArticleTabs.tsx create mode 100644 src/pages/category/components/Banner.tsx delete mode 100644 src/pages/order/order.scss diff --git a/src/api/cms/cmsWebsiteField/model/index.ts b/src/api/cms/cmsWebsiteField/model/index.ts index 4863d36..222f79f 100644 --- a/src/api/cms/cmsWebsiteField/model/index.ts +++ b/src/api/cms/cmsWebsiteField/model/index.ts @@ -43,6 +43,7 @@ export interface Config { siteName?: string; siteLogo?: string; domain?: string; + apiUrl?: string; icpNo?: string; copyright?: string; loginBgImg?: string; diff --git a/src/api/system/dict/index.ts b/src/api/system/dict/index.ts index 0076c39..a017f6a 100644 --- a/src/api/system/dict/index.ts +++ b/src/api/system/dict/index.ts @@ -9,9 +9,7 @@ import {SERVER_API_URL} from "@/utils/server"; export async function listDictionaries(params?: DictParam) { const res = await request.get>( SERVER_API_URL + '/system/dict', - { - params - } + params ); if (res.code === 0) { return res.data; diff --git a/src/app.config.ts b/src/app.config.ts index 5e83456..ae304e4 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -4,7 +4,7 @@ export default { 'pages/cart/cart', 'pages/find/find', 'pages/user/user', - 'pages/cms/category/index' + 'pages/category/category' ], "subpackages": [ { @@ -126,6 +126,12 @@ export default { selectedIconPath: "assets/tabbar/home-active.png", text: "首页", }, + { + pagePath: "pages/category/category", + iconPath: "assets/tabbar/category.png", + selectedIconPath: "assets/tabbar/category-active.png", + text: "分类", + }, { pagePath: "pages/cart/cart", iconPath: "assets/tabbar/cart.png", diff --git a/src/app.ts b/src/app.ts index 41fd67b..94746fc 100644 --- a/src/app.ts +++ b/src/app.ts @@ -6,10 +6,12 @@ import './app.scss' import {loginByOpenId} from "@/api/layout"; import {TenantId} from "@/config/app"; import {saveStorageByLoginUser} from "@/utils/server"; -import {parseInviteParams, saveInviteParams, trackInviteSource, handleInviteRelation, debugInviteInfo} from "@/utils/invite"; -import {configWebsiteField} from "@/api/cms/cmsWebsiteField"; +import {parseInviteParams, saveInviteParams, trackInviteSource, handleInviteRelation} from "@/utils/invite"; +import { useConfig } from "@/hooks/useConfig"; // 引入新的自定义Hook function App(props: { children: any; }) { + const { refetch: handleTheme } = useConfig(); // 使用新的Hook + const reload = () => { Taro.login({ success: (res) => { @@ -38,6 +40,8 @@ function App(props: { children: any; }) { }; // 可以使用所有的 React Hooks useEffect(() => { + // 设置主题 (现在由useConfig Hook处理) + handleTheme() // Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。 Taro.getSetting({ success: (res) => { @@ -53,13 +57,12 @@ function App(props: { children: any; }) { // 处理小程序启动参数中的邀请信息 const options = Taro.getLaunchOptionsSync() handleLaunchOptions(options) - handleTheme() }) // 处理启动参数 const handleLaunchOptions = (options: any) => { try { - console.log('=== 小程序启动参数处理开始 ===') + console.log('=== 小程 序启动参数处理开始 ===') console.log('完整启动参数:', JSON.stringify(options, null, 2)) // 解析邀请参数 @@ -82,10 +85,6 @@ function App(props: { children: any; }) { }) }, 1000) - // 打印调试信息 - setTimeout(() => { - debugInviteInfo() - }, 2000) } else { console.log('❌ 未检测到邀请参数') } @@ -96,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(() => { }) @@ -112,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/assets/tabbar/category-active.png b/src/assets/tabbar/category-active.png new file mode 100644 index 0000000000000000000000000000000000000000..eebe3d5d46971b34657077f1ede3b530f2c7ac8f GIT binary patch literal 3321 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 { return ( <> -
- {props.data.map((item, index) => { + + {props.data.map((item: any, index: number) => { return ( + {item.title} + {item.comments && ( + + {item.comments} + + )} + + } extra={ } @@ -18,7 +28,7 @@ const ArticleList = (props: any) => { /> ) })} -
+ ) } diff --git a/src/doctor/apply/add.config.ts b/src/doctor/apply/add.config.ts index ac37521..4748cd8 100644 --- a/src/doctor/apply/add.config.ts +++ b/src/doctor/apply/add.config.ts @@ -1,4 +1,4 @@ export default definePageConfig({ - navigationBarTitleText: '邀请注册', + navigationBarTitleText: '会员注册', navigationBarTextStyle: 'black' }) diff --git a/src/doctor/apply/add.tsx b/src/doctor/apply/add.tsx index f862bf3..897bd9b 100644 --- a/src/doctor/apply/add.tsx +++ b/src/doctor/apply/add.tsx @@ -1,5 +1,5 @@ import {useEffect, useState, useRef} from "react"; -import {Loading, CellGroup, Input, Form, Avatar, Button, Space} from '@nutui/nutui-react-taro' +import {Loading, CellGroup, Input, Form, Avatar, Radio, Button, Space, InputNumber, TextArea, ConfigProvider} from '@nutui/nutui-react-taro' import {Edit} from '@nutui/icons-react-taro' import Taro from '@tarojs/taro' import {View} from '@tarojs/components' @@ -11,6 +11,8 @@ import {User} from "@/api/system/user/model"; import {getStoredInviteParams, handleInviteRelation} from "@/utils/invite"; import {addShopDealerUser} from "@/api/shop/shopDealerUser"; import {listUserRole, updateUserRole} from "@/api/system/userRole"; +import {DictData} from "@/api/system/dict-data/model"; +import {listDictData} from "@/api/system/dict-data"; // 类型定义 interface ChooseAvatarEvent { @@ -19,16 +21,20 @@ interface ChooseAvatarEvent { }; } -interface InputEvent { - detail: { - value: string; - }; +const customTheme = { + nutuiInputnumberButtonWidth: '30px', + nutuiInputnumberButtonHeight: '30px', + nutuiInputnumberButtonBorderRadius: '2px', + nutuiInputnumberButtonBackgroundColor: `#f4f4f4`, + nutuiInputnumberInputHeight: '30px', + nutuiInputnumberInputMargin: '0 2px', } const AddUserAddress = () => { const {user, loginUser} = useUser() const [loading, setLoading] = useState(true) const [FormData, setFormData] = useState() + const [userType, setUserType] = useState() const formRef = useRef(null) const reload = async () => { @@ -47,6 +53,9 @@ const AddUserAddress = () => { nickname: '', }) } + listDictData({dictCode: 'UserType'}).then((data) => { + setUserType(data) + }) } @@ -217,23 +226,6 @@ const AddUserAddress = () => { } } - // 获取微信昵称 - const getWxNickname = (nickname: string) => { - // 更新表单数据 - const updatedFormData = { - ...FormData, - nickname: nickname - } - setFormData(updatedFormData); - - // 同步更新表单字段 - if (formRef.current) { - formRef.current.setFieldsValue({ - realName: nickname - }) - } - } - /* 获取用户手机号 */ const handleGetPhoneNumber = ({detail}: { detail: { code?: string, encryptedData?: string, iv?: string } }) => { const {code, encryptedData, iv} = detail @@ -382,9 +374,13 @@ const AddUserAddress = () => { > - - - + { + FormData?.phone && + + + } { - { - FormData?.phone && - - - } - - getWxNickname(e.detail.value)} + {FormData?.refereeId && } + + + + {FormData?.type} + + + {userType?.map((item) => ( + { + setFormData({ + ...FormData, + type: item.value + }) + }}> + {item.label} + + ))} + + + + + + 男 + + + 女 + + + + + + + + + + + + {FormData?.type == 1 && ( + +