Prechádzať zdrojové kódy

fix: 增加返现多语言

Before 10 mesiacov pred
rodič
commit
a831497516

+ 16 - 2
messages/br.json

@@ -129,7 +129,7 @@
     "deposits": "Depósitos",
     "saques": "Saques",
     "bonus":  "Bônus",
-    "expTips": "leia {exp} atualizando para"
+    "expTips": "{exp} Apostas to "
   },
   "DepositPage": {
     "Montante": "Montante",
@@ -259,7 +259,21 @@
     "content6-3":"Aposta válidas em equiper[num] - Total de valor de apostas válidas provenientes de indicações e contribuições de suas equipes. num - Número total de indicações e membros de suas equipes que contribuíram com apostas válidas."
   },
   "cashback": {
-    "cashbackTitle": "Cashback 25%"
+    "cashbackTitle": "Cashback",
+    "weekCashback": "Seu Cashback de Semanal",
+    "weekTips": "Você ganhará",
+    "weekAfterTips": "BRL em cashback jogando esta semana.",
+    "afterTips": "Tempo de reivindicação",
+    "beforeTips": "Periodo",
+    "cashbackStatus": "VIP cashback statuses",
+    "rules": "TERMOS E REGRAS",
+    "rulesFirst": "1. O cashback semanal é dado como recompensa todas as semanas.",
+    "rulesSecond": "2. O período sobre o qual é calculado o cashback semanal vai de segunda-feira às 00:00 a domingo às 23:59.",
+    "rulesThird": "3. Horário de solicitação do cashback: De segunda-feira da próxima semana 06:00 a sexta-feira 23:59, expirará se não for resgatado.",
+    "rulesFourth": "4. O número de Perdas de dinheiro real multiplicado pela % de reembolso é o reembolso/cashback da semana.",
+    "rulesFifth": "5. Caso você não tenha apostado durante o período em que o cashback estava ativo ou se seus ganhos da última semana ou ganhos totais são maiores que suas perdas, você não receberá cashback.",
+    "rulesSixth": "6. Limite máximo de recompensa de cashback por pessoa por semana: R$ 10000",
+    "rulesSeventh": "7. O valor do cashback pode ser sacar diretamente ou utilizado para continuar jogando"
   },
   "code": {
       "1005": "Nome de usuário ou senha incorreta. ",

+ 18 - 2
messages/en.json

@@ -130,7 +130,7 @@
     "deposits": "Depósitos",
     "saques": "Saques",
     "bonus":  "Bônus",
-    "expTips": "leia {exp} atualizando para"
+    "expTips": "{exp} Bet to "
   },
   "DepositPage": {
     "Montante": "Montante",
@@ -260,7 +260,23 @@
     "content6-3":"Aposta válidas em equiper[num] - Total de valor de apostas válidas provenientes de indicações e contribuições de suas equipes. num - Número total de indicações e membros de suas equipes que contribuíram com apostas válidas."
   },
   "cashback": {
-    "cashbackTitle": "Cashback 25%"
+    "cashbackTitle": "Cashback",
+    "weekCashback": "Your Weekly Cashback",
+    "weekTips": "You'll win",
+    "weekAfterTips": "BRL in cashback playing this week.",
+    "afterTips": "Time of claim",
+    "beforeTips": "Period",
+    "cashbackStatus": "VIP cashback statuses",
+
+    "rules": "TERMS AND RULES",
+    "rulesFirst": "1. The weekly cashback is given as a reward every week.",
+    "rulesSecond": "2. The period for which weekly cashback is calculated goes from Monday to Sunday at 11:59 p.m.",
+    "rulesThird": "3. Cashback application time: From Monday next week 06:00 to Friday 23:59, expires if not rescued",
+    "rulesFourth": "4. The number of real money losses multiplied by the % of reimbursement is the reimbursement/cashback of the week.",
+    "rulesFifth": "5. If you have not bet during the period in which the cashback was active or if your earnings of the last week or total earnings are greater than your losses, you will not receive cashback.",
+    "rulesSixth": "6. Cashback maximum per person per week: R$ 10000",
+    "rulesSeventh": "7. Cashback value can be extracted directly or used to continue playing"
+
   },
   "code": {
     "1005": "Invalid username or password.",

+ 19 - 1
messages/zh.json

@@ -129,7 +129,7 @@
     "deposits": "存款",
     "saques": "提款",
     "bonus": "奖金",
-    "expTips": "leia {exp} atualizando para"
+    "expTips": "{exp} 升级至 "
   },
   "DepositPage": {
     "Montante": "金额",
@@ -258,6 +258,24 @@
     "content6-2": "新玩家 - 今天注册的付费新玩家",
     "content6-3": "有效团队投注[num] - 来源于推荐和团队成员的有效投注总金额。num - 提供有效投注的总推荐次数和团队成员数量。"
   },
