zhejiushizhuce il y a 2 ans
Parent
commit
e43bf85544

+ 3 - 0
src/App.js

@@ -45,6 +45,7 @@ import {getBFP, getFetchStatus, getUserID, getUserInfo} from '@features/mainSlic
 import {useDispatch, useSelector} from "react-redux";
 import {REQ_STATUS} from "@api/config";
 import {
+    reqAgentCheck,
     reqCustomService,
     reqGetRoutes,
     reqMailCheck,
@@ -159,6 +160,8 @@ const App = () => {
         //redpack
         dispatch(reqRedpackCheck());
         dispatch(reqRedpackConfig());
+        //agent
+        dispatch(reqAgentCheck());
     }
     const appInitData=()=>{
         // scroll to top on route change

+ 3 - 1
src/api/config.js

@@ -79,4 +79,6 @@ export const APP_MAIL_TAKE=BASE_PREFIX+"mail/take";
 // /game/redpack/receive
 export const APP_REDPACK_CHECK=BASE_PREFIX+"redpack/check";
 export const APP_REDPACK_RECEIVE=BASE_PREFIX+"redpack/receive";
-export const APP_REDPACK_CONFIG=BASE_PREFIX+"redpack/config";
+export const APP_REDPACK_CONFIG=BASE_PREFIX+"redpack/config";
+//agent
+export const APP_AGENT_CHECK=BASE_PREFIX+"agent/check";

+ 3 - 1
src/app/store.js

@@ -8,6 +8,7 @@ import SocketReducer from '@features/socketSlice';
 import TurnplateReducer from '@features/turnplateSlice';
 import MailReducer from '@features/mailSlice';
 import RedPackReducer from '@features/redpackSlice';
+import AgentReducer from '@features/agentSlice';
 export default configureStore({
     reducer: {
         // todos: TodosReducer,
@@ -18,7 +19,8 @@ export default configureStore({
         socket:SocketReducer,
         turnplate:TurnplateReducer,
         mail:MailReducer,
-        redpack:RedPackReducer
+        redpack:RedPackReducer,
+        agent:AgentReducer,
     },
     middleware:(getDefaultMiddleware => {
         let middlewares=getDefaultMiddleware();

BIN
src/assets/agent/agent_icon.png


BIN
src/assets/agent/doller_icon.png


BIN
src/assets/agent/gold_icon.png


BIN
src/assets/agent/link.png


BIN
src/assets/agent/policy.png


BIN
src/assets/agent/rank_icon.png


BIN
src/assets/agent/user_icon.png


Fichier diff supprimé car celui-ci est trop grand
+ 6 - 0
src/assets/singlesvg/tree_bai.svg


+ 13 - 0
src/db/routes.js

@@ -360,4 +360,17 @@ export const routes=[
         lpath:"#/signin",//登录path
         subs:[]
     },
+    {
+        path: "#/agent",
+        type: 1,
+        side: 0,
+        block:1,//块排序
+        title: "Performance",
+        icon:"",
+        fill:";;",//icon 颜色 默认 选中 本身颜色
+        component:"agent",
+        login:0,//0,1 检不检查登录
+        lpath:"#/signin",//登录path
+        subs:[]
+    },
 ]

+ 68 - 0
src/features/agentSlice.js

@@ -0,0 +1,68 @@
+import {createSlice} from "@reduxjs/toolkit";
+import {REQ_STATUS} from "@api/config";
+import {buildReqReducer, reqAgentCheck} from "@features/api";
+const reducerAgentCheck=(state,action,arg)=>{
+    let payload=action.payload;
+    if (payload&&payload.code===200){
+        let data=payload.data;
+        if (data){
+            if (data.info)state.info=data.info;
+            if (data.subs)state.subs=data.subs;
+            if (data.levels)state.levels=data.levels;
+            if (data.history)state.bonusList=data.history;
+            // state.subs=[
+            //     {
+            //         NickName:"xdh123dfasdfasdfa",
+            //         SubTotal:10000,
+            //         bonus:40
+            //     },
+            //     {
+            //         NickName:"xdh123",
+            //         SubTotal:10000,
+            //         bonus:40
+            //     },
+            //     {
+            //         NickName:"xdh123",
+            //         SubTotal:10000,
+            //         bonus:40
+            //     }
+            // ]
+        }
+    }
+}
+const agentCheckStatus=(state,status,arg)=>{
+    state.status.AgentCheck=status;
+}
+export const AgentSlice = createSlice({
+    name: "agent",
+    initialState: {
+        status:{
+            AgentCheck:REQ_STATUS.NONE,
+        },
+        info:{},
+        subs:[],
+        levels:{},
+        bonusList:[],
+        history:[]
+    },
+    reducers:{
+
+    },
+    extraReducers: (builder) => {
+        buildReqReducer(builder,reqAgentCheck,reducerAgentCheck,agentCheckStatus);
+    }
+})
+export const {}=AgentSlice.actions;
+export const getAgentInfo=(state)=>{
+    return state.agent.info;
+}
+export const getAgentSubs=(state)=>{
+    return state.agent.subs;
+}
+export const getAgentLevels=(state)=>{
+    return state.agent.levels;
+}
+export const getBonusList=(state)=>{
+    return state.agent.bonusList;
+}
+export default AgentSlice.reducer;

+ 11 - 1
src/features/api.js

@@ -1,6 +1,6 @@
 import {createAsyncThunk} from "@reduxjs/toolkit";
 import {
-    APP_ACCOUNTS_PAY_INFO,
+    APP_ACCOUNTS_PAY_INFO, APP_AGENT_CHECK,
     APP_CHANGE_EMAIL,
     APP_CHANGE_INFO,
     APP_CHANGE_PASS,
@@ -607,4 +607,14 @@ export const reqRedpackConfig=createAsyncThunk(
         return response;
     }
 )
+export const reqAgentCheck=createAsyncThunk(
+    APP_AGENT_CHECK,
+    async (arg,thunkAPI)=>{
+        let params={
+            url:APP_AGENT_CHECK,
+        }
+        const response=await Http.get(params);
+        return response;
+    }
+)
 //api

+ 31 - 0
src/locales/languages/en_US.json

@@ -472,5 +472,36 @@
       "des_3": "Today's performance from C\n20,000 Level 12",
       "title_1": "Today's earnings of A = 19,400"
     }
+  },
+  "agent": {
+    "no_data": "No records yet",
+    "base": {
+      "title_link": "Reference Link",
+      "btn_copy": "Copy",
+      "value": "Value",
+      "title_policy": "Agent Policy",
+      "details": "See details"
+    },
+    "today": {
+      "label_level": "Level",
+      "label_team_size": "Team Size",
+      "label_direct_agent": "Direct Agent",
+      "label_revenue": "Today's Revenue",
+      "label_commission": "Today's Commission"
+    },
+    "subs": {
+      "title": "Today's Direct Agent Performance",
+      "label_name": "Agent Name",
+      "label_revenue": "Revenue",
+      "label_commision": "Commission"
+    },
+    "bonus": {
+      "title_bonus": "Commission available",
+      "btn_claim": "Claim",
+      "history": "History",
+      "label_date": "Date",
+      "label_commision": "Commission",
+      "label_claim": "Claim"
+    }
   }
 }

+ 10 - 0
src/pages/Agent.jsx

@@ -0,0 +1,10 @@
+import WAgent from "@widgets/WAgent";
+
+const Agent=({...props})=>{
+    return (
+        <>
+            <WAgent {...props}/>
+        </>
+    )
+}
+export default Agent;

+ 2 - 0
src/pages/index.jsx

@@ -24,6 +24,7 @@ const WithdrawRecord=lazy(()=>import("@pages/WithdrawRecord"));
 const Security=lazy(()=>import("@pages/Security"));
 const MoneyRain=lazy(()=>import("@pages/MoneyRain"));
 const AgentPolicy=lazy(()=>import("@pages/AgentPolicy"));
+const Agent=lazy(()=>import("@pages/Agent"));
 export default {
     ModulePage:ModulePage,
     Home:Home,
@@ -47,6 +48,7 @@ export default {
     security:Security,
     moneyrain:MoneyRain,
     agentPolicy:AgentPolicy,
+    agent:Agent,
 }
 export const Header={
     deposit: DepositHeader,

+ 277 - 0
src/widgets/WAgent/index.jsx

@@ -0,0 +1,277 @@
+import styles from './styles.module.scss';
+import Spring from "@components/Spring";
+import {useSelector} from "react-redux";
+import {getAgentInfo, getAgentSubs} from "@features/agentSlice";
+import link_icon from "@assets/agent/link.png";
+import doller_icon from "@assets/agent/doller_icon.png";
+import policy_icon from "@assets/agent/policy.png";
+import rank_icon from "@assets/agent/rank_icon.png";
+import user_icon from "@assets/agent/user_icon.png";
+import agent_icon from "@assets/agent/agent_icon.png";
+import gold_icon from "@assets/agent/gold_icon.png";
+import tree_icon from "@assets/singlesvg/tree_bai.svg";
+import no_data from "@assets/mail/no_data.png";
+import SvgIcon from "@components/SvgIcon";
+import {CopyToClipboard} from "react-copy-to-clipboard";
+import {toast} from "react-toastify";
+import {formatCash, formatDate} from "@utils/helpers";
+import {useNavigate} from "react-router-dom";
+import {ROUTE_PATH} from "@constants/routes";
+const i18n=global.i18n;
+const WAgent=({close})=>{
+    const navigate = useNavigate();
+    const agentInfo=useSelector(getAgentInfo);
+    const agentSubs=useSelector(getAgentSubs);
+    const lvnum=4;
+    const getTeamUser=()=>{
+        let teamNum=0;
+        for (let i = 0; i < lvnum; i++) {
+            let num=agentInfo["downCount"+(i+1)];
+            if (num!=null)teamNum+=num;
+        }
+        return teamNum;
+    }
+    const renderBase=()=>{
+        let agentUrl="";
+        let bonus=agentInfo.bonus?agentInfo.bonus:0;
+        let bonusStr=formatCash(bonus);
+        return (
+            <div className={styles.base_con}>
+                <div className={styles.base_item_con}>
+                    <div className={styles.title_con}>
+                        <span className={styles.title}>
+                            <div className={styles.base_icon}>
+                                 <img src={link_icon}/>
+                            </div>
+                            {i18n.t("agent.base.title_link")}
+                        </span>
+                    </div>
+                    <div className={styles.item_con}>
+                        <CopyToClipboard text={agentUrl} onCopy={() => {
+                            toast.success(i18n.t("copy_success"));
+                        }}>
+                            <div className={styles.item}>
+                                <span className={styles.text_white}>{agentUrl}</span>
+                                <SvgIcon className={styles.icon} herf={"icon_Copy"}></SvgIcon>
+                            </div>
+                        </CopyToClipboard>
+                    </div>
+                </div>
+                {/*<div className={styles.base_item_con}>*/}
+                {/*    <div className={styles.title_con}>*/}
+                {/*        <span className={styles.title}>*/}
+                {/*            <div className={styles.base_icon}>*/}
+                {/*                 <img src={doller_icon}/>*/}
+                {/*            </div>*/}
+                {/*            {i18n.t("agent.base.title_bonus")}*/}
+                {/*        </span>*/}
+                {/*        <button className={`${styles.title} ${styles.text_white}`}>*/}
+                {/*            {i18n.t("agent.base.history")}*/}
+                {/*            <SvgIcon className={styles.arrow} herf={"icon_Arrow"}></SvgIcon>*/}
+                {/*        </button>*/}
+                {/*    </div>*/}
+                {/*    <div className={styles.item_con}>*/}
+                {/*       <div className={styles.item}>*/}
+                {/*            <div className={styles.item_value}>*/}
+                {/*                <span className={styles.label}>{i18n.t("agent.base.value")}</span>*/}
+                {/*                <span className={styles.text_line}></span>*/}
+                {/*                <span className={styles.text_white}>{bonusStr}</span>*/}
+                {/*            </div>*/}
+                {/*       </div>*/}
+                {/*        <button className={`button-green ${styles.base_button}`} disabled={bonus<=0}>*/}
+                {/*            {i18n.t("agent.base.btn_claim")}*/}
+                {/*        </button>*/}
+                {/*    </div>*/}
+                {/*</div>*/}
+                <div className={styles.base_item_con}>
+                    <div className={styles.title_con}>
+                        <div className={`${styles.title} ${styles.itme_policy}`}>
+                            <img src={policy_icon}/>
+                            {i18n.t("agent.base.title_policy")}
+                        </div>
+                        <button className={`${styles.title} ${styles.text_white}`} onClick={()=>{
+                            navigate(ROUTE_PATH.AGENT_POLICY);
+                        }}>
+                            {i18n.t("agent.base.details")}
+                            <SvgIcon className={styles.arrow} herf={"icon_Arrow"}></SvgIcon>
+                        </button>
+                    </div>
+                    <div className={styles.item_line}></div>
+                </div>
+            </div>
+        )
+    }
+    const renderTodayInfo=()=>{
+        let date=formatDate(Date.now(),"yyyy-MM-dd");
+        let level=agentInfo.level?agentInfo.level:0;
+        let totalUser=getTeamUser();
+        let directUser=0;
+        let revenue=0;
+        let bonus=0;
+        if (agentInfo["downCount"+(1)])directUser=agentInfo["downCount"+(1)];
+        if (agentInfo.SubTotal!=null)revenue=formatCash(agentInfo.SubTotal,2,true);
+        if (agentInfo.bonus!=null)bonus=formatCash(agentInfo.bonus,2,true);
+        return (
+            <div className={"d-flex flex-column g-1"}>
+                <div className={`${styles.info_item} ${styles.info_item_top}`}>
+                    <div className={styles.title_con}>
+                        <div className={`${styles.title} ${styles.text_white}`}>
+                            <div className={styles.base_icon}>
+                                <img src={rank_icon}/>
+                            </div>
+                            {date}
+                        </div>
+                        <div className={styles.title}>
+                            <div className={styles.text_line}></div>
+                            <span>{i18n.t("agent.today.label_level")}</span>
+                            <span className={styles.text_white_big}>{level}</span>
+                        </div>
+                    </div>
+                </div>
+                <div className={`${styles.info_item} ${styles.info_item_middle}`}>
+                    <div className={styles.title_con}>
+                        <div className={styles.title}>
+                            <div className={styles.base_icon}>
+                                <img src={user_icon}/>
+                            </div>
+                            {i18n.t("agent.today.label_team_size")}
+                        </div>
+                        <span className={styles.text_white_big}>{totalUser}</span>
+                    </div>
+                </div>
+                <div className={`${styles.info_item} ${styles.info_item_middle}`}>
+                    <div className={styles.title_con}>
+                        <div className={styles.title}>
+                            <div className={styles.base_icon}>
+                                <img src={agent_icon}/>
+                            </div>
+                            {i18n.t("agent.today.label_direct_agent")}
+                        </div>
+                        <span className={styles.text_white_big}>{directUser}</span>
+                    </div>
+                </div>
+                <div className={`${styles.info_item} ${styles.info_item_middle}`}>
+                    <div className={styles.title_con}>
+                        <div className={styles.title}>
+                            <div className={styles.base_icon}>
+                                <img src={gold_icon}/>
+                            </div>
+                            {i18n.t("agent.today.label_revenue")}
+                        </div>
+                        <span className={styles.text_white_big}>{global.DOLLAR+revenue}</span>
+                    </div>
+                </div>
+                <div className={`${styles.info_item} ${styles.info_item_bottom}`}>
+                    <div className={styles.title_con}>
+                        <div className={styles.title}>
+                            <div className={styles.base_icon}>
+                                <img src={gold_icon}/>
+                            </div>
+                            {i18n.t("agent.today.label_commission")}
+                        </div>
+                        <span className={styles.text_white_big}>{global.DOLLAR+bonus}</span>
+                    </div>
+                </div>
+            </div>
+        )
+    }
+    const renderEmpty=(isImg=true)=>{
+        return (
+            <div className={`${styles.data_empty} ${!isImg?styles.data_empty_text:''}`}>
+                {
+                    isImg ? <img src={no_data}/>:(<></>)
+                }
+                <span>{i18n.t("agent.no_data")}</span>
+            </div>
+        )
+    }
+    const renderSubsList=()=>{
+        let len=agentSubs.length;
+        if (len<=0)return renderEmpty();
+        return (
+            <>
+                {
+                    agentSubs.map((item,index)=>{
+                        let name=item.NickName;
+                        let SubTotal=item.SubTotal;
+                        let bonus=item.bonus;
+                        return (
+                            <div key={index} className={`${styles.info_item_title} ${styles.info_item_middle}`}>
+                                <span className={styles.sub_data_item}>{name}</span>
+                                <span className={styles.sub_data_item}>{global.DOLLAR+formatCash(SubTotal, 2, true)}</span>
+                                <span className={styles.sub_data_item}>{global.DOLLAR+formatCash(bonus, 2, true)}</span>
+                            </div>
+                        )
+                    })
+                }
+            </>
+        )
+    }
+    const renderSubs=()=>{
+        return (
+            <div className={"d-flex flex-column g-1"}>
+                <div className={`${styles.info_item} ${styles.info_item_top}`}>
+                    <div className={styles.title_con}>
+                        <div className={`${styles.title} ${styles.text_white}`}>
+                            <div className={styles.base_icon}>
+                                <img src={tree_icon}/>
+                            </div>
+                            {i18n.t("agent.subs.title")}
+                        </div>
+                    </div>
+                </div>
+                <div className={`${styles.info_item_title} ${styles.info_item_title_middle} ${styles.text_white}`}>
+                    <span>{i18n.t("agent.subs.label_name")}</span>
+                    <div className={styles.text_line}></div>
+                    <span>{i18n.t("agent.subs.label_revenue")}</span>
+                    <div className={styles.text_line}></div>
+                    <span>{i18n.t("agent.subs.label_commision")}</span>
+                </div>
+                {renderSubsList()}
+            </div>
+        )
+    }
+    const renderAvailabelList=()=>{
+        return renderEmpty(false)
+    }
+    const renderAvailable = () => {
+        return (
+            <div className={"d-flex flex-column g-1"}>
+                <div className={`${styles.info_item} ${styles.info_item_top}`}>
+                    <div className={styles.title_con}>
+                        <div className={`${styles.title} ${styles.text_white}`}>
+                            <div className={styles.base_icon}>
+                                <img src={doller_icon}/>
+                            </div>
+                            {i18n.t("agent.bonus.title_bonus")}
+                        </div>
+                        <button className={`${styles.title} ${styles.text_white}`}>
+                            <div className={styles.text_line}></div>
+                            <span>{i18n.t("agent.bonus.history")}</span>
+                            <SvgIcon className={styles.arrow} herf={"icon_Arrow"}></SvgIcon>
+                        </button>
+                    </div>
+                </div>
+                <div className={`${styles.info_item_title} ${styles.info_item_title_middle} ${styles.text_white}`}>
+                    <span>{i18n.t("agent.bonus.label_date")}</span>
+                    <div className={styles.text_line}></div>
+                    <span>{i18n.t("agent.bonus.label_commision")}</span>
+                    <div className={styles.text_line}></div>
+                    <span>{i18n.t("agent.bonus.label_claim")}</span>
+                </div>
+                {renderAvailabelList()}
+            </div>
+        )
+    }
+    return (
+        <div className={styles.container}>
+            <Spring type="slideUp" className={styles.content}>
+                {renderBase()}
+                {renderAvailable()}
+                {renderTodayInfo()}
+                {renderSubs()}
+            </Spring>
+        </div>
+    )
+}
+export default WAgent;

+ 172 - 0
src/widgets/WAgent/styles.module.scss

@@ -0,0 +1,172 @@
+.container{
+  width: 100%;
+  min-height: 100%;
+  background-color: var(--widget-bg);
+}
+.content{
+  display: flex;
+  flex-direction: column;
+  padding: 1rem;
+  height: 100%;
+  gap: 2rem;
+  font-size: 1rem;
+  color: var(--text);
+}
+.base_button{
+  width: 8rem;
+  &:disabled{
+    opacity: 0.5;
+  }
+}
+.base_icon{
+  width: 1.4rem;
+  height: auto;
+  overflow: hidden;
+  img{
+    width: 1.4rem;
+    height: auto;
+    filter: drop-shadow(-1.6rem 0 var(--text));
+    transform: translateX(1.6rem);
+  }
+}
+.text_white{
+  color: var(--header);
+}
+.text_white_big{
+  font-size: 1.4rem;
+  font-weight: 500;
+  color: var(--header);
+}
+.icon{
+  width: 1.4rem;
+  height: 1.4rem;
+  fill: var(--text);
+}
+.arrow{
+  width: 1.2rem;
+  height: 1.2rem;
+  fill: var(--header);
+}
+.title_con{
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+  & .title{
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    gap: 0.5rem;
+  }
+}
+.text_line{
+  width: 1px;
+  height: 1.8rem;
+  background-color: var(--card-line);
+}
+.base_con{
+  display: flex;
+  flex-direction: column;
+  gap: 1.5rem;
+  & .base_item_con{
+    display: flex;
+    flex-direction: column;
+    gap: 0.7rem;
+    & .item_con{
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: space-between;
+      gap: 0.6rem;
+      width: 100%;
+      & .item{
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        justify-content: space-between;
+        position: relative;
+        width: 100%;
+        min-height: 3rem;
+        background-color: var(--card-bg);
+        padding: 0.5rem 1rem;
+        border-radius: var(--border-radius);
+        gap: 0.5rem;
+        span{
+          overflow-x: auto;
+        }
+      }
+    }
+    & .item_value{
+      display: flex;
+      align-items: center;
+      gap: 0.8rem;
+    }
+    & .itme_policy{
+      color: #F9C486;
+      img{
+        width: 1.4rem;
+        height: auto;
+      }
+    }
+    & .item_line{
+      margin-top: 0.5rem;
+      width: 100%;
+      height: 1px;
+      background-color: var(--card-line);
+    }
+  }
+}
+.info_item{
+  display: flex;
+  align-items: center;
+  width: 100%;
+  padding: 0.5rem 1rem;
+  height: 3rem;
+}
+.info_item_top{
+  background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0.04) 100%);
+  border-radius: 0.3rem 0.3rem 0 0;
+}
+.info_item_middle{
+  background: rgba(255, 255, 255, 0.04);
+}
+.info_item_bottom{
+  background: rgba(255, 255, 255, 0.04);
+  border-radius: 0 0 0.3rem 0.3rem;
+}
+.info_item_title{
+  display: flex;
+  align-items: center;
+  width: 100%;
+  justify-content: space-around;
+  padding:0.5rem;
+  height: 3rem;
+}
+.info_item_title_middle{
+  background: rgba(255, 255, 255, 0.08);
+}
+.sub_data_item{
+  color: var(--header);
+  width: 30%;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  text-align: center;
+}
+.data_empty{
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  margin-top: 3rem;
+  width: 100%;
+  gap: 2rem;
+  img{
+    width: 30%;
+    height: auto;
+    opacity: 0.6;
+  }
+  &_text{
+    margin-top: 1rem;
+  }
+}

+ 1 - 1
src/widgets/WPromotion/index.jsx

@@ -50,7 +50,7 @@ const WPromotion=({close})=>{
             title:"Agent",
             icon:"",
             banner:"",
-            link:"#/agentPolicy",
+            link:"#/agent",
         }
     ]
     useEffect(()=>{

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff