forked from gxwebsoft/mp-10550
refactor(invite): 重构邀请二维码生成逻辑
- 优化了 generateMiniProgramCode 函数,直接返回完整的二维码 URL - 移除了未使用的 getInviteStats 函数调用 - 增加了二维码加载失败时的错误处理和重新生成逻辑 -调整了页面布局,隐藏了邀请统计数据部分
This commit is contained in:
@@ -4,61 +4,66 @@ import {Button, Loading} from '@nutui/nutui-react-taro'
|
||||
import {Share, Download, Copy, QrCode} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {useDealerUser} from '@/hooks/useDealerUser'
|
||||
import {generateInviteCode, getInviteStats} from '@/api/invite'
|
||||
import type {InviteStats} from '@/api/invite'
|
||||
import {generateInviteCode} from '@/api/invite'
|
||||
// import type {InviteStats} from '@/api/invite'
|
||||
import {businessGradients} from '@/styles/gradients'
|
||||
|
||||
const DealerQrcode: React.FC = () => {
|
||||
const [miniProgramCodeUrl, setMiniProgramCodeUrl] = useState<string>('')
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [inviteStats, setInviteStats] = useState<InviteStats | null>(null)
|
||||
const [statsLoading, setStatsLoading] = useState<boolean>(false)
|
||||
// const [inviteStats, setInviteStats] = useState<InviteStats | null>(null)
|
||||
// const [statsLoading, setStatsLoading] = useState<boolean>(false)
|
||||
const {dealerUser} = useDealerUser()
|
||||
|
||||
// 生成小程序码
|
||||
const generateMiniProgramCode = async () => {
|
||||
if (!dealerUser?.userId) return
|
||||
if (!dealerUser?.userId) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
// 生成邀请小程序码
|
||||
const codeUrl = await generateInviteCode(dealerUser.userId)
|
||||
console.log('小程序码生成成功:', codeUrl)
|
||||
|
||||
if (codeUrl) {
|
||||
setMiniProgramCodeUrl(codeUrl)
|
||||
} else {
|
||||
throw new Error('返回的小程序码URL为空')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('生成小程序码失败:', error)
|
||||
} catch (error: any) {
|
||||
Taro.showToast({
|
||||
title: '生成小程序码失败',
|
||||
title: error.message || '生成小程序码失败',
|
||||
icon: 'error'
|
||||
})
|
||||
// 清空之前的二维码
|
||||
setMiniProgramCodeUrl('')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取邀请统计数据
|
||||
const fetchInviteStats = async () => {
|
||||
if (!dealerUser?.userId) return
|
||||
|
||||
try {
|
||||
setStatsLoading(true)
|
||||
const stats = await getInviteStats(dealerUser.userId)
|
||||
stats && setInviteStats(stats)
|
||||
} catch (error) {
|
||||
console.error('获取邀请统计失败:', error)
|
||||
} finally {
|
||||
setStatsLoading(false)
|
||||
}
|
||||
}
|
||||
// const fetchInviteStats = async () => {
|
||||
// if (!dealerUser?.userId) return
|
||||
//
|
||||
// try {
|
||||
// setStatsLoading(true)
|
||||
// const stats = await getInviteStats(dealerUser.userId)
|
||||
// stats && setInviteStats(stats)
|
||||
// } catch (error) {
|
||||
// // 静默处理错误,不影响用户体验
|
||||
// } finally {
|
||||
// setStatsLoading(false)
|
||||
// }
|
||||
// }
|
||||
|
||||
// 初始化生成小程序码和获取统计数据
|
||||
useEffect(() => {
|
||||
if (dealerUser?.userId) {
|
||||
generateMiniProgramCode()
|
||||
fetchInviteStats()
|
||||
// fetchInviteStats()
|
||||
}
|
||||
}, [dealerUser?.userId])
|
||||
|
||||
@@ -189,11 +194,6 @@ const DealerQrcode: React.FC = () => {
|
||||
|
||||
<View className="px-4">
|
||||
{/* 小程序码展示区 */}
|
||||
{/*<Image*/}
|
||||
{/* src={'http://127.0.0.1:9200/api/wx-login/getOrderQRCodeUnlimited/33103'}*/}
|
||||
{/* className="w-full h-full"*/}
|
||||
{/* mode="aspectFit"*/}
|
||||
{/*/>*/}
|
||||
<View className="bg-white rounded-2xl p-6 mb-6 shadow-sm">
|
||||
<View className="text-center">
|
||||
{loading ? (
|
||||
@@ -207,6 +207,20 @@ const DealerQrcode: React.FC = () => {
|
||||
src={miniProgramCodeUrl}
|
||||
className="w-full h-full"
|
||||
mode="aspectFit"
|
||||
onError={() => {
|
||||
Taro.showModal({
|
||||
title: '二维码加载失败',
|
||||
content: '请检查网络连接或联系管理员',
|
||||
showCancel: true,
|
||||
confirmText: '重新生成',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
generateMiniProgramCode();
|
||||
}
|
||||
}
|
||||
});
|
||||
}}
|
||||
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
@@ -227,9 +241,11 @@ const DealerQrcode: React.FC = () => {
|
||||
<View className="text-lg font-semibold text-gray-800 mb-2">
|
||||
扫码加入我的团队
|
||||
</View>
|
||||
<View className="text-sm text-gray-500 mb-6">
|
||||
<View className="text-sm text-gray-500 mb-4">
|
||||
好友扫描小程序码即可直接进入小程序并建立邀请关系
|
||||
</View>
|
||||
|
||||
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -273,7 +289,7 @@ const DealerQrcode: React.FC = () => {
|
||||
</View>
|
||||
|
||||
{/* 推广说明 */}
|
||||
<View className="bg-white rounded-2xl p-4 mt-6">
|
||||
<View className="bg-white rounded-2xl p-4 mt-6 hidden">
|
||||
<Text className="font-semibold text-gray-800 mb-3">推广说明</Text>
|
||||
<View className="space-y-2">
|
||||
<View className="flex items-start">
|
||||
@@ -298,82 +314,82 @@ const DealerQrcode: React.FC = () => {
|
||||
</View>
|
||||
|
||||
{/* 邀请统计数据 */}
|
||||
<View className="bg-white rounded-2xl p-4 mt-4 mb-6">
|
||||
<Text className="font-semibold text-gray-800 mb-3">我的邀请数据</Text>
|
||||
{statsLoading ? (
|
||||
<View className="flex items-center justify-center py-8">
|
||||
<Loading/>
|
||||
<Text className="text-gray-500 mt-2">加载中...</Text>
|
||||
</View>
|
||||
) : inviteStats ? (
|
||||
<View className="space-y-4">
|
||||
<View className="grid grid-cols-2 gap-4">
|
||||
<View className="text-center">
|
||||
<Text className="text-2xl font-bold text-blue-500">
|
||||
{inviteStats.totalInvites || 0}
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500">总邀请数</Text>
|
||||
</View>
|
||||
<View className="text-center">
|
||||
<Text className="text-2xl font-bold text-green-500">
|
||||
{inviteStats.successfulRegistrations || 0}
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500">成功注册</Text>
|
||||
</View>
|
||||
</View>
|
||||
{/*<View className="bg-white rounded-2xl p-4 mt-4 mb-6">*/}
|
||||
{/* <Text className="font-semibold text-gray-800 mb-3">我的邀请数据</Text>*/}
|
||||
{/* {statsLoading ? (*/}
|
||||
{/* <View className="flex items-center justify-center py-8">*/}
|
||||
{/* <Loading/>*/}
|
||||
{/* <Text className="text-gray-500 mt-2">加载中...</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* ) : inviteStats ? (*/}
|
||||
{/* <View className="space-y-4">*/}
|
||||
{/* <View className="grid grid-cols-2 gap-4">*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <Text className="text-2xl font-bold text-blue-500">*/}
|
||||
{/* {inviteStats.totalInvites || 0}*/}
|
||||
{/* </Text>*/}
|
||||
{/* <Text className="text-sm text-gray-500">总邀请数</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <Text className="text-2xl font-bold text-green-500">*/}
|
||||
{/* {inviteStats.successfulRegistrations || 0}*/}
|
||||
{/* </Text>*/}
|
||||
{/* <Text className="text-sm text-gray-500">成功注册</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
|
||||
<View className="grid grid-cols-2 gap-4">
|
||||
<View className="text-center">
|
||||
<Text className="text-2xl font-bold text-purple-500">
|
||||
{inviteStats.conversionRate ? `${(inviteStats.conversionRate * 100).toFixed(1)}%` : '0%'}
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500">转化率</Text>
|
||||
</View>
|
||||
<View className="text-center">
|
||||
<Text className="text-2xl font-bold text-orange-500">
|
||||
{inviteStats.todayInvites || 0}
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500">今日邀请</Text>
|
||||
</View>
|
||||
</View>
|
||||
{/* <View className="grid grid-cols-2 gap-4">*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <Text className="text-2xl font-bold text-purple-500">*/}
|
||||
{/* {inviteStats.conversionRate ? `${(inviteStats.conversionRate * 100).toFixed(1)}%` : '0%'}*/}
|
||||
{/* </Text>*/}
|
||||
{/* <Text className="text-sm text-gray-500">转化率</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <Text className="text-2xl font-bold text-orange-500">*/}
|
||||
{/* {inviteStats.todayInvites || 0}*/}
|
||||
{/* </Text>*/}
|
||||
{/* <Text className="text-sm text-gray-500">今日邀请</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
|
||||
{/* 邀请来源统计 */}
|
||||
{inviteStats.sourceStats && inviteStats.sourceStats.length > 0 && (
|
||||
<View className="mt-4">
|
||||
<Text className="text-sm font-medium text-gray-700 mb-2">邀请来源分布</Text>
|
||||
<View className="space-y-2">
|
||||
{inviteStats.sourceStats.map((source, index) => (
|
||||
<View key={index} className="flex items-center justify-between py-2 px-3 bg-gray-50 rounded-lg">
|
||||
<View className="flex items-center">
|
||||
<View className="w-3 h-3 rounded-full bg-blue-500 mr-2"></View>
|
||||
<Text className="text-sm text-gray-700">{source.source}</Text>
|
||||
</View>
|
||||
<View className="text-right">
|
||||
<Text className="text-sm font-medium text-gray-800">{source.count}</Text>
|
||||
<Text className="text-xs text-gray-500">
|
||||
{source.conversionRate ? `${(source.conversionRate * 100).toFixed(1)}%` : '0%'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
) : (
|
||||
<View className="text-center py-8">
|
||||
<View className="text-gray-500">暂无邀请数据</View>
|
||||
<Button
|
||||
size="small"
|
||||
type="primary"
|
||||
className="mt-2"
|
||||
onClick={fetchInviteStats}
|
||||
>
|
||||
刷新数据
|
||||
</Button>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
{/* /!* 邀请来源统计 *!/*/}
|
||||
{/* {inviteStats.sourceStats && inviteStats.sourceStats.length > 0 && (*/}
|
||||
{/* <View className="mt-4">*/}
|
||||
{/* <Text className="text-sm font-medium text-gray-700 mb-2">邀请来源分布</Text>*/}
|
||||
{/* <View className="space-y-2">*/}
|
||||
{/* {inviteStats.sourceStats.map((source, index) => (*/}
|
||||
{/* <View key={index} className="flex items-center justify-between py-2 px-3 bg-gray-50 rounded-lg">*/}
|
||||
{/* <View className="flex items-center">*/}
|
||||
{/* <View className="w-3 h-3 rounded-full bg-blue-500 mr-2"></View>*/}
|
||||
{/* <Text className="text-sm text-gray-700">{source.source}</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* <View className="text-right">*/}
|
||||
{/* <Text className="text-sm font-medium text-gray-800">{source.count}</Text>*/}
|
||||
{/* <Text className="text-xs text-gray-500">*/}
|
||||
{/* {source.conversionRate ? `${(source.conversionRate * 100).toFixed(1)}%` : '0%'}*/}
|
||||
{/* </Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
{/* ))}*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
{/* )}*/}
|
||||
{/* </View>*/}
|
||||
{/* ) : (*/}
|
||||
{/* <View className="text-center py-8">*/}
|
||||
{/* <View className="text-gray-500">暂无邀请数据</View>*/}
|
||||
{/* <Button*/}
|
||||
{/* size="small"*/}
|
||||
{/* type="primary"*/}
|
||||
{/* className="mt-2"*/}
|
||||
{/* onClick={fetchInviteStats}*/}
|
||||
{/* >*/}
|
||||
{/* 刷新数据*/}
|
||||
{/* </Button>*/}
|
||||
{/* </View>*/}
|
||||
{/* )}*/}
|
||||
{/*</View>*/}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user