feat(pages): 实现商品分类页面及优化轮播图功能

- 新增商品分类页面,包含左侧导航和右侧商品列表
- 实现分类切换和商品展示功能
- 添加骨架屏加载效果和空状态处理
- 优化首页轮播图组件,支持自动播放和触摸滑动
- 调整轮播图高度默认值为300px- 移除旧的热卖商品逻辑,改为获取推荐文章
- 修复医生申请页面用户类型选择功能
- 更新页面标题文本内容
- 添加网站配置获取hook
This commit is contained in:
2025-10-05 09:45:18 +08:00
parent 0a517b1247
commit 7b7bf80bc5
21 changed files with 1153 additions and 123 deletions

View File

@@ -1,4 +1,4 @@
export default definePageConfig({
navigationBarTitleText: '邀请注册',
navigationBarTitleText: '会员注册',
navigationBarTextStyle: 'black'
})

View File

@@ -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<boolean>(true)
const [FormData, setFormData] = useState<User>()
const [userType, setUserType] = useState<DictData[]>()
const formRef = useRef<any>(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 = () => {
>
<View className={'bg-gray-100 h-3'}></View>
<CellGroup style={{padding: '4px 0'}}>
<Form.Item name="refereeId" label="邀请人ID" initialValue={FormData?.refereeId} required>
<Input placeholder="邀请人ID" disabled={true}/>
</Form.Item>
{
FormData?.phone && <Form.Item name="avatar" label="头像" initialValue={FormData?.avatar} required>
<Button open-type="chooseAvatar" style={{height: '58px'}} onChooseAvatar={uploadAvatar}>
<Avatar src={FormData?.avatar || user?.avatar} size="54"/>
</Button>
</Form.Item>
}
<Form.Item name="phone" label="手机号" initialValue={FormData?.phone} required>
<View className="flex items-center justify-between">
<Input
@@ -400,22 +396,76 @@ const AddUserAddress = () => {
</Button>
</View>
</Form.Item>
{
FormData?.phone && <Form.Item name="avatar" label="头像" initialValue={FormData?.avatar} required>
<Button open-type="chooseAvatar" style={{height: '58px'}} onChooseAvatar={uploadAvatar}>
<Avatar src={FormData?.avatar || user?.avatar} size="54"/>
</Button>
</Form.Item>
}
<Form.Item name="realName" label="昵称" initialValue="" required>
<Input
type="nickname"
className="info-content__input"
placeholder="请获取微信昵称"
value={FormData?.nickname || ''}
onInput={(e: InputEvent) => getWxNickname(e.detail.value)}
{FormData?.refereeId && <Form.Item name="refereeId" label="邀请人ID" initialValue={FormData?.refereeId} required><Input placeholder="邀请人ID" disabled={true}/></Form.Item>}
</CellGroup>
<View className={'h-3 bg-gray-100'}></View>
<CellGroup style={{padding: '4px 0'}}>
{FormData?.type}
<Form.Item label="用户类型" name="type" initialValue={FormData?.type} required>
<Radio.Group defaultValue="1" direction="horizontal" value={FormData?.type}>
{userType?.map((item) => (
<Radio key={item.value} value={item.value} onChange={() => {
setFormData({
...FormData,
type: item.value
})
}}>
{item.label}
</Radio>
))}
</Radio.Group>
</Form.Item>
<Form.Item label="性别" name="sex" required>
<Radio.Group defaultValue="0" direction="horizontal">
<Radio value="1">
</Radio>
<Radio value="2">
</Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="真实姓名" name="realName">
<Input placeholder={'请填写真实姓名'} value={FormData?.realName || ''} />
</Form.Item>
<Form.Item label="年龄" name="age" initialValue={18} style={{
display: 'none'
}}>
<ConfigProvider theme={customTheme}>
<InputNumber defaultValue={1} />
</ConfigProvider>
<InputNumber
value={FormData?.age || 0}
/>
</Form.Item>
{FormData?.type == 1 && (
<Form.Item label="个人签名" name="introduction">
<TextArea
placeholder={'个人签名'}
style={{
height: '50px',
backgroundColor: '#fafafa',
padding: '10px',
}}
value={FormData?.introduction || ''}
/>
</Form.Item>
)}
{
FormData?.type == 2 && (
<Form.Item label="医生简介" name="introduction">
<TextArea
placeholder={'医生简介'}
style={{
height: '50px',
backgroundColor: '#fafafa',
padding: '10px',
}}
value={FormData?.introduction || ''}
/>
</Form.Item>
)
}
</CellGroup>
</Form>

View File

@@ -445,7 +445,7 @@ const CustomerIndex = () => {
<Space className="flex justify-end">
<Button
size="small"
onClick={() => navTo(`/dealer/customer/add?id=${customer.applyId}`, true)}
onClick={() => navTo(`/doctor/customer/add?id=${customer.applyId}`, true)}
style={{marginRight: '8px', backgroundColor: '#52c41a', color: 'white'}}
>
@@ -575,7 +575,7 @@ const CustomerIndex = () => {
{/* 客户列表 */}
{renderCustomerList()}
<FixedButton text={'客户报备'} onClick={() => Taro.navigateTo({url: '/dealer/customer/add'})}/>
<FixedButton text={'客户报备'} onClick={() => Taro.navigateTo({url: '/doctor/customer/add'})}/>
</View>
);
};