feat(invite): 添加邀请统计功能

- 新增邀请统计页面,包含统计概览、邀请记录和排行榜三个标签页
- 实现邀请统计数据的获取和展示,包括总邀请数、成功注册数、转化率等
- 添加邀请记录的查询和展示功能
- 实现邀请排行榜的查询和展示功能
- 新增生成小程序码和处理邀请场景值的接口
This commit is contained in:
2025-08-19 01:38:37 +08:00
parent 9d9762ef17
commit f928264e2c
23 changed files with 2406 additions and 261 deletions

View File

@@ -8,6 +8,7 @@ import {TenantId} from "@/config/app";
import {getOrganization} from "@/api/system/organization";
import {myUserVerify} from "@/api/system/userVerify";
import { useShopInfo } from '@/hooks/useShopInfo';
import {handleInviteRelation} from "@/utils/invite";
import MySearch from "./MySearch";
import './Header.scss';
@@ -105,7 +106,7 @@ const Header = (props: any) => {
'content-type': 'application/json',
TenantId
},
success: function (res) {
success: async function (res) {
if (res.data.code == 1) {
Taro.showToast({
title: res.data.message,
@@ -118,6 +119,23 @@ const Header = (props: any) => {
Taro.setStorageSync('access_token', res.data.data.access_token)
Taro.setStorageSync('UserId', res.data.data.user.userId)
setIsLogin(true)
// 处理邀请关系
if (res.data.data.user?.userId) {
try {
const inviteSuccess = await handleInviteRelation(res.data.data.user.userId)
if (inviteSuccess) {
Taro.showToast({
title: '邀请关系建立成功',
icon: 'success',
duration: 2000
})
}
} catch (error) {
console.error('处理邀请关系失败:', error)
}
}
// 重新加载小程序
Taro.reLaunch({
url: '/pages/index/index'

View File

@@ -10,22 +10,23 @@ import {myUserVerify} from "@/api/system/userVerify";
import {User} from "@/api/system/user/model";
import { useShopInfo } from '@/hooks/useShopInfo';
import { useUser } from '@/hooks/useUser';
import {handleInviteRelation} from "@/utils/invite";
import MySearch from "./MySearch";
import './Header.scss';
const Header = (props: any) => {
// 使用新的hooks
const {
shopInfo,
loading: shopLoading,
getWebsiteName,
getWebsiteLogo
const {
shopInfo,
loading: shopLoading,
getWebsiteName,
getWebsiteLogo
} = useShopInfo();
const {
user,
isLoggedIn,
loading: userLoading
const {
user,
isLoggedIn,
loading: userLoading
} = useUser();
const [showBasic, setShowBasic] = useState(false)
@@ -37,10 +38,10 @@ const Header = (props: any) => {
setStatusBarHeight(res.statusBarHeight)
},
})
// 注意商店信息现在通过useShopInfo自动管理不需要手动获取
// 用户信息现在通过useUser自动管理不需要手动获取
// 如果需要获取openId可以在用户登录后处理
if (user && !user.openid) {
Taro.login({
@@ -88,7 +89,7 @@ const Header = (props: any) => {
sceneType: 'save_referee',
tenantId: TenantId
},
success: function (res) {
success: async function (res) {
if (res.data.code == 1) {
Taro.showToast({
title: res.data.message,
@@ -100,7 +101,23 @@ const Header = (props: any) => {
// 登录成功
Taro.setStorageSync('access_token', res.data.data.access_token)
Taro.setStorageSync('UserId', res.data.data.user.userId)
// 处理邀请关系
if (res.data.data.user?.userId) {
try {
const inviteSuccess = await handleInviteRelation(res.data.data.user.userId)
if (inviteSuccess) {
Taro.showToast({
title: '邀请关系建立成功',
icon: 'success',
duration: 2000
})
}
} catch (error) {
console.error('处理邀请关系失败:', error)
}
}
// 重新加载小程序
Taro.reLaunch({
url: '/pages/index/index'
@@ -179,7 +196,7 @@ const Header = (props: any) => {
<h3></h3>
<div>: {getWebsiteName()}</div>
<div>Logo: <img src={getWebsiteLogo()} alt="logo" style={{width: '50px', height: '50px'}} /></div>
<h3></h3>
<div>: {isLoggedIn ? '已登录' : '未登录'}</div>
{user && (
@@ -189,8 +206,8 @@ const Header = (props: any) => {
<div>: {user.nickname}</div>
</>
)}
<button
<button
onClick={() => setShowBasic(false)}
style={{marginTop: '20px', padding: '10px 20px'}}
>

View File

@@ -4,6 +4,7 @@ import {Input, Radio, Button} from '@nutui/nutui-react-taro'
import {TenantId} from "@/config/app";
import './login.scss';
import {saveStorageByLoginUser} from "@/utils/server";
import {handleInviteRelation} from "@/utils/invite";
// 微信获取手机号回调参数类型
interface GetPhoneNumberDetail {
@@ -58,8 +59,25 @@ const Login = (props: LoginProps) => {
'content-type': 'application/json',
TenantId
},
success: function (res: LoginResponse) {
success: async function (res: LoginResponse) {
saveStorageByLoginUser(res.data.data.access_token, res.data.data.user)
// 处理邀请关系
if (res.data.data.user?.userId) {
try {
const inviteSuccess = await handleInviteRelation(res.data.data.user.userId)
if (inviteSuccess) {
Taro.showToast({
title: '邀请关系建立成功',
icon: 'success',
duration: 2000
})
}
} catch (error) {
console.error('处理邀请关系失败:', error)
}
}
props.done?.(res.data.data.user);
}
})