瀏覽代碼

Merge branch 'dev' of http://192.168.0.111:3000/bcwin/site_front into dev

XianCH 1 年之前
父節點
當前提交
e354307184

+ 2 - 1
package.json

@@ -22,7 +22,8 @@
     "react-dom": "^18.3.1",
     "sass": "^1.77.8",
     "swiper": "^11.1.5",
-    "tailwind-merge": "^2.4.0"
+    "tailwind-merge": "^2.4.0",
+    "zustand": "^4.5.4"
   },
   "devDependencies": {
     "@types/node": "^20.14.10",

文件差異過大導致無法顯示
+ 2839 - 102
pnpm-lock.yaml


二進制
public/img/a.png


二進制
public/img/logo.webp


+ 19 - 0
public/svg/gg.svg

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="26px" height="27px" viewBox="0 0 26 27" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <g id="" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="" transform="translate(-199.000000, -208.000000)">
+            <g id="" transform="translate(199.000000, 208.500000)">
+                <circle id="" fill="#FFFFFF" cx="13" cy="13" r="13"></circle>
+                <g id="google-2" transform="translate(4.500000, 5.000000)" fill-rule="nonzero">
+                    <g id="google">
+                        <path d="M3.55743847,8.5 C3.55743847,7.94796727 3.65166543,7.41839257 3.81837464,6.92214267 L0.891540636,4.73429643 C0.303491494,5.90245673 -0.0018826868,7.1923137 0,8.5 C0,9.85327708 0.320380366,11.1297622 0.890090996,12.2628058 L3.81547536,10.0713373 C3.64490091,9.56497892 3.55775373,9.03428886 3.55743847,8.5" id="路径" fill="#FBBC05"></path>
+                        <path d="M8.69788096,3.47737152 C9.9228313,3.47737152 11.0296355,3.90190063 11.8994228,4.59737493 L14.4297788,2.12481888 C12.8880809,0.811386693 10.9114894,0 8.69788096,0 C5.26077179,0 2.30639451,1.92342112 0.891540636,4.73429643 L3.8198243,6.92214267 C4.49390939,4.91830734 6.41613916,3.47737152 8.69788096,3.47737152" id="路径" fill="#EA4335"></path>
+                        <path d="M8.69788096,13.5226285 C6.41541433,13.5226285 4.49318457,12.0816927 3.81837464,10.0778573 L0.891540636,12.2657036 C2.3056697,15.0765789 5.26004696,17 8.69788096,17 C10.8187121,17 12.8438667,16.2632319 14.3645447,14.8817012 L11.5855745,12.7793403 C10.8020412,13.2625501 9.81483271,13.5226285 8.69715615,13.5226285" id="路径" fill="#34A853"></path>
+                        <path d="M17,8.5 C17,7.99795449 16.9202695,7.45678855 16.8021234,6.95474303 L8.69715615,6.95474303 L8.69715615,10.2386858 L13.3621149,10.2386858 C13.1294469,11.3586892 12.4945022,12.2193386 11.5862994,12.7793403 L14.3645447,14.8817012 C15.9613291,13.4313475 17,11.2710304 17,8.5" id="路径" fill="#4285F4"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 3 - 2
src/api/user.ts

@@ -17,9 +17,10 @@ export const getCheckUserPhoneExistApi = (params: any) => {
 };
 
 // 找回密码
-export const getFindPwdApi = () => {
+export const getFindPwdApi = (data: any) => {
     return server.post<any>({
-        url: "/v1/api/user/find_pwd"
+        url: "/v1/api/user/find_pwd",
+        data
     });
 };
 

+ 39 - 0
src/app/[locale]/(ordinary)/profile/component/ItemCom/index.tsx

@@ -0,0 +1,39 @@
+"use client";
+import { ChangeEvent, FC, PropsWithChildren, useMemo, useState } from "react";
+import clsx from "clsx";
+import Link from "next/link";
+import ButtonOwn from "@/components/ButtonOwn";
+import "./style.scss";
+
+/**
+ * @description 列表组件
+ * @param {string} type 使用类型
+ * @param {(params: any) => void} callbackFun 回调方法
+ */
+export interface ItemComProps {
+    type?: string;
+    callbackFun?: (params: any) => void;
+}
+
+const ItemCom: FC<PropsWithChildren<ItemComProps>> = ({type = 'login', callbackFun}) => {
+
+    let amountList = [10,20,50,100,200,500,1000,5000,10000,500,1000,5000,10000]
+
+    return (
+        <ul className="itemCom-box">
+            {
+                amountList.map((item, index) => (
+                    <li className={index==0?'free':''} key={index}>
+                        <div className="content"> Afiliado - Ganhe R$ 10.000 por dia | 9F.COM 
+                            <span data-v-5c42ece6="" className="iconfont icon-hot"></span>
+                            <div data-v-5c42ece6=""></div>
+                        </div>
+                        <div><span className="iconfont icon-xiangyou1"></span></div>
+                    </li>
+                ))
+            }
+        </ul>
+    );
+};
+
+export default ItemCom;

+ 62 - 0
src/app/[locale]/(ordinary)/profile/component/ItemCom/style.scss

@@ -0,0 +1,62 @@
+.itemCom-box {
+  width: 100%;
+  height: auto;
+
+  li {
+    color: #fff;
+    height: .5rem;
+    line-height: .5rem;
+    font-size: .12rem;
+    border-bottom: .01rem solid #3f3f3f;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    margin: 0 .18rem;
+    -webkit-box-pack: justify;
+    -ms-flex-pack: justify;
+    justify-content: space-between;
+    line-height: .2rem;
+
+    &.free {
+      padding-top: .12rem;
+      margin: 0;
+      padding: 0 .18rem;
+      border-bottom: .08rem solid #131212;
+    }
+
+    & > div {
+      display: -webkit-box;
+      display: -ms-flexbox;
+      display: flex;
+      -webkit-box-align: center;
+      -ms-flex-align: center;
+      align-items: center;
+    }
+
+    .icon-hot {
+      font-size: .14rem;
+      color: #fc9b26;
+      margin-left: .1rem;
+    }
+
+    div {
+      &.content {
+        .iconfont {
+          margin-right: .04rem;
+          margin-left: .1rem;
+          font-size: .14rem;
+        }
+      }
+    }
+
+    .iconfont {
+      
+      &.icon-to {
+        -webkit-transform: rotate(180deg);
+        -ms-transform: rotate(180deg);
+        transform: rotate(180deg);
+      }
+    }
+  }
+}
+  

+ 23 - 55
src/app/[locale]/(ordinary)/profile/page.scss

@@ -1,5 +1,5 @@
-.main {
-    padding: .44rem 0 .04rem;
+.profile-box {
+    padding: .44rem 0 .6rem;
     min-height: 100vh;
     background-color: #1f1f1f;
     -webkit-box-sizing: border-box;
@@ -36,14 +36,20 @@
         height: .36rem;
         font-size: .14rem;
         color: #000;
+
         .bgImg {
           width: .36rem;
           height: .36rem;
           margin-right: .1rem;
           background-color: transparent;
-          background-image: url('https://9f.com/img/logo_5.6a41c34a.png');
+          background: url('/img/logo.webp') no-repeat center;
           background-size: 100% 100%;
+
+          &.default {
+            background-size: 80% 80%;
+          }
         }
+        
         & > div {
           display: -webkit-box;
           display: -ms-flexbox;
@@ -101,6 +107,11 @@
         .iconfont {
           margin: 0 .08rem;
           font-size: .18rem;
+          color: #000;
+
+          &.icon-gift2 {
+            width: .32rem;
+          }
         }
 
         & > div {
@@ -112,6 +123,14 @@
         div {
           span {
             font-size: .12rem;
+            color: #333;
+            display: flex;
+            align-items: center;
+
+            .a {
+              width: .14rem;
+              margin-left: .03rem;
+            }
           }
           .num {
             width: 100%;
@@ -147,58 +166,7 @@
         text-align: center;
       }
     }
-    ul {
-      li {
-        color: #fff;
-        height: .5rem;
-        line-height: .5rem;
-        font-size: .14rem;
-        border-bottom: .01rem solid #3f3f3f;
-        display: -webkit-box;
-        display: -ms-flexbox;
-        display: flex;
-        margin: 0 .18rem;
-        -webkit-box-pack: justify;
-        -ms-flex-pack: justify;
-        justify-content: space-between;
-        line-height: .2rem;
-        &.free {
-          padding-top: .12rem;
-          margin: 0;
-          padding: 0 .18rem;
-          border-bottom: .08rem solid #131212;
-        }
-        & > div {
-          display: -webkit-box;
-          display: -ms-flexbox;
-          display: flex;
-          -webkit-box-align: center;
-          -ms-flex-align: center;
-          align-items: center;
-        }
-        .icon-hot {
-          font-size: .16rem;
-          color: #fc9b26;
-          margin-left: .1rem;
-        }
-        div {
-          &.content {
-            .iconfont {
-              margin-right: .04rem;
-              margin-left: .1rem;
-              font-size: .16rem;
-            }
-          }
-        }
-        .iconfont {
-          &.icon-to {
-            -webkit-transform: rotate(180deg);
-            -ms-transform: rotate(180deg);
-            transform: rotate(180deg);
-          }
-        }
-      }
-    }
+
     .logOut {
       color: #fff;
       font-size: .12rem;

+ 57 - 48
src/app/[locale]/(ordinary)/profile/page.tsx

@@ -1,83 +1,92 @@
 "use client";
 import { FC, PropsWithChildren } from "react";
 import { useRouter } from "@/i18n";
-// import ButtonOwn from "@/components/ButtonOwn";
+import clsx from "clsx";
+import ItemCom from "./component/ItemCom";
 import './page.scss'
+import { useGlobalStore } from '@/stores';
+import {getLogoutApi} from "@/api/user";
 
 interface Props {}
 
-const Profile: FC<PropsWithChildren<Props>> = (props) => {
-    // let [amount, setAmount] = React.useState(0)
-    let amount = 50
-    let amountList = [10,20,50,100,200,500,1000,5000,10000,500,1000,5000,10000]
+const Profile: FC<PropsWithChildren<Props>> = () => {
+    const { token, setToken, userInfo, setUserInfo } = useGlobalStore();
+
+    const logoutRequest = async () => {
+        let res = await getLogoutApi()
+        if(res.code == 200) {
+            setUserInfo('')
+            setToken('')
+            router.replace('/login')
+        }
+    }
 
     const router = useRouter();
     const goPage = (path = '/') => {
         router.push(path)
     }
 
+    const divClassName = clsx('bgImg', token && 'default');
     return (
-        <div className="main">
+        <div className="profile-box">
             <div className="userContent">
                 <div className="userInfo">
                     <div>
-                        <div className="bgImg"></div>
-                        <div>
-                            <span>Conta</span>
-                            <span className="phone">5516982013895</span>
-                        </div>
+                        <div className={divClassName}></div>
+                        {
+                            token && (
+                                <div>
+                                    <span>{userInfo?.user_name || '昵称'}</span>
+                                    <span className="phone">{userInfo?.user_phone || ''}</span>
+                                </div>
+                            )
+                        }
                     </div>
                     <div className="goto" onClick={() => goPage('/login')}>
-                        <span>Login</span>
+                        { !token && <span>Login</span> }
                         <span className="iconfont icon-xiangzuo1"></span>
                     </div>
                 </div>
-                <div className="coin">
-                    <div>
-                        <span className="iconfont icon-wallet"></span>
-                        <div>
-                            <span> Saldo </span>
-                            <div className="num">
-                                <span className="uppercase">brl </span>
-                                <span>0.00</span>
+                { 
+                    token && (
+                        <div className="coin">
+                            <div>
+                                <span className="iconfont icon-icon-wallet"></span>
+                                <div>
+                                    <span> Saldo </span>
+                                    <div className="num">
+                                        <span className="uppercase">brl </span>
+                                        <span>0.00</span>
+                                    </div>
+                                </div>
                             </div>
-                        </div>
-                    </div>
-                    <div>
-                        <span className="iconfont icon-gift2"></span>
-                        <div>
-                            <span> Bônus </span>
-                            <div className="num">
-                                <span className="uppercase">brl </span>
-                                <span>0.00</span>
+                            <div>
+                                <span className="iconfont icon-gift2"></span>
+                                <div>
+                                    <span> Bônus <img className="a" src="/img/a.png" alt="" /></span>
+                                    <div className="num">
+                                        <span className="uppercase">brl </span>
+                                        <span>0.00</span>
+                                    </div>
+                                </div>
                             </div>
                         </div>
-                    </div>
-                </div>
+                    ) 
+                }
             </div>
 
             <div className="link">
                 <span  onClick={() => goPage('/deposit')}>Depósito</span>
-                <span  onClick={() => goPage('/withdraw')}>Sacar</span>
-                {/* <ButtonOwn active={true}>Depósito</ButtonOwn>
-                <ButtonOwn active={true}>Sacar</ButtonOwn> */}
+                <span  onClick={() => goPage(token ? '/withdraw' : `/login?redirect=withdraw`)}>Sacar</span>
             </div>
 
-            <ul>
-                {
-                    amountList.map((item, index) => (
-                        <li className={index==0?'free':''} key={index}>
-                            <div className="content"> Afiliado - Ganhe R$ 10.000 por dia | 9F.COM 
-                                <span data-v-5c42ece6="" className="iconfont icon-hot"></span>
-                                <div data-v-5c42ece6=""></div>
-                            </div>
-                            <div><span className="iconfont icon-xiangyou1"></span></div>
-                        </li>
-                    ))
-                }
-            </ul>
+            <ItemCom />
 
-            <span className="logOut" onClick={() => goPage('/login')}>Login</span>
+            {
+                token ? <span className="logOut" onClick={logoutRequest}>Sair</span> : (
+                    <span className="logOut" onClick={() => goPage('/login')}>Login</span>
+                )
+            }
         </div>
     );
 };

+ 83 - 0
src/app/[locale]/confirmPassword/page.scss

@@ -0,0 +1,83 @@
+.confirmPassword-box {
+    width: 100%;
+    min-height: 100vh;
+    background-color: rgb(31, 31, 31);
+    display: flex;
+    flex-direction: column;
+  
+  .main {
+    background-color: #1f1f1f;
+    padding: .72rem .18rem 0;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    .title {
+      font-size: .18rem;
+      h2 {
+        color: #fcde26;
+        line-height: .22rem;
+      }
+      div {
+        color: #fff;
+        font-size: .12rem;
+        margin: .06rem 0;
+        line-height: .2rem;
+      }
+    }
+    .phoneInput {
+      width: 100%;
+      height: auto;
+      background-color: #494949;
+      border-radius: 4px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      overflow: hidden;
+      margin-top: 0.2rem;
+      position: relative;
+
+      .after {
+          color: #fcde26;
+          font-size: .14rem;
+          border: .01rem solid #fcde26;
+          position: absolute;
+          height: .26rem;
+          line-height: .26rem;
+          padding: 0 .08rem;
+          text-align: center;
+          right: .1rem;
+          top: .11rem;
+          border-radius: .13rem;
+      }
+
+      input {
+        padding-left: .14rem;
+        -webkit-box-sizing: border-box;
+        box-sizing: border-box;
+      }
+      
+    }
+    
+    input {
+      flex: 1;
+      background-color: #494949;
+      height: .48rem;
+      color: #868686;
+      font-size: .14rem;
+      outline: none;
+      &::placeholder {
+        color: #868686;
+      }
+    }
+
+    .tips {
+      width: 100%;
+      color: #e53535;
+      font-size: 0.12rem;
+      margin-top: .02rem;
+    }
+
+    .btnContent {
+      margin: .29rem 0 .19rem;
+    }
+  }
+}

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

@@ -0,0 +1,88 @@
+"use client";
+import { FC, PropsWithChildren, useEffect, useMemo, useState } from "react";
+import HeaderBack from "@/components/HeaderBack";
+import ButtonOwn from "@/components/ButtonOwn";
+import DomainFooter from "@/components/DomainFooter";
+import './page.scss'
+import React from "react";
+import {getFindPwdApi} from "@/api/user";
+import { useSearchParams } from "next/navigation";
+import { useRouter } from "@/i18n";
+
+interface Props {}
+
+const ResetPhone: FC<PropsWithChildren<Props>> = () => {
+    const router:any = useRouter()
+
+    let searchParams = useSearchParams();
+    let user_phone = searchParams.get('userPhone')
+    let code = searchParams.get('code')
+
+    let [fromParam, setFromParam] = useState({
+        pwd: '',
+        againPwd: ''
+    })
+
+    const setInputVal = (e: { target: { name: any; value: any; }; }) => {
+        const {name, value} = e.target;
+        setFromParam({
+            ...fromParam,
+            [name]: value
+        })
+    }
+
+    const verifyPwd = (e: any) => {
+        let pwd = e.target.value || '';
+        pwd.replaceAll(/[^a-zA-Z0-9_-]/g, '')
+        setFromParam({ ...fromParam, pwd })
+    }
+
+    const activeCls = useMemo(() => {
+        let { pwd, againPwd } = fromParam
+        if (pwd && againPwd && pwd.length==againPwd.length) {
+            return true
+        }
+        return false
+    }, [fromParam]);
+
+    let [msgError, setMsgError] = useState('')
+    const findPwdRequest = () => {
+        let { pwd, againPwd } = fromParam
+        if (pwd && againPwd && pwd!=againPwd) {
+            setMsgError('两次输入的密码不相同')
+            return true
+        }
+        getFindPwdApi({user_phone, code, pwd}).then((res) => {
+            setMsgError(res.msg || '')
+            if(res.code == 200) {
+                alert('修改成功')
+                router.replace('/login')
+            }
+        })
+    }
+
+    return (
+        <div className="confirmPassword-box">
+            <HeaderBack />
+            <div className="main">
+                <div className="title">
+                    <h2>Ativa a sua conta por entrar a Senha de Verificação!</h2>
+                    <div>A senha de verificação foi enviado para o teu telemóvel 16982013895</div>
+                </div>
+                <div className="phoneInput">
+                    <input name="pwd" type="password" value={fromParam.pwd} onChange={setInputVal} onInput={verifyPwd} placeholder="Senha" maxLength={12}/>
+                </div>
+                <div className="phoneInput">
+                    <input name="againPwd" type="password" value={fromParam.againPwd} onChange={setInputVal} placeholder="Senha" maxLength={12}/>
+                </div>
+                { msgError && <div className="tips"> {msgError} </div> }
+                <div className="btnContent">
+                    <ButtonOwn active={activeCls} callbackFun={findPwdRequest}>Completar</ButtonOwn>
+                </div>
+            </div>
+            <DomainFooter />
+        </div>
+    );
+};
+
+export default ResetPhone;

+ 1 - 1
src/app/[locale]/login/component/GoogleCom/style.scss

@@ -46,7 +46,7 @@
           width: .26rem;
           height: .26rem;
           margin-right: .13rem;
-          background-image: url('https://9f.com/img/gg.ef7c3bc6.svg');
+          background-image: url('/svg/gg.svg');
           background-size: 100% 100%;
         }
       }

+ 11 - 4
src/app/[locale]/login/page.tsx

@@ -1,28 +1,35 @@
 "use client";
 import { FC, PropsWithChildren, useState } from "react";
 import { useRouter } from "@/i18n";
+import { useSearchParams } from "next/navigation";
 import HeaderBack from "@/components/HeaderBack";
 import GoogleCom from "./component/GoogleCom";
 import FromCom from "./component/FromCom";
 import DomainFooter from "@/components/DomainFooter";
 import './page.scss'
 import {getLoginApi} from "@/api/user";
+import { useGlobalStore } from '@/stores';
 
 interface Props {}
 
 const Login: FC<PropsWithChildren<Props>> = () => {
+    const { setToken, setUserInfo } = useGlobalStore();
+
     const router:any = useRouter()
+    let searchParams = useSearchParams();
+    let redirect = searchParams.get('redirect') || ''
+
     const [msgError, setMsgError] = useState('')
     const loginRequest = async ({userPhone, pwd}: any) => {
         let params = {user_phone: userPhone, pwd}
         let res = await getLoginApi(params)
         if(res.code == 200) {
             alert('登录成功')
-            window.localStorage.setItem('userInfo',JSON.stringify(res.data))
-            router.replace('/')
-        } else {
-            setMsgError(res.msg)
+            setUserInfo({...res.data, user_phone: userPhone})
+            setToken(res.data.token)
+            router.replace('/' + redirect)
         }
+        setMsgError(res.msg || '')
     }
 
     return (

+ 6 - 6
src/app/[locale]/resetPhone/page.tsx

@@ -23,16 +23,16 @@ const ResetPhone: FC<PropsWithChildren<Props>> = () => {
     })
     const blurVerifyPhone = (e: { target: { value: any; }; }) => {
         const {value} = e.target;
-        if (value && !phoneRegex(value)) {
+        if (!value) {
             setVerifyInfo({
-                msgError: '请输入正确的手机号',
+                msgError: '',
                 check: false
             })
             return
         }
-        if (!value) {
+        if (value && !phoneRegex(value)) {
             setVerifyInfo({
-                msgError: '',
+                msgError: '请输入正确的手机号',
                 check: false
             })
             return
@@ -44,8 +44,8 @@ const ResetPhone: FC<PropsWithChildren<Props>> = () => {
     }
     const checkUserPhoneRequest = async () => {
         if(!phoneRegex(userPhone)) return
-        let { code, msg } = await getCheckUserPhoneExistApi({user_phone: userPhone})
-        if(code == 200) {
+        let { code, msg, data } = await getCheckUserPhoneExistApi({user_phone: userPhone})
+        if(code == 200 && data) {
             router.push(`/verification?userPhone=${userPhone}`)
             return
         }

+ 44 - 8
src/app/[locale]/verification/page.tsx

@@ -1,11 +1,12 @@
 "use client";
-import { FC, PropsWithChildren, useState } from "react";
+import { FC, PropsWithChildren, useEffect, useRef, useState } from "react";
 import HeaderBack from "@/components/HeaderBack";
 import ButtonOwn from "@/components/ButtonOwn";
 import DomainFooter from "@/components/DomainFooter";
 import './page.scss'
 import React from "react";
 import {getSendCodeApi} from "@/api/user";
+import { useSearchParams } from "next/navigation";
 import { useRouter } from "@/i18n";
 
 interface Props {}
@@ -16,17 +17,52 @@ const ResetPhone: FC<PropsWithChildren<Props>> = () => {
     const changeCode = (e: { target: { value: any; }; }) => {
         setCode(e.target.value)
     }
+
+    let searchParams = useSearchParams();
+    let user_phone = searchParams.get('userPhone')
     let [msgError, setMsgError] = useState('')
-    const checkUserPhoneRequest = async () => {
-        getSendCodeApi({user_phone: userPhone}).then((res) => {
+    const sendCodeRequest = () => {
+        if(!user_phone) return
+        getSendCodeApi({user_phone}).then((res) => {
             if(res.code == 200) {
-                alert('验证码发送成功')
-                router.push('/verification')
+                setTime(60);
+    		    setIsNote(true);
                 return
             }
-            setMsgError(res.MSG)
+            setMsgError(res.msg)
         })
     }
+    useEffect(() => {
+        sendCodeRequest()
+        // eslint-disable-next-line react-hooks/exhaustive-deps
+    }, [])
+
+
+    let [isNote, setIsNote] = useState(true);
+    let [time, setTime] = useState(60);
+    let timeRef: any = useRef();
+    useEffect(() => {
+        if (time && time != 0) {
+            timeRef.current = setTimeout(() => {
+                setTime((time) => time - 1);
+            }, 1000);
+        } else {
+            setIsNote(false);
+        }
+        return () => {
+            timeRef.current && clearInterval(timeRef.current);
+        };
+    }, [time]);
+    const sendCodeFun = () => {
+        if(isNote) return
+        sendCodeRequest()
+    }
+
+    const goPage = () => {
+        if(!code || code.length < 6) return
+        router.push(`/confirmPassword?userPhone=${user_phone}&code=${code}`)
+    }
+
     return (
         <div className="verification-box">
             <HeaderBack />
@@ -37,11 +73,11 @@ const ResetPhone: FC<PropsWithChildren<Props>> = () => {
                 </div>
                 <div className="phoneInput">
                     <input type="tel" value={code} onChange={changeCode} placeholder="Reenviar código" maxLength={6} />
-                    <span className="after">Envie de novo</span>
+                    <span className="after" onClick={sendCodeFun}> { isNote ? `${time}s`: 'Envie de novo'} </span>
                 </div>
                 { msgError && <div className="tips"> {msgError} </div> }
                 <div className="btnContent">
-                    <ButtonOwn active={code.length==6} callbackFun={checkUserPhoneRequest}>Completar</ButtonOwn>
+                    <ButtonOwn active={code.length==6} callbackFun={goPage}>Completar</ButtonOwn>
                 </div>
             </div>
             <DomainFooter />

+ 41 - 0
src/stores/index.ts

@@ -0,0 +1,41 @@
+import { create } from 'zustand'
+import { devtools, persist, createJSONStorage } from 'zustand/middleware';
+
+interface State {
+  lang: string;
+  token: string;
+  userInfo: any
+}
+
+interface Action {
+  setLang: (lang: State['lang']) => void;
+  setToken: (lang: State['token']) => void;
+  setUserInfo: (lang: State['userInfo']) => void;
+}
+
+export const useGlobalStore = create<State & Action>()(
+  devtools(persist(
+    (set) => {
+      return {
+        lang: 'zh',
+        token: '',
+        userInfo: '',
+        setLang: (lang: State['lang']) => set({
+          lang,
+        }),
+        setToken: (token: State['token']) => set({
+          token,
+        }),
+        setUserInfo: (userInfo: State['userInfo']) => set({
+          userInfo,
+        }),
+      };
+    },
+    {
+      name: 'globalStore',
+      storage: createJSONStorage(() => localStorage),
+    }
+  ),
+    { name: 'globalStore' }
+  )
+)

+ 7 - 3
src/styles/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 4617618 */
-  src: url('iconfont.woff2?t=1721445755488') format('woff2'),
-       url('iconfont.woff?t=1721445755488') format('woff'),
-       url('iconfont.ttf?t=1721445755488') format('truetype');
+  src: url('iconfont.woff2?t=1721636933902') format('woff2'),
+       url('iconfont.woff?t=1721636933902') format('woff'),
+       url('iconfont.ttf?t=1721636933902') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,10 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-icon-wallet:before {
+  content: "\e796";
+}
+
 .icon-tishi1:before {
   content: "\e61d";
 }

二進制
src/styles/iconfont/iconfont.ttf


二進制
src/styles/iconfont/iconfont.woff


二進制
src/styles/iconfont/iconfont.woff2


+ 1 - 1
src/utils/index.ts

@@ -25,7 +25,7 @@ export const pwdRegex = (pwd = '') => {
 	return regex.test(pwd)
 }
 
-// 密码正则 6到12位(字母,数字,下划线,减号)
+// 手机号正则
 export const phoneRegex = (pwd = '') => {
 	let regex =  /^1[3-9]\d{9}$/;
 	return regex.test(pwd)

+ 7 - 0
src/utils/server/axios.ts

@@ -40,6 +40,13 @@ export default class Request {
             (config: InternalAxiosRequestConfig) => {
                 if (requestInterceptor) {
                     config = requestInterceptor(config);
+
+                    // header请求头添加token
+                    let globalStore = window.localStorage.getItem("globalStore") || '';
+                    if (globalStore) {
+                        let userInfo = JSON.parse(globalStore)
+                        config.headers['token'] = userInfo?.state?.token;
+                    }
                 }
                 return config;
             },

部分文件因文件數量過多而無法顯示