+  "cashback": {
+    "cashbackTitle": "Cashback",
+    "weekCashback": "您的每周现金返还",
+    "weekTips": "你会赢",
+    "weekAfterTips": "BRL本周正在进行返现游戏。",
+    "afterTips": "返现时间",
+    "beforeTips": "期间",
+    "cashbackStatus": "VIP 返现状态",
+    "rules": "条款和规则",
+    "rulesFirst": "1.每周返现作为每周的奖励。",
+    "rulesSecond": "2.计算每周现金返还的时间为周一至周日晚上11:59。",
+    "rulesThird": "3.返现申请时间:下周一06:00至周五23:59,如未获救则到期",
+    "rulesFourth": "4.实际损失金额乘以报销百分比即为本周的报销/现金返还。",
+    "rulesFifth": "5.如果您在返现活动期间没有下注,或者您上周的收入或总收入大于您的损失,您将不会收到返现。",
+    "rulesSixth": "6.每人每周最高现金返还额:R$ 10000",
+    "rulesSeventh": "7.返现值可以直接提取或用于继续玩儿"
+
+  },
   "code": {
     "1005": "用户名或密码无效",
     "1009": "无此用户",

+ 4 - 4
src/api/user.ts

@@ -185,19 +185,19 @@ export interface UserVipInfo {
     /**
      * vip经验
      */
-    vip_exp?: number;
+    vip_exp: number;
     /**
      * vip等级
      */
-    vip_level?: number;
+    vip_level: number;
     /**
      * 下一级vip等级
      */
-    vip_next_level?: any;
+    vip_next_level: any;
     /**
      * vip等级经验
      */
-    vip_score_exp?: number;
+    vip_score_exp: number;
 }
 export const getUserVipApi = () => {
     return server.post<UserVipInfo>({

+ 6 - 3
src/app/[locale]/(TabBar)/(ordinary)/profile/ProfileHeader.tsx

@@ -1,6 +1,7 @@
 "use client";
 import { UserInfoRep, UserVipInfo, Wallet } from "@/api/user";
 import { Link } from "@/i18n";
+import { percentage } from "@/utils/methods";
 import { ProgressBar } from "antd-mobile";
 import { useTranslations } from "next-intl";
 import Image from "next/image";
@@ -67,10 +68,10 @@ export const ProfileHeader = (props: Props) => {
                 <div className={"vip-card"}>
                     <div className={"vip-card__icon"}>{vipIconElement}</div>
                     <div className={"vip-card-process"}>
-                        <div className={"process-top"}>{userVip.vip_exp}xp</div>
+                        {/*<div className={"process-top"}>{userVip.vip_exp}xp</div>*/}
                         <div>
                             <ProgressBar
-                                percent={userVip.vip_exp}
+                                percent={percentage(userVip.vip_exp, userVip.vip_score_exp)}
                                 style={{
                                     "--fill-color": "#fb8b05",
                                     "--track-width": "0.0694rem",
@@ -80,7 +81,9 @@ export const ProfileHeader = (props: Props) => {
                         <div className={"process-bottom"}>
                             <span>VIP{userVip.vip_level}</span>
                             <span className={"process-bottom-desc"}>
-                                {t("expTips", { exp: userVip.vip_score_exp })}
+                                {t("expTips", {
+                                    exp: userVip.vip_score_exp - userVip.vip_exp,
+                                })}
                             </span>
                             <span>
                                 VIP

+ 2 - 2
src/app/[locale]/(TabBar)/(ordinary)/profile/component/ModalCom/index.tsx

@@ -1,8 +1,8 @@
 "use client";
 import { getLogoutApi } from "@/api/user";
 import { useRouter } from "@/i18n";
-import { useGlobalStore } from "@/stores";
 import { useSearchStore } from "@/stores/useSearchStore";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { useWalletStore } from "@/stores/useWalletStore";
 import { CenterPopup } from "antd-mobile";
 import Cookies from "js-cookie";
@@ -20,7 +20,7 @@ export interface ItemComProps {
 
 const ModalCom: FC<PropsWithChildren<ItemComProps>> = () => {
     const t = useTranslations("ProfilePage");
-    const restGlobal = useGlobalStore((state) => state.reset);
+    const restGlobal = useUserInfoStore((state) => state.reset);
     const resetSearch = useSearchStore((state) => state.reset);
     const restWalletStore = useWalletStore((state) => state.reset);
 

+ 1 - 2
src/app/[locale]/(TabBar)/(ordinary)/profile/page.tsx

@@ -42,7 +42,6 @@ const getVipApi = async () => {
         })
         .then((res) => {
             if (res.code === 200) return res.data;
-            return {};
         });
 };
 interface Props {}
@@ -52,7 +51,7 @@ const Profile: FC<Props> = async () => {
     const userVip = await getVipApi();
     return (
         <div className="profile-box">
-            <ProfileHeader userInfo={userInfo} userMoney={userMoney} userVip={userVip} />
+            <ProfileHeader userInfo={userInfo} userMoney={userMoney} userVip={userVip!} />
             <ItemCom />
             <ModalCom />
         </div>

+ 2 - 2
src/app/[locale]/(enter)/components/FromCom/index-copy.tsx

@@ -1,7 +1,7 @@
 "use client";
 import ButtonOwn from "@/components/ButtonOwn";
 import { Link, useRouter } from "@/i18n";
-import { useGlobalStore } from "@/stores";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { setCookies } from "@/utils/Cookies";
 import { Toast } from "antd-mobile";
 import clsx from "clsx";
@@ -41,7 +41,7 @@ const FromCom: FC<PropsWithChildren<FromComProps>> = ({ type = "login", msgError
     let [pwdVisible, setPwdVisible] = useState(false);
     const searchParams = useSearchParams();
     const router = useRouter();
-    const { setUserInfo } = useGlobalStore();
+    const { setUserInfo } = useUserInfoStore();
     const [loginFormStatus, setLoginFormStatus] = useState<{ success?: boolean; message?: string }>(
         {}
     );

+ 2 - 2
src/app/[locale]/(enter)/components/FromCom/index.tsx

@@ -1,7 +1,7 @@
 "use client";
 import ButtonOwn from "@/components/ButtonOwn";
 import { Link, useRouter } from "@/i18n";
-import { useGlobalStore } from "@/stores";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { Toast } from "antd-mobile";
 import clsx from "clsx";
 import { useTranslations } from "next-intl";
@@ -40,7 +40,7 @@ const FromCom: FC<PropsWithChildren<FromComProps>> = ({ type = "login", msgError
     let [pwdVisible, setPwdVisible] = useState(false);
     const searchParams = useSearchParams();
     const router = useRouter();
-    const { setUserInfo } = useGlobalStore();
+    const { setUserInfo } = useUserInfoStore();
     const [loginFormStatus, setLoginFormStatus] = useState<{ success?: boolean; message?: string }>(
         {}
     );

+ 3 - 1
src/app/[locale]/(navbar)/cashback/@cashbackInfo/CashbackTable.tsx

@@ -2,6 +2,7 @@
 import { CashbackTypes, Rule } from "@/api/cashback";
 import Box from "@/components/Box";
 import Table, { TableHeaderItem } from "@/components/Table";
+import { useTranslations } from "next-intl";
 import { JSX } from "react";
 
 interface Props {
@@ -9,6 +10,7 @@ interface Props {
 }
 const Page = (props: Props) => {
     const { cashbackInfo } = props;
+    const t = useTranslations("cashback");
     const columns: TableHeaderItem[] = [
         {
             title: <div className={"text-center text-primary-color"}>VIP</div>,
@@ -44,7 +46,7 @@ const Page = (props: Props) => {
     };
     return (
         <Box className={"mt-[10px] rounded-[10px] bg-[#ededed]"}>
-            <div> VIP cashback statuses </div>
+            <div> {t("cashbackStatus")}</div>
             <Table
                 columns={columns}
                 dataSource={cashbackInfo.rules}

+ 7 - 7
src/app/[locale]/(navbar)/cashback/@cashbackInfo/Week.tsx

@@ -1,7 +1,7 @@
 import { CashbackTypes } from "@/api/cashback";
 import Box from "@/components/Box";
 import { timeFormat } from "@/utils/methods";
-import { getLocale } from "next-intl/server";
+import { getLocale, getTranslations } from "next-intl/server";
 import Extract from "./components/Extract";
 
 interface Props {
@@ -10,18 +10,18 @@ interface Props {
 const Page = async (props: Props) => {
     const { cashbackInfo } = props;
     const local = await getLocale();
-    console.log(`🚀🚀🚀🚀🚀-> in Week.tsx on 11`, cashbackInfo);
+    const t = await getTranslations("cashback");
     return (
         <Box className={"mt-[10px] rounded-[10px] bg-[#e8e8e8]"}>
             <div className={"flex"}>
                 <div className={"flex-1"}>
                     <h1 className={"text-[0.18rem] font-black text-primary-color"}>
-                        Seu Cashback de Semanal
+                        {t("weekCashback")}
                     </h1>
                     <p className={"text-[0.12rem]"}>
-                        <span>Você ganhará </span>
+                        <span> {t("weekTips")} </span>
                         <span className={"text-primary-color"}>{cashbackInfo.amount ?? "???"}</span>
-                        <span> BRL em cashback jogando esta semana.</span>
+                        <span> {t("weekAfterTips")} </span>
                     </p>
                 </div>
 
@@ -36,14 +36,14 @@ const Page = async (props: Props) => {
             </div>
             <p className={"mb-[0.05rem] text-[0.12rem] text-[#ff9323]"}>
                 <span>
-                    Periodo {timeFormat(cashbackInfo.last_period.start_time, local)} ~{" "}
+                    {t("beforeTips")} {timeFormat(cashbackInfo.last_period.start_time, local)} ~{" "}
                     {timeFormat(cashbackInfo.last_period.end_time, local)}
                 </span>
             </p>
             <Extract />
 
             <div className={"mt-[0.05rem]"}>
-                <p>Tempo de reivindicação</p>
+                <p> {t("afterTips")} </p>
                 <p>
                     {timeFormat(cashbackInfo.next_period.start_time, local)} ~{" "}
                     {timeFormat(cashbackInfo.next_period.end_time, local)}

+ 18 - 5
src/app/[locale]/(navbar)/cashback/@cashbackInfo/page.tsx

@@ -1,7 +1,9 @@
 import { CashbackTypes } from "@/api/cashback";
 import { UserVipInfo } from "@/api/user";
 import Box from "@/components/Box";
+import { percentage } from "@/utils/methods";
 import { server } from "@/utils/server";
+import { getTranslations } from "next-intl/server";
 import CashbackTable from "./CashbackTable";
 import Progress from "./components/Progress";
 import Week from "./Week";
@@ -14,7 +16,12 @@ const getVipInfoApi = async () => {
         })
         .then((res) => {
             if (res.code === 200) return res.data;
-            return {};
+            return {
+                vip_exp: 0,
+                vip_level: 0,
+                vip_next_level: 0,
+                vip_score_exp: 0,
+            };
         });
 };
 
@@ -34,6 +41,9 @@ const CashbackInfo = async () => {
 
     const currentGrade = cashbackInfo.rules.find((item) => item.level === (vipInfo.vip_level || 1));
     const maxGrade = cashbackInfo.rules.at(-1);
+
+    const t = await getTranslations();
+
     return (
         <>
             <Box className={"w-full rounded-[10px] bg-gradient-to-b from-[#ffaa30] to-[#ffe6be]"}>
@@ -47,7 +57,9 @@ const CashbackInfo = async () => {
                         <span className={"mr-[0.06rem] text-[0.25rem] font-bold"}>
                             {currentGrade?.cashback}%
                         </span>
-                        <span className={"mr-[0.06rem] text-[0.25rem] font-bold"}>Cashback</span>
+                        <span className={"mr-[0.06rem] text-[0.25rem] font-bold"}>
+                            {t("cashback.cashbackTitle")}
+                        </span>
                         <span className={"align-text-bottom text-[0.1rem] text-[#383838]"}>
                             Max {maxGrade?.cashback}%
                         </span>
@@ -60,14 +72,15 @@ const CashbackInfo = async () => {
                                 " ml-[0.06rem] rounded-[0.03rem] text-[0.1rem]"
                             }
                         >
-                            v{vipInfo.vip_exp}
+                            v{vipInfo.vip_level}
                         </div>
                     </div>
                 </div>
                 <div className={"mt-[0.1rem]"}>
-                    <Progress num={vipInfo.vip_exp ?? 0} />
+                    <Progress num={percentage(vipInfo?.vip_exp, vipInfo.vip_score_exp)} />
                     <div className={"font-lightl mt-[0.04rem] text-right text-[0.1rem]"}>
-                        {vipInfo.vip_level} Apostas to VIP{vipInfo.vip_next_level}
+                        {t("ProfilePage.expTips", { exp: vipInfo.vip_score_exp - vipInfo.vip_exp })}
+                        VIP{vipInfo.vip_next_level}
                     </div>
                 </div>
             </Box>

+ 12 - 25
src/app/[locale]/(navbar)/cashback/page.tsx

@@ -1,31 +1,18 @@
-const page = () => {
+import { getTranslations } from "next-intl/server";
+
+const page = async () => {
+    const t = await getTranslations("cashback");
     return (
         <div className={"mt-[0.0694rem]"}>
-            <h1 className={"font-bold"}>TERMOS E REGRAS</h1>
+            <h1 className={"font-bold"}>{t("rules")}</h1>
             <ul className={"text-[0.11rem] leading-[0.18rem]"}>
-                <li>1. O cashback semanal é dado como recompensa todas as semanas. </li>
-                <li>
-                    2. O período sobre o qual é calculado o cashback semanal vai de segunda-feira às
-                    00:00 a domingo às 23:59.
-                </li>
-                <li>
-                    3. Horário de solicitação do cashback: De segunda-feira da próxima semana 06:00
-                    a sexta-feira 23:59, expirará se não for resgatado.
-                </li>
-                <li>
-                    4. O número de Perdas de dinheiro real multiplicado pela % de reembolso é o
-                    reembolso/cashback da semana.
-                </li>
-                <li>
-                    5. Caso você não tenha apostado durante o período em que o cashback estava ativo
-                    ou se seus ganhos da última semana ou ganhos totais são maiores que suas perdas,
-                    você não receberá cashback.
-                </li>
-                <li>6. Limite máximo de recompensa de cashback por pessoa por semana: R$ 10000</li>
-                <li>
-                    7. O valor do cashback pode ser sacar diretamente ou utilizado para continuar
-                    jogando
-                </li>
+                <li>{t("rulesFirst")} </li>
+                <li>{t("rulesSecond")}</li>
+                <li>{t("rulesThird")}</li>
+                <li>{t("rulesFourth")}</li>
+                <li>{t("rulesFifth")}</li>
+                <li>{t("rulesSixth")}</li>
+                <li>{t("rulesSeventh")}</li>
             </ul>
         </div>
     );

+ 2 - 2
src/app/[locale]/affiliate/summary/page.tsx

@@ -7,7 +7,7 @@ import {
     UserAgentToDayInfo,
     UserCommissionStatistics,
 } from "@/api/summary";
-import { useGlobalStore } from "@/stores";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { useRequest } from "ahooks";
 import { Toast } from "antd-mobile";
 import { useLocale, useTranslations } from "next-intl";
@@ -26,7 +26,7 @@ const App: FC<Props> = (props) => {
     const sliderRef = useRef<HTMLDivElement>(null);
     const [num, setNum] = useState(100);
     const [money, setMoney] = useState("5000");
-    const { userInfo } = useGlobalStore();
+    const { userInfo } = useUserInfoStore();
     const token = getToken();
     const shareUrl = `http://192.168.0.84:3000/${locale}/${userInfo ? userInfo.referrer_code : "xxxxxx"}`;
     const TIME = 180000;

+ 2 - 2
src/app/[locale]/confirmPassword/page.tsx

@@ -4,7 +4,7 @@ import ButtonOwn from "@/components/ButtonOwn";
 import DomainFooter from "@/components/DomainFooter";
 import HeaderBack from "@/components/HeaderBack";
 import { Link, useRouter } from "@/i18n";
-import { useGlobalStore } from "@/stores";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { Toast } from "antd-mobile";
 import { useTranslations } from "next-intl";
 import { useSearchParams } from "next/navigation";
@@ -64,7 +64,7 @@ const ResetPhone: FC<Props> = () => {
         return false;
     }, [fromParam]);
 
-    const { setUserInfo } = useGlobalStore();
+    const { setUserInfo } = useUserInfoStore();
     let [msgError, setMsgError] = useState("");
     const findPwdRequest = () => {
         let { pwd, againPwd } = fromParam;

+ 2 - 2
src/components/Header/HeaderRight.tsx

@@ -1,6 +1,6 @@
 import { getUserMoneyApi } from "@/api/user";
 import { Link } from "@/i18n";
-import { useGlobalStore } from "@/stores";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { useWalletStore } from "@/stores/useWalletStore";
 import { getToken } from "@/utils/Cookies";
 import { useRequest } from "ahooks";
@@ -9,7 +9,7 @@ import styles from "./style.module.scss";
 
 const HeaderRight = () => {
     const t = useTranslations("Header");
-    const { userInfo } = useGlobalStore();
+    const { userInfo } = useUserInfoStore();
     const token = getToken();
     const score = useWalletStore((state) => state.score);
     const setScore = useWalletStore((state) => state.setScore);

+ 1 - 35
src/stores/index.ts

@@ -1,35 +1 @@
-import { create } from "zustand";
-import { createJSONStorage, devtools, persist } from "zustand/middleware";
-
-interface State {
-    userInfo: any;
-}
-
-interface Action {
-    setUserInfo: (lang: State["userInfo"]) => void;
-    reset: () => void;
-}
-const initialState: State = {
-    userInfo: "",
-};
-export const useGlobalStore = create<State & Action>()(
-    devtools(
-        persist(
-            (set) => {
-                return {
-                    ...initialState,
-                    setUserInfo: (userInfo: State["userInfo"]) =>
-                        set({
-                            userInfo,
-                        }),
-                    reset: () => set(initialState),
-                };
-            },
-            {
-                name: "globalStore",
-                storage: createJSONStorage(() => localStorage),
-            }
-        ),
-        { name: "globalStore" }
-    )
-);
+//  TODO 将各个store 整合为一个库 // 添加统一清除方法

+ 35 - 0
src/stores/useUserInfoStore.ts

@@ -0,0 +1,35 @@
+import { create } from "zustand";
+import { createJSONStorage, devtools, persist } from "zustand/middleware";
+
+interface State {
+    userInfo: any;
+}
+
+interface Action {
+    setUserInfo: (lang: State["userInfo"]) => void;
+    reset: () => void;
+}
+const initialState: State = {
+    userInfo: "",
+};
+export const useUserInfoStore = create<State & Action>()(
+    devtools(
+        persist(
+            (set) => {
+                return {
+                    ...initialState,
+                    setUserInfo: (userInfo: State["userInfo"]) =>
+                        set({
+                            userInfo,
+                        }),
+                    reset: () => set(initialState),
+                };
+            },
+            {
+                name: "globalStore",
+                storage: createJSONStorage(() => localStorage),
+            }
+        ),
+        { name: "globalStore" }
+    )
+);

+ 2 - 2
src/utils/client/index.ts

@@ -1,4 +1,4 @@
-import { useGlobalStore } from "@/stores";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { useWalletStore } from "@/stores/useWalletStore";
 import actions from "@/utils/client/actions";
 import Request from "./axios";
@@ -28,7 +28,7 @@ const server = new Request({
                 case 401:
                     localStorage.removeItem("globalStore");
                     useWalletStore.getState().reset();
-                    useGlobalStore.getState().reset();
+                    useUserInfoStore.getState().reset();
                     await actions();
                     break;
                 default:

+ 7 - 0
src/utils/methods/index.ts

@@ -72,3 +72,10 @@ export let copyText = function (text: string) {
     }
     copyText(text);
 };
+
+/**
+ * @description 两个数值计算百分比
+ */
+export const percentage = (current: number, source: number) => {
+    return (current * 100) / source;
+};