Jelajahi Sumber

feat: 进入单位组织架构

outaozhen 4 tahun lalu
induk
melakukan
59c0ad4665

+ 6 - 0
config/routes.ts

@@ -59,6 +59,12 @@
         component: './Institutions/Company'
       },
       {
+        path: '/company/companyname',
+        name: 'companyName',
+        hideInMenu: true,
+        component: './Institutions/Company/CompanyName'
+      },
+      {
         path: 'staff',
         name: 'staff',
         component: './Institutions/Staff'

+ 103 - 0
src/pages/Institutions/Company/CompanyName/index.tsx

@@ -0,0 +1,103 @@
+import { GridContent } from '@ant-design/pro-layout'
+import React, { useState, useRef, useLayoutEffect } from 'react'
+import { Menu } from 'antd'
+import Staff from '../components/Staff'
+import Organization from '../components/Organization'
+import Role from '../components/Role'
+import styles from '@/pages/Institutions/Company/style.less'
+
+const { Item } = Menu
+
+type CompanyNameStateKeys = 'staff' | 'organization' | 'role'
+type CompanyNameState = {
+  mode: 'inline' | 'horizontal'
+  selectKey: CompanyNameStateKeys
+}
+
+const CompanyName: React.FC = () => {
+  const menuMap: Record<string, React.ReactNode> = {
+    staff: '人员管理',
+    organization: '组织架构',
+    role: '角色权限'
+  }
+  const [initConfig, setInitConfig] = useState<CompanyNameState>({
+    mode: 'inline',
+    selectKey: 'staff'
+  })
+  const dom = useRef<HTMLDivElement>()
+  const resize = () => {
+    requestAnimationFrame(() => {
+      if (!dom.current) {
+        return
+      }
+      let mode: 'inline' | 'horizontal' = 'inline'
+      const { offsetWidth } = dom.current
+      if (dom.current.offsetWidth < 641 && offsetWidth > 400) {
+        mode = 'horizontal'
+      }
+      if (window.innerWidth < 768 && offsetWidth > 400) {
+        mode = 'horizontal'
+      }
+      setInitConfig({ ...initConfig, mode: mode as SettingsState['mode'] })
+    })
+  }
+
+  useLayoutEffect(() => {
+    if (dom.current) {
+      window.addEventListener('resize', resize)
+      resize()
+    }
+    return () => {
+      window.removeEventListener('resize', resize)
+    }
+  }, [dom.current])
+  const getMenu = () => {
+    return Object.keys(menuMap).map(item => <Item key={item}>{menuMap[item]}</Item>)
+  }
+
+  const renderChildren = () => {
+    const { selectKey } = initConfig
+    switch (selectKey) {
+      case 'staff':
+        return <Staff />
+      case 'organization':
+        return <Organization />
+      case 'role':
+        return <Role />
+      default:
+        return null
+    }
+  }
+
+  return (
+    <GridContent>
+      <div
+        className={styles.main}
+        ref={ref => {
+          if (ref) {
+            dom.current = ref
+          }
+        }}>
+        <div className={styles.leftMenu}>
+          <Menu
+            mode={initConfig.mode}
+            selectedKeys={[initConfig.selectKey]}
+            onClick={({ key }) => {
+              setInitConfig({
+                ...initConfig,
+                selectKey: key as CompanyNameStateKeys
+              })
+            }}>
+            {getMenu()}
+          </Menu>
+        </div>
+        <div className={styles.right}>
+          <div className={styles.title}>{menuMap[initConfig.selectKey]}</div>
+          {renderChildren()}
+        </div>
+      </div>
+    </GridContent>
+  )
+}
+
+export default CompanyName

+ 11 - 0
src/pages/Institutions/Company/components/Organization.tsx

@@ -0,0 +1,11 @@
+import React from 'react'
+
+const Organization = () => {
+  return (
+    <div>
+      <span>组织架构</span>
+    </div>
+  )
+}
+
+export default Organization

+ 11 - 0
src/pages/Institutions/Company/components/Role.tsx

@@ -0,0 +1,11 @@
+import React from 'react'
+
+const Role = () => {
+  return (
+    <div>
+      <span>角色管理</span>
+    </div>
+  )
+}
+
+export default Role

+ 11 - 0
src/pages/Institutions/Company/components/Staff.tsx

@@ -0,0 +1,11 @@
+import React from 'react'
+
+const Staff = () => {
+  return (
+    <div>
+      <span>人员管理</span>
+    </div>
+  )
+}
+
+export default Staff

+ 16 - 3
src/pages/Institutions/Company/index.tsx

@@ -2,13 +2,14 @@ import ProTable from '@ant-design/pro-table'
 import type { ProColumnType, ActionType } from '@ant-design/pro-table'
 import { Button } from 'antd'
 import consts from '@/utils/consts'
-import { useRef, useState, useEffect } from 'react'
-import { connect } from 'umi'
+import { useRef, useState, useEffect, useCallback } from 'react'
+import { connect, history, useModel } from 'umi'
 import type { ConnectProps } from 'umi'
 import type { ProjectModelState } from '../model'
 import CompanyModal, { ModalType } from './components/CompanyModal'
 import { queryInstitutionList } from '@/services/api/institution'
 import dayjs from 'dayjs'
+// import CompanyName from './CompanyName'
 
 type ListProps = ConnectProps & {
   pTypeList: { label: string; value: string }[]
@@ -35,10 +36,22 @@ const CompanyList: React.FC<ListProps> = ({ dispatch, pTypeList }) => {
   //   manual: true,
   //   onSuccess: () => tRef.current?.reload()
   // })
+
+  const { initialState, setInitialState } = useModel('@@initialState')
+
+  const showName = useCallback(() => {
+    return history.push(`/institutions/company/companyname`)
+  }, [initialState, setInitialState])
+
   const columns: ProColumnType<API.InstitutionListItem>[] = [
     {
       dataIndex: 'name',
-      title: '企事业单位名称'
+      title: '企事业单位名称',
+      render: (name, record) => (
+        <span onClick={() => showName(record.id)} className="text-primary cursor-pointer">
+          {name}
+        </span>
+      )
     },
     {
       dataIndex: 'acronym',

+ 57 - 0
src/pages/Institutions/Company/style.less

@@ -0,0 +1,57 @@
+@import '~antd/es/style/themes/default.less';
+
+.main {
+  display: flex;
+  width: 100%;
+  height: 100%;
+  padding-top: 16px;
+  padding-bottom: 16px;
+  background-color: @menu-bg;
+  .leftMenu {
+    width: 224px;
+    border-right: @border-width-base @border-style-base @border-color-split;
+    :global {
+      .ant-menu-inline {
+        border: none;
+      }
+      .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
+        font-weight: bold;
+      }
+    }
+  }
+  .right {
+    flex: 1;
+    padding: 8px 40px;
+    .title {
+      margin-bottom: 12px;
+      color: @heading-color;
+      font-weight: 500;
+      font-size: 20px;
+      line-height: 28px;
+    }
+  }
+  /* stylelint-disable-next-line no-descending-specificity */
+  :global {
+    .ant-list-split .ant-list-item:last-child {
+      border-bottom: 1px solid @border-color-split;
+    }
+    /* stylelint-disable-next-line no-descending-specificity */
+    .ant-list-item {
+      padding-top: 14px;
+      padding-bottom: 14px;
+    }
+  }
+}
+
+@media screen and (max-width: @screen-md) {
+  .main {
+    flex-direction: column;
+    .leftMenu {
+      width: 100%;
+      border: none;
+    }
+    .right {
+      padding: 40px;
+    }
+  }
+}