feat: scan QRCode auto redeem coupon (#5616)

* feat: scan QRCode auto redeem coupon

* feat: use hook to auto redeem, instead of modify auth
This commit is contained in:
Zeng Qingwen
2025-09-12 09:54:36 +08:00
committed by GitHub
parent 635e606ef1
commit 768fb63b88
4 changed files with 49 additions and 2 deletions

View File

@@ -0,0 +1,23 @@
import { useEffect, useRef } from 'react';
import { getCouponCode, removeCouponCode } from '@/web/support/marketing/utils';
import type { UserType } from '@fastgpt/global/support/user/type.d';
import { redeemCoupon } from '@/web/support/user/team/api';
export const useCheckCoupon = (userInfo: UserType | null) => {
const hasCheckedCouponRef = useRef(false);
useEffect(() => {
if (!userInfo || hasCheckedCouponRef.current) return;
const couponCode = getCouponCode();
if (!couponCode) return;
hasCheckedCouponRef.current = true;
redeemCoupon(couponCode)
.catch(() => {})
.finally(removeCouponCode);
}, [userInfo]);
};
export default useCheckCoupon;

View File

@@ -15,6 +15,7 @@ import { useDebounceEffect, useMount } from 'ahooks';
import { useTranslation } from 'next-i18next';
import { useToast } from '@fastgpt/web/hooks/useToast';
import WorkorderButton from './WorkorderButton';
import { useCheckCoupon } from './hooks/checkCoupon';
const Navbar = dynamic(() => import('./navbar'));
const NavbarPhone = dynamic(() => import('./navbarPhone'));
@@ -74,6 +75,8 @@ const Layout = ({ children }: { children: JSX.Element }) => {
const { userInfo, isUpdateNotification, setIsUpdateNotification } = useUserStore();
const { setUserDefaultLng } = useI18nLng();
useCheckCoupon(userInfo);
const isChatPage = useMemo(
() => router.pathname === '/chat' && Object.values(router.query).join('').length !== 0,
[router.pathname, router.query]

View File

@@ -17,6 +17,7 @@ import {
setUtmWorkflow
} from '../support/marketing/utils';
import { type ShortUrlParams } from '@fastgpt/global/support/marketing/type';
import { setCouponCode } from '@/web/support/marketing/utils';
type MarketingQueryParams = {
hiId?: string;
@@ -29,6 +30,7 @@ type MarketingQueryParams = {
utm_medium?: string;
utm_content?: string;
utm_workflow?: string;
couponCode?: string;
};
const MARKETING_PARAMS: (keyof MarketingQueryParams)[] = [
@@ -40,7 +42,8 @@ const MARKETING_PARAMS: (keyof MarketingQueryParams)[] = [
'utm_source',
'utm_medium',
'utm_content',
'utm_workflow'
'utm_workflow',
'couponCode'
];
export const useInitApp = () => {
@@ -55,7 +58,8 @@ export const useInitApp = () => {
utm_source,
utm_medium,
utm_content,
utm_workflow
utm_workflow,
couponCode
} = router.query as MarketingQueryParams;
const { loadGitStar, setInitd, feConfigs } = useSystemStore();
@@ -149,6 +153,10 @@ export const useInitApp = () => {
}
setFastGPTSem({ keyword: k, search, ...utmParams });
if (couponCode) {
setCouponCode(couponCode);
}
const newPath = getPathWithoutMarketingParams();
router.replace(newPath);
});

View File

@@ -90,3 +90,16 @@ export const setSourceDomain = (sourceDomain?: string) => {
if (!formatSourceDomain || getSourceDomain()) return;
sessionStorage.setItem('sourceDomain', formatSourceDomain);
};
export const setCouponCode = (couponCode?: string) => {
if (!couponCode) return;
localStorage.setItem('couponCode', couponCode);
};
export const getCouponCode = () => {
return localStorage.getItem('couponCode') || undefined;
};
export const removeCouponCode = () => {
localStorage.removeItem('couponCode');
};