Ver código fonte

feat: 标段管理-新增标段成员。doing

lanjianrong 4 anos atrás
pai
commit
79cd383931

+ 8 - 3
src/components/AuditContent/index.tsx

@@ -1,9 +1,11 @@
+import { userStore } from '@/store/mobx'
 import { iAuditHistoryState, iAuditor, iLatestAuditorState } from '@/types/safe'
 import { iAccountGroupItem, iUserInfo } from '@/types/setting'
 import { auditConsts } from '@/utils/common/constStatus'
 import { getUserGroup } from '@/utils/common/user'
 import { formatDate } from '@/utils/util'
 import { Input, Popover } from 'antd'
+import { observer } from 'mobx-react'
 import QueueAnim from 'rc-queue-anim'
 import React, { ChangeEvent, useEffect, useState } from 'react'
 import { ExpandButton, ZhButton } from '../Button'
@@ -71,6 +73,9 @@ const Index: React.FC<iAuditContentProps> = props => {
   const [ searchValue, setSearchValue ] = useState<string>('')
   const [ groups, setGroups ] = useState<Array<iAccountGroupItem>>([])
   useEffect(() => {
+    if (!userStore.groupList.length) {
+      userStore.getGroupList()
+    }
     if (visible.check || visible.reCheck) {
       initGroupList()
     }
@@ -444,7 +449,7 @@ const Index: React.FC<iAuditContentProps> = props => {
                     onVisibleChange={visible => handleVisibleChange('check', visible)}
                     placement="bottomRight">
                     <ZhButton size="small" onClick={() => showPopover('check')}>
-                      添加审批流程
+                      <span>添加审批流程</span><SvgIcon type="xxh-caret-down"></SvgIcon>
                     </ZhButton>
                   </Popover>
                 </div>
@@ -472,7 +477,7 @@ const Index: React.FC<iAuditContentProps> = props => {
                     onVisibleChange={visible => handleVisibleChange('reCheck', visible)}
                     placement="bottomRight">
                     <ZhButton size="small" onClick={() => showPopover('reCheck')}>
-                      添加审批流程
+                      <span>添加审批流程</span><SvgIcon type="xxh-caret-down"></SvgIcon>
                     </ZhButton>
                   </Popover>
                 </div>
@@ -498,4 +503,4 @@ const Index: React.FC<iAuditContentProps> = props => {
   )
 }
 
-export default Index
+export default observer(Index)

src/pages/Management/Tender/api.ts → src/pages/Management/Tender/List/api.ts


src/pages/Management/Tender/components/ModalForm.tsx → src/pages/Management/Tender/List/components/ModalForm.tsx


+ 1 - 1
src/pages/Management/Tender/index.module.scss

@@ -1,5 +1,5 @@
 .tableContent {
-  margin: 0 16px;
+  margin: 16px 16px;
   font-size: 12px;
 
   .treeBtn {

src/pages/Management/Tender/index.scss → src/pages/Management/Tender/List/index.scss


+ 203 - 0
src/pages/Management/Tender/List/index.tsx

@@ -0,0 +1,203 @@
+import Header from '@/components/Header'
+import Slot from '@/components/Header/slot'
+import SvgIcon from '@/components/SvgIcon'
+import { iModalProps, iTenderFormValue, TenderTree } from '@/types/tender'
+import consts from '@/utils/consts'
+import { CaretDownOutlined, FolderAddFilled } from '@ant-design/icons'
+import { Button, Dropdown, Menu, Table, Tooltip } from 'antd'
+import { ColumnsType } from 'antd/lib/table'
+import React, { useEffect, useState } from 'react'
+import { Link } from 'react-router-dom'
+import { apiResfulTree, apiTree } from './api'
+import ModalForm from './components/ModalForm'
+import styles from './index.module.scss'
+import './index.scss'
+const Tender: React.FC<{}> = () =>{
+  const [ tree, setTree ] = useState<TenderTree>({
+    ancounts: 0,
+    attribution: '',
+    bidsectionId: '',
+    childsTotal: 0,
+    createTime: '',
+    csrf: '',
+    depth: 0,
+    children: [],
+    hasFolder: false,
+    id: '',
+    isBid: false,
+    leaf: false,
+    isEnd: false,
+    isfolder: 0,
+    moveId: '',
+    name: '',
+    parentId: '',
+    projectId: '',
+    serial: '',
+    updateTime: '' })
+  const [ modal, setModal ] = useState<iModalProps>({
+    type: 'folder',
+    visible: false,
+    confirmLoading: false,
+    isFolder: false,
+    id: ''
+  })
+  const treeBtnClick = (payload: any) => {
+    setModal({
+      ...modal,
+      visible: true,
+      ...payload
+    })
+  }
+
+  const columns: ColumnsType<TenderTree>  = [
+    {
+      title: '名称',
+      dataIndex: 'name',
+      key: 'name',
+      // eslint-disable-next-line react/display-name
+      render: (text: string, record: TenderTree) => {
+        if (record.isfolder) {
+          return <div style={{ verticalAlign: "baseline" }}><SvgIcon type="xxh-folder-open" style={{ fontSize: 12 }} /><span className="pi-mg-left-2">{text}</span></div>
+        } else {
+          return <div><span style={{ color: '#6c757d', marginRight: '.5rem' }}>{record.isEnd ? '└' : '├'}</span><span>{text}</span></div>
+        }
+      }
+    },
+    {
+      title: '成员',
+      dataIndex: 'member',
+      key: 'member',
+      width: 200,
+      // eslint-disable-next-line react/display-name
+      render: (text:string, record: TenderTree) => {
+        if (!record.isfolder) {
+          return (
+            <div>
+              {record.ancounts ? <span className="pi-mg-right-5">{record.ancounts} 成员</span> : null}
+              <Link className={styles.treeBtn} to={{ pathname: '/console/management/tender/member', state: { id: record.bidsectionId, name: record.name } }}>成员管理</Link>
+            </div>
+          )
+        }
+      }
+    },
+    {
+      title: '操作',
+      dataIndex: 'opreate',
+      key: 'opreate',
+      width: 80,
+      // eslint-disable-next-line react/display-name
+      render: (text:string, record: TenderTree) => {
+        return <Dropdown overlay={() => {
+          return (
+            <Menu>
+              <Menu.Item key="0"><div className="menu-item"  onClick={() => treeBtnClick({ type: 'rename', id: record.id })}><SvgIcon type="xxh-edit" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">重命名</span></div></Menu.Item>
+              <Menu.Item key="1"><div className="menu-item" onClick={() => treeBtnClick({ type: 'move', id: record.id, isFolder: Boolean(record.isfolder) })}><SvgIcon type="xxh-exchange-alt" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">移动</span></div></Menu.Item>
+              {
+                record.children?.length ?
+                  <Menu.Item key="2">
+                    <Tooltip placement="left" title="请先移除所有数据">
+                      <div className="menu-item text-muted">
+                        <SvgIcon type="xxh-times" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">删除</span>
+                      </div>
+                    </Tooltip>
+                  </Menu.Item>
+                :
+                <Menu.Item key="2"><div className="menu-item" onClick={() => treeBtnClick({ type : record.isfolder ? 'delFolder' : 'delTender', id: record.id, name: record.name })}><SvgIcon type="xxh-times" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">删除</span></div></Menu.Item>
+              }
+              {
+                record.isfolder ? <Menu.Divider /> : ''
+              }
+              {
+                record.isfolder ? (!record.hasFolder) ?
+                <Menu.Item key="3"><div className= "menu-item" onClick={() => treeBtnClick({ type: 'tender', id: record.id })}><SvgIcon type="xxh-plus" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建标段</span></div></Menu.Item>
+                :
+                <Menu.Item key="3">
+                  <Tooltip placement="left" title="标段无法与文件夹同层">
+                    <div className= "menu-item text-muted"><SvgIcon type="xxh-plus" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建标段</span></div>
+                  </Tooltip></Menu.Item>
+                : ''
+              }
+              {
+                record.isfolder ? !record.isBid ?
+                <Menu.Item key="4"><div className="menu-item" onClick={() => treeBtnClick({ type : 'folder', id: record.id })}><SvgIcon type="xxh-folders" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建子文件夹</span></div></Menu.Item>
+                :
+                <Menu.Item key="4">
+                  <Tooltip placement="left" title="文件夹无法与标段同层">
+                    <div className="menu-item text-muted"><SvgIcon type="xxh-folders" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建子文件夹</span></div>
+                  </Tooltip>
+                </Menu.Item>
+                : ''
+              }
+
+            </Menu>
+          )
+        }} trigger={[ 'click' ]}>
+          <span>
+          <SvgIcon type="xxh-align-justify" style={{ fontSize: 12, color: "#007bff" }}></SvgIcon>
+            <CaretDownOutlined style={{ fontSize: "12px", color: "#007bff" }}/>
+          </span>
+        </Dropdown>
+      }
+    }
+  ]
+
+  const onCreate = async (values: iTenderFormValue, type: string) => {
+    console.log('Received values of form: ', values, type)
+    setModal({
+      ...modal,
+      confirmLoading: true
+    })
+    const { code = -1 } = await apiResfulTree(type, values)
+    if (code === consts.RET_CODE.SUCCESS) {
+      getTree()
+    }
+    setModal({
+      ...modal,
+      confirmLoading: false,
+      visible: false,
+      isFolder: false,
+      id: ''
+    })
+
+  }
+  useEffect(() => {
+    getTree()
+  }, [])
+  const getTree = async () => {
+    const { data = {}, code = -1 } = await apiTree()
+    if (code === consts.RET_CODE.SUCCESS) {
+      setTree(data)
+    }
+  }
+  return (
+    <div className="wrap-contaniner">
+      <Header title="标段管理">
+        <Slot position="right">
+          <Button type="primary" size="small" icon={<FolderAddFilled />} onClick={() => treeBtnClick({ type: 'root', id: tree.id })}>新建文件夹</Button>
+        </Slot>
+      </Header>
+      <div className="pi-flex-column">
+        {/* <div className="pi-mg-16 pi-pd-tb-64 pi-pd-lr-32 jumbotron">
+          <h3>没有标段数据</h3>
+        </div> */}
+        <div className={styles.tableContent}>
+          <Table<TenderTree>
+            columns={columns}
+            dataSource={tree.children}
+            pagination={false}
+            rowKey={record => record.id}
+            indentSize={20}
+            bordered
+            ></Table>
+        </div>
+        <ModalForm modalObj={modal}  treeObj={tree} onCreate={onCreate} onCancel={() => setModal({
+          ...modal,
+          visible: false
+        })} ></ModalForm>
+      </div>
+    </div>
+  )
+}
+
+
+export default Tender

+ 20 - 0
src/pages/Management/Tender/Member/api.ts

@@ -0,0 +1,20 @@
+import request from "@/utils/common/request"
+
+/**
+ * 获取标段账号列表
+ * @param id 标段id
+ */
+export async function apiGetSettingAccount(id: string) {
+  const { data } = await request.get('/api/projectSetting/bid/account', { bidsectionId: id })
+  return data
+}
+
+/**
+ * 添加成员账号
+ * @param bidsectionId 标段id
+ * @param accountId 账号id
+ */
+export async function apiCreateBidAccount(bidsectionId: string, accountId: string) {
+  const { data } = await request.post('/api/projectSetting/bid/account/create', { bidsectionId, accountId })
+  return data
+}

+ 110 - 0
src/pages/Management/Tender/Member/index.tsx

@@ -0,0 +1,110 @@
+import { GroupItem } from '@/components/AuditContent'
+import Header from '@/components/Header'
+import Slot from '@/components/Header/slot'
+import SvgIcon from '@/components/SvgIcon'
+import { userStore } from '@/store/mobx'
+import { iAccountGroupItem, iUserInfo } from '@/types/setting'
+import { getUserGroup } from '@/utils/common/user'
+import consts from '@/utils/consts'
+import { Button, Input, message, Popover, Table } from 'antd'
+import { observer } from 'mobx-react'
+import React, { useState, useEffect, ChangeEvent } from 'react'
+import { useActivate } from 'react-activation'
+import { RouteComponentProps } from 'react-router'
+import { apiCreateBidAccount, apiGetSettingAccount } from './api'
+
+
+interface iPopoverState {
+  visible: boolean
+  searchValue: string
+}
+const Member: React.FC<RouteComponentProps> = (props) => {
+  const { id = '', name = '' }: {id: string, name: string} = props.location.state as any
+  const [ groups, setGroups ] = useState<Array<iAccountGroupItem>>([])
+  const [ popoverState, setPopoverState ] = useState<iPopoverState>({ visible: false, searchValue: '' })
+  useEffect(() => {
+    popoverState.visible && (initGroupList())
+    if (!userStore.groupList.length) {
+      userStore.getGroupList()
+    }
+  }, [ popoverState.visible ])
+
+  useEffect(() => {
+    initData()
+  }, [])
+
+  useActivate(() => initData())
+  const initData = async () => {
+    const { code = -1, data } = await apiGetSettingAccount(id)
+    if (code === consts.RET_CODE.SUCCESS) {
+      console.log(data)
+
+    }
+  }
+  const initGroupList = async (serach?: string) => {
+    const data = await getUserGroup(serach)
+    console.log(data)
+
+    setGroups(data)
+  }
+
+  const search = (value: string) => {
+    if (value != popoverState.searchValue) {
+      setPopoverState({ ...popoverState, searchValue: value })
+      initGroupList(value)
+    }
+  }
+
+  const change = (e: ChangeEvent) => {
+    e.persist()
+    const target = e.target as HTMLTextAreaElement
+    if (!target.value) {
+      initGroupList()
+    }
+  }
+
+  const itemSelectHandler = async (item: iUserInfo) => {
+    setPopoverState({ ...popoverState, visible: false })
+    const { code = -1, msg = '添加成员账号失败!' } = await apiCreateBidAccount(id, item.id)
+    if (code === consts.RET_CODE.SUCCESS) {
+      await initGroupList(id)
+      return message.success('创建成功!')
+    }
+    return message.error(msg)
+  }
+
+  const handleVisibleChange = (visible: boolean) => {
+    setPopoverState({ ...popoverState, visible })
+  }
+
+  const showPopover = () => {
+    setPopoverState({ ...popoverState, visible: true })
+  }
+  return (
+    <div className="wrap-contaniner">
+      <Header title={`${name} 成员管理`}>
+        <Slot position="right">
+        <Popover
+          title={<Input.Search size="small" placeholder="姓名/手机 检索" onSearch={search} onChange={e => change(e)}></Input.Search>}
+          content={groups.map(item => (
+            <GroupItem {...item} key={item.value} onSelect={(item: iUserInfo) => itemSelectHandler(item)}></GroupItem>
+          ))}
+          overlayClassName="popover-card"
+          trigger="click"
+          visible={popoverState.visible}
+          onVisibleChange={handleVisibleChange}
+          placement="bottomRight">
+          <Button type="primary" size="small" onClick={showPopover}>
+            <span>添加成员</span><SvgIcon type="xxh-caret-down"></SvgIcon>
+          </Button>
+        </Popover>
+        </Slot>
+      </Header>
+      <div className="wrap-content">
+        <Table></Table>
+      </div>
+    </div>
+  )
+}
+
+export default observer(Member)

+ 13 - 193
src/pages/Management/Tender/index.tsx

@@ -1,197 +1,17 @@
-import Header from '@/components/Header'
-import Slot from '@/components/Header/slot'
-import SvgIcon from '@/components/SvgIcon'
-import { iModalProps, iTenderFormValue, TenderTree } from '@/types/tender'
-import consts from '@/utils/consts'
-import { CaretDownOutlined, FolderAddFilled } from '@ant-design/icons'
-import { Button, Dropdown, Menu, Table, Tooltip } from 'antd'
-import { ColumnsType } from 'antd/lib/table'
-import React, { useEffect, useState } from 'react'
-import { Link } from 'react-router-dom'
-import { apiResfulTree, apiTree } from './api'
-import ModalForm from './components/ModalForm'
-import styles from './index.module.scss'
-import './index.scss'
-const Tender: React.FC<{}> = () =>{
-  const [ tree, setTree ] = useState<TenderTree>({ ancounts: 0,
-    attribution: '',
-    bidsectionId: '',
-    childsTotal: 0,
-    createTime: '',
-    csrf: '',
-    depth: 0,
-    children: [],
-    hasFolder: false,
-    id: '',
-    isBid: false,
-    leaf: false,
-    isEnd: false,
-    isfolder: 0,
-    moveId: '',
-    name: '',
-    parentId: '',
-    projectId: '',
-    serial: '',
-    updateTime: '' })
-  const [ modal, setModal ] = useState<iModalProps>({
-    type: 'folder',
-    visible: false,
-    confirmLoading: false,
-    isFolder: false,
-    id: ''
-  })
-  const treeBtnClick = (payload: any) => {
-    setModal({
-      ...modal,
-      visible: true,
-      ...payload
-    })
-  }
-
-  const columns: ColumnsType<TenderTree>  = [
-    {
-      title: '名称',
-      dataIndex: 'name',
-      key: 'name',
-      // eslint-disable-next-line react/display-name
-      render: (text: string, record: TenderTree) => {
-        if (record.isfolder) {
-          return <div style={{ verticalAlign: "baseline" }}><SvgIcon type="xxh-folder-open" style={{ fontSize: 12 }} /><span className="pi-mg-left-2">{text}</span></div>
-        } else {
-          return <div><span style={{ color: '#6c757d', marginRight: '.5rem' }}>{record.isEnd ? '└' : '├'}</span><span>{text}</span></div>
-        }
-      }
-    },
-    {
-      title: '成员',
-      dataIndex: 'member',
-      key: 'member',
-      width: 200,
-      // eslint-disable-next-line react/display-name
-      render: (text:string, record: TenderTree) => {
-        if (record.leaf) {
-          return <div><span className="pi-mg-right-5">{record.ancounts} 成员</span><Link className={styles.treeBtn} to="/">成员管理</Link></div>
-        }
-      }
-    },
-    {
-      title: '操作',
-      dataIndex: 'opreate',
-      key: 'opreate',
-      width: 80,
-      // eslint-disable-next-line react/display-name
-      render: (text:string, record: TenderTree) => {
-        return <Dropdown overlay={() => {
-          return (
-            <Menu>
-              <Menu.Item key="0"><div className="menu-item"  onClick={() => treeBtnClick({ type: 'rename', id: record.id })}><SvgIcon type="xxh-edit" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">重命名</span></div></Menu.Item>
-              <Menu.Item key="1"><div className="menu-item" onClick={() => treeBtnClick({ type: 'move', id: record.id, isFolder: Boolean(record.isfolder) })}><SvgIcon type="xxh-exchange-alt" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">移动</span></div></Menu.Item>
-              {
-                record.children?.length ?
-                  <Menu.Item key="2">
-                    <Tooltip placement="left" title="请先移除所有数据">
-                      <div className="menu-item text-muted">
-                        <SvgIcon type="xxh-times" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">删除</span>
-                      </div>
-                    </Tooltip>
-                  </Menu.Item>
-                :
-                <Menu.Item key="2"><div className="menu-item" onClick={() => treeBtnClick({ type : record.isfolder ? 'delFolder' : 'delTender', id: record.id, name: record.name })}><SvgIcon type="xxh-times" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">删除</span></div></Menu.Item>
-              }
-              {
-                record.isfolder ? <Menu.Divider /> : ''
-              }
-              {
-                record.isfolder ? (!record.hasFolder) ?
-                <Menu.Item key="3"><div className= "menu-item" onClick={() => treeBtnClick({ type: 'tender', id: record.id })}><SvgIcon type="xxh-plus" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建标段</span></div></Menu.Item>
-                :
-                <Menu.Item key="3">
-                  <Tooltip placement="left" title="标段无法与文件夹同层">
-                    <div className= "menu-item text-muted"><SvgIcon type="xxh-plus" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建标段</span></div>
-                  </Tooltip></Menu.Item>
-                : ''
-              }
-              {
-                record.isfolder ? !record.isBid ?
-                <Menu.Item key="4"><div className="menu-item" onClick={() => treeBtnClick({ type : 'folder', id: record.id })}><SvgIcon type="xxh-folders" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建子文件夹</span></div></Menu.Item>
-                :
-                <Menu.Item key="4">
-                  <Tooltip placement="left" title="文件夹无法与标段同层">
-                    <div className="menu-item text-muted"><SvgIcon type="xxh-folders" style={{ fontSize: 12 }}></SvgIcon><span className="pi-mg-left-5">新建子文件夹</span></div>
-                  </Tooltip>
-                </Menu.Item>
-                : ''
-              }
-
-            </Menu>
-          )
-        }} trigger={[ 'click' ]}>
-          <span>
-          <SvgIcon type="xxh-align-justify" style={{ fontSize: 12, color: "#007bff" }}></SvgIcon>
-            <CaretDownOutlined style={{ fontSize: "12px", color: "#007bff" }}/>
-          </span>
-        </Dropdown>
-      }
-    }
-  ]
-
-  const onCreate = async (values: iTenderFormValue, type: string) => {
-    console.log('Received values of form: ', values, type)
-    setModal({
-      ...modal,
-      confirmLoading: true
-    })
-    const { code = -1 } = await apiResfulTree(type, values)
-    if (code === consts.RET_CODE.SUCCESS) {
-      getTree()
-    }
-    setModal({
-      ...modal,
-      confirmLoading: false,
-      visible: false,
-      isFolder: false,
-      id: ''
-    })
-
-  }
-  useEffect(() => {
-    getTree()
-  }, [])
-  const getTree = async () => {
-    const { data = {}, code = -1 } = await apiTree()
-    if (code === consts.RET_CODE.SUCCESS) {
-      setTree(data)
-    }
-  }
+import Guards from '@/components/Navigation'
+import { NavigationGuardsProps } from '@/types/router'
+import React from 'react'
+import { Switch } from 'react-router-dom'
+const Management:React.FC<NavigationGuardsProps> = props => {
+  const { routeConfig, match, location } = props
   return (
-    <div className="wrap-contaniner">
-      <Header title="标段管理">
-        <Slot position="right">
-          <Button type="primary" size="small" icon={<FolderAddFilled />} onClick={() => treeBtnClick({ type: 'root', id: tree.id })}>新建文件夹</Button>
-        </Slot>
-      </Header>
-      <div className="pi-flex-column">
-        <div className="pi-mg-16 pi-pd-tb-64 pi-pd-lr-32 jumbotron">
-          <h3>没有标段数据</h3>
-        </div>
-        <div className={styles.tableContent}>
-          <Table<TenderTree>
-            columns={columns}
-            dataSource={tree.children}
-            pagination={false}
-            rowKey={record => record.id}
-            indentSize={20}
-            bordered
-            ></Table>
-        </div>
-        <ModalForm modalObj={modal}  treeObj={tree} onCreate={onCreate} onCancel={() => setModal({
-          ...modal,
-          visible: false
-        })} ></ModalForm>
+    <>
+      <div className="panel-content">
+        <Switch>
+            <Guards routeConfig={routeConfig} match={match} location={location}></Guards>
+        </Switch>
       </div>
-    </div>
+    </>
   )
 }
-
-
-export default Tender
+export default Management

+ 1 - 1
src/pages/Safe/Content/Info/index.tsx

@@ -8,7 +8,7 @@ const Content:React.FC<NavigationGuardsProps> = props => {
     <>
       <div className="panel-content">
         <Switch>
-              <Guards routeConfig={routeConfig} match={match} location={location}></Guards>
+          <Guards routeConfig={routeConfig} match={match} location={location}></Guards>
         </Switch>
       </div>
     </>

+ 14 - 1
src/router/routes.ts

@@ -238,7 +238,20 @@ export const routeConfig: RouteModel[] = [
             component: AsyncModuleLoader(() => import('@/pages/Management/Tender')),
             meta: {
               title: '标段管理'
-            }
+            },
+            childRoutes: [
+              {
+                path: 'list',
+                defaultChildRoute: true,
+                auth: [ 'ADMIN' ],
+                component: AsyncModuleLoader(() => import('@/pages/Management/Tender/List'))
+              },
+              {
+                path: 'member',
+                auth: [ 'ADMIN' ],
+                component: AsyncModuleLoader(() => import('@/pages/Management/Tender/Member'))
+              }
+            ]
           }
         ]
       },