فهرست منبع

feat:路由菜单搭建

lidongsheng 1 سال پیش
والد
کامیت
3649920c23

+ 1 - 1
index.html

@@ -8,7 +8,7 @@
     <meta name="referrer" content="no-referrer" />
     <!-- icon -->
     <link rel="icon" type="" href="./assets/images/logo_icon.png" />
-    <title>广告联盟</title>
+    <title>优量圈</title>
   </head>
   <body>
     <div id="root"></div>

+ 11 - 11
src/components/Nav/index.tsx

@@ -58,9 +58,9 @@ function Nav() {
     })
   }
 
-  function editPassword() {
-    setShowModal(true)
-  }
+  // function editPassword() {
+  //   setShowModal(true)
+  // }
 
   function formSubmit() {
     setShowModal(false)
@@ -82,13 +82,13 @@ function Nav() {
   ]
 
   const items: MenuProps['items'] = [
-    {
-      label: <p onClick={editPassword}>修改密码</p>,
-      key: '3',
-    },
-    {
-      type: 'divider',
-    },
+    // {
+    //   label: <p onClick={editPassword}>修改密码</p>,
+    //   key: '3',
+    // },
+    // {
+    //   type: 'divider',
+    // },
     {
       label: <p onClick={logout}>退出登录</p>,
       key: '4',
@@ -101,7 +101,7 @@ function Nav() {
         <div className={styles['logo-contianer']}>
           <div className={styles['logo-icon']}></div>
           <div className={styles['logo-title']}>
-            票圈 <span>|</span> 广告联盟
+            AD <span>|</span> 优量圈
           </div>
         </div>
         <div className={styles['tabs-contianer']}>

+ 0 - 5
src/pages/Index/index.tsx

@@ -1,5 +0,0 @@
-export default function Index(){
-  return (<>
-        首页
-  </>)
-}

+ 91 - 91
src/pages/Login/index.tsx

@@ -41,11 +41,11 @@ export default function Login() {
       label: '账号登录',
       children: <AccountLogin activeTab={activeTab} onLogin={login} onEditPassword={editPassword}/>
     },
-    {
-      key: '2',
-      label: '短信登录',
-      children: <SMSlogin activeTab={activeTab} onLogin={login} onEditPassword={editPassword} />
-    }
+    // {
+    //   key: '2',
+    //   label: '短信登录',
+    //   children: <SMSlogin activeTab={activeTab} onLogin={login} onEditPassword={editPassword} />
+    // }
   ]
 
   return (
@@ -53,7 +53,7 @@ export default function Login() {
       <div className={styles['logo-banner']}>
         <div className={styles['logo-icon']}></div>
         <div className={styles['logo-title']}>
-          票圈 <span>|</span> 广告联盟
+          AD <span>|</span> 优量圈
         </div>
       </div>
       <div className={styles['login-body']}>
@@ -65,16 +65,16 @@ export default function Login() {
           {loginType === 'register' && <Register backToLogin={backToLogin}/>}
         </div>
       </div>
-      <div className={styles['login-footer']}>
+      {/* <div className={styles['login-footer']}>
         <p>客服电话 0731-85679198、18974809627 | 客服邮箱:piaoquankefu@piaoquantv.com</p>
         <p>ICP备案:湘B2-20180063 | <span onClick={() => window.open('https://beian.miit.gov.cn/')}>湘ICP备16013107-06号</span> | <span onClick={() => window.open('https://beian.mps.gov.cn/#/query/webSearch')}>湘公网安备:43019002001624</span></p>
-      </div>
+      </div> */}
     </div>
   )
 }
 
 // 密码登录
-function AccountLogin({ onLogin, onEditPassword, activeTab }: LoginTypeProps) {
+function AccountLogin({ onLogin, activeTab }: LoginTypeProps) {
   const [form] = Form.useForm()
 
   useEffect(() => {
@@ -122,94 +122,94 @@ function AccountLogin({ onLogin, onEditPassword, activeTab }: LoginTypeProps) {
           <Button type="primary" block onClick={login}>登录</Button>
         </Form.Item>
       </Form>
-      <p className={styles['forget-password']} onClick={onEditPassword}>忘记密码?</p>
+      {/* <p className={styles['forget-password']} onClick={onEditPassword}>忘记密码?</p> */}
     </div>
   )
 }
 
 // 短信登录
-function SMSlogin({ onLogin, onEditPassword, activeTab }: LoginTypeProps) {
-  const [smsText, setSmsText] = useState('获取验证码')
-  const [verificationDisabled, setVerificationDisabled] = useState(false)
-  const [form] = Form.useForm()
-
-  useEffect(() => {
-    form.resetFields()
-  }, [activeTab])
-
-  function login() {
-    form.validateFields().then(res => {
-      const { verificationCode, phone } = res
-      fetchLogin(phone, verificationCode)
-    })
-  }
-
-  const fetchLogin = debounce((phone, verificationCode) => {
-    sso.loginBySendCode(phone, verificationCode).then(res => {
-      res && onLogin()
-    })
-  }, 500)
-
-  function verificationCode() {
-    form.validateFields(['phone']).then(res => {
-      const { phone } = res
-      sso.sendCode(phone).then(res => {
-        res && countdown()
-      })
-    })
-  }
-
-  function countdown() {
-    let count = 59
-    setVerificationDisabled(true)
-    setSmsText(`${count--}`)
-
-    const interval = setInterval(() => {
-      setSmsText(`${count--}`)
-      if (interval && count === 0) {
-        clearInterval(interval)
-        setVerificationDisabled(false)
-        setSmsText('获取验证码')
-      }
-    }, 1000)
-  }
-
-  function validator() {
-    const phone = form.getFieldValue('phone')
-
-    if (!phone)
-      return Promise.resolve()
-
-    const phoneRegx = /^1[3456789]\d{9}$/
-
-    if (phoneRegx.test(phone))
-      return Promise.resolve()
+// function SMSlogin({ onLogin, onEditPassword, activeTab }: LoginTypeProps) {
+//   const [smsText, setSmsText] = useState('获取验证码')
+//   const [verificationDisabled, setVerificationDisabled] = useState(false)
+//   const [form] = Form.useForm()
+
+//   useEffect(() => {
+//     form.resetFields()
+//   }, [activeTab])
+
+//   function login() {
+//     form.validateFields().then(res => {
+//       const { verificationCode, phone } = res
+//       fetchLogin(phone, verificationCode)
+//     })
+//   }
+
+//   const fetchLogin = debounce((phone, verificationCode) => {
+//     sso.loginBySendCode(phone, verificationCode).then(res => {
+//       res && onLogin()
+//     })
+//   }, 500)
+
+//   function verificationCode() {
+//     form.validateFields(['phone']).then(res => {
+//       const { phone } = res
+//       sso.sendCode(phone).then(res => {
+//         res && countdown()
+//       })
+//     })
+//   }
+
+//   function countdown() {
+//     let count = 59
+//     setVerificationDisabled(true)
+//     setSmsText(`${count--}`)
+
+//     const interval = setInterval(() => {
+//       setSmsText(`${count--}`)
+//       if (interval && count === 0) {
+//         clearInterval(interval)
+//         setVerificationDisabled(false)
+//         setSmsText('获取验证码')
+//       }
+//     }, 1000)
+//   }
+
+//   function validator() {
+//     const phone = form.getFieldValue('phone')
+
+//     if (!phone)
+//       return Promise.resolve()
+
+//     const phoneRegx = /^1[3456789]\d{9}$/
+
+//     if (phoneRegx.test(phone))
+//       return Promise.resolve()
     
-    return Promise.reject('请输入合法手机号')
-  }
-
-  return (
-    <div className={styles['sms-login']}>
-      <Form form={form}>
-        <Form.Item name='phone' validateTrigger='onBlur' rules={[{ required: true, message: '请输入手机号' }, { validator }]}>
-          <Input placeholder='请输入手机号' allowClear />
-        </Form.Item>
-        <Form.Item name='verificationCode' rules={[{ required: true, message: '请输入验证码' }]}>
-          <div className={styles['msg-password']}>
-            <Input placeholder='请输入验证码' allowClear />
-            <Button type="primary" onClick={verificationCode} disabled={verificationDisabled}>
-              {smsText}
-            </Button>
-          </div>
-        </Form.Item>
-        <Form.Item name='loginBtn'>
-          <Button type="primary" block onClick={login}>登录</Button>
-        </Form.Item>
-      </Form>
-      <p className={styles['forget-password']} onClick={onEditPassword}>忘记密码?</p>
-    </div>
-  )
-}
+//     return Promise.reject('请输入合法手机号')
+//   }
+
+//   return (
+//     <div className={styles['sms-login']}>
+//       <Form form={form}>
+//         <Form.Item name='phone' validateTrigger='onBlur' rules={[{ required: true, message: '请输入手机号' }, { validator }]}>
+//           <Input placeholder='请输入手机号' allowClear />
+//         </Form.Item>
+//         <Form.Item name='verificationCode' rules={[{ required: true, message: '请输入验证码' }]}>
+//           <div className={styles['msg-password']}>
+//             <Input placeholder='请输入验证码' allowClear />
+//             <Button type="primary" onClick={verificationCode} disabled={verificationDisabled}>
+//               {smsText}
+//             </Button>
+//           </div>
+//         </Form.Item>
+//         <Form.Item name='loginBtn'>
+//           <Button type="primary" block onClick={login}>登录</Button>
+//         </Form.Item>
+//       </Form>
+//       <p className={styles['forget-password']} onClick={onEditPassword}>忘记密码?</p>
+//     </div>
+//   )
+// }
 
 // 忘记密码
 function Register({ backToLogin }: RegisterType) {

+ 7 - 0
src/pages/Manage/components/AdData/index.tsx

@@ -0,0 +1,7 @@
+export function AdData(){
+  return (
+    <>
+        广告数据
+    </>
+  )
+}

+ 7 - 0
src/pages/Manage/components/AdManage/index.tsx

@@ -0,0 +1,7 @@
+export function AdManage(){
+  return (
+    <>
+        广告列表
+    </>
+  )
+}

+ 7 - 0
src/pages/Manage/components/AppManage/index.tsx

@@ -0,0 +1,7 @@
+export function AppManage(){
+  return (
+    <>
+        应用列表
+    </>
+  )
+}

+ 22 - 0
src/pages/Manage/index.module.css

@@ -0,0 +1,22 @@
+.container {
+    height: 100%;
+    position: relative;
+}
+
+.sider {
+    padding-top: 8px;
+
+    :global {
+        .ant-layout-sider-children {
+            overflow: auto;
+        }
+    }
+}
+
+.content {
+    background-color: #fff;
+    margin: 24px;
+    padding: 24px;
+    border-radius: 8px;
+    overflow: auto;
+}

+ 94 - 0
src/pages/Manage/index.tsx

@@ -0,0 +1,94 @@
+import { ReactNode, useState } from 'react'
+import { Outlet, useLocation, useNavigate } from 'react-router-dom'
+import { Layout, Menu } from 'antd'
+import {
+  PieChartOutlined,
+  AppstoreOutlined,
+} from '@ant-design/icons'
+import styles from './index.module.css'
+
+const { Sider, Content } = Layout
+
+export default function Index(){
+  const [collapsed, setCollapsed] = useState(false)
+  const location = useLocation()
+  const navigate = useNavigate()
+  
+  const {pathname} = location
+  const defaultSelectedKeys = [pathname]
+  const defaultOpenKeys = findPath(items, pathname)
+  
+  return (<>
+    <Layout className={styles['container']}>
+      <Sider 
+        className={styles['sider']} 
+        theme='light' 
+        collapsible 
+        collapsed={collapsed} 
+        breakpoint='xl'
+        onCollapse={(v)=>setCollapsed(v)}
+      >
+        <Menu 
+          defaultSelectedKeys={defaultSelectedKeys} 
+          defaultOpenKeys={defaultOpenKeys}
+          mode="inline" 
+          items={items} 
+          onSelect={(v)=>{navigate(v.key)}}
+        />
+      </Sider>
+      <Content className={styles['content']}>
+        <Outlet/>
+      </Content>
+    </Layout>
+  </>)
+}
+
+const items: MenuItem[] = [
+  {
+    label: '广告设置',
+    key: 'manage',
+    icon: <AppstoreOutlined />,
+    children: [
+      {
+        label: '应用列表',
+        key: '/manage/app-manage'
+      },
+      {
+        label: '广告列表',
+        key: '/manage/ad-manage',
+      }
+    ]
+  },
+  {
+    label: '广告数据',
+    key: '/manage/ad-data',
+    icon: <PieChartOutlined />
+  }
+]
+
+interface MenuItem {
+  label: string,
+  key: string,
+  icon?: ReactNode,
+  children?: MenuItem[],
+  types?: string
+}
+
+function findPath(menus:MenuItem[],findKey:string): string[]|undefined {
+  const path: string[] =  []
+
+  function dfs(items:MenuItem[]): boolean {
+    for (let i = 0; i < items.length; i++) {
+      const {key,children} = items[i]
+      path.push(key)
+      if (key===findKey) 
+        return true
+      if (children?.length && dfs(children)) 
+        return true
+      path.pop()
+    }
+    return false
+  }
+  
+  return dfs(menus) ? path : undefined
+}

+ 3 - 3
src/router/router.ts

@@ -3,7 +3,7 @@ import Home from '@src/pages/Home'
 import Login from '@src/pages/Login'
 import ErrorPage from '@src/pages/ErrorPage'
 import sso from '@src/lib/http/sso.ts'
-import Index from './routes/index'
+import Manage from './routes/manage'
 
 export default createBrowserRouter([
   {
@@ -19,12 +19,12 @@ export default createBrowserRouter([
   
       // 默认首页
       if (request.url.endsWith('/'))
-        return redirect('/index')
+        return redirect('/manage/app-manage')
       
       return null
     },
     children: [
-      Index
+      Manage
     ]
   },
   {

+ 0 - 8
src/router/routes/index.tsx

@@ -1,8 +0,0 @@
-import { RouteObject } from 'react-router-dom'
-import Index from '@src/pages/Index'
-
-const routeObject: RouteObject = {
-  path: 'index',
-  Component: Index
-}
-export default routeObject

+ 31 - 0
src/router/routes/manage.tsx

@@ -0,0 +1,31 @@
+import { RouteObject } from 'react-router-dom'
+import Manage from '@src/pages/Manage'
+
+const routeObject: RouteObject = {
+  path: 'manage',
+  Component: Manage,
+  children:[
+    {
+      path: 'app-manage',
+      lazy: async () => {
+        const {AppManage} = await import('@src/pages/Manage/components/AppManage')
+        return {Component:AppManage}
+      }
+    },
+    {
+      path: 'ad-manage',
+      lazy: async () => {
+        const {AdManage} = await import('@src/pages/Manage/components/AdManage')
+        return {Component:AdManage}
+      }
+    },
+    {
+      path: 'ad-data',
+      lazy: async () => {
+        const {AdData} = await import('@src/pages/Manage/components/AdData')
+        return {Component:AdData}
+      }
+    }
+  ]
+}
+export default routeObject

+ 0 - 2
src/store/stateCreater.tsx

@@ -1,6 +1,4 @@
 import React, { useState, createContext, useContext, PropsWithChildren } from 'react'
-// import { reactComponentProps } from ""
-
 
 // 构造器函数,用于创建全局状态管理钩子
 function createGlobalStateHook<T>(initialState?: T) {