Browse Source

feat: 修复缓存问题以及标段管理移动文件夹选项置灰的bug

lanjianrong 4 years ago
parent
commit
f10fa87313

+ 10 - 8
src/components/Menu/index.tsx

@@ -3,7 +3,7 @@ import { userStore } from '@/store/mobx'
 import { iMenuItem } from '@/types/router'
 import { Button, Dropdown, Menu } from "antd"
 import { observer } from 'mobx-react'
-import React, { Component } from 'react'
+import React from 'react'
 import { Link } from "react-router-dom"
 import styles from './index.module.scss'
 import './index.scss'
@@ -11,10 +11,13 @@ import MenuItem from './MenuItem'
 interface iMenuProps {
   list: iMenuItem[]
 }
-@observer
-class NavSider extends Component<iMenuProps, any> {
-  render() {
-    const { list: MeunList } = this.props
+
+const NavSider: React.FC<iMenuProps> = (props) => {
+  const { list: MeunList } = props
+
+  const handleLogout = () => {
+    userStore.logout()
+  }
     return (
       <div className="main-nav">
         <div className="logo"><img src={logo} /></div>
@@ -52,7 +55,7 @@ class NavSider extends Component<iMenuProps, any> {
                     </Menu.Item>
                     <Menu.Item key="3">
                       {/* <Link to="/login">退出登录</Link> */}
-                      <span onClick={() => userStore.logout()}>退出登录</span>
+                      <span onClick={() => handleLogout()}>退出登录</span>
                     </Menu.Item>
                   </Menu>
                 )
@@ -64,7 +67,6 @@ class NavSider extends Component<iMenuProps, any> {
         </div>
       </div>
     )
-  }
 }
 
-export default NavSider
+export default observer(NavSider)

+ 20 - 21
src/pages/Login/index.tsx

@@ -3,7 +3,8 @@ import { userStore } from '@/store/mobx'
 import { iFromValues, iLoginProps, iRetrieveFormProps } from '@/types/login'
 import consts from '@/utils/consts'
 import { Button, Form, Input, Modal } from 'antd'
-import React, { Component } from 'react'
+import React, { useState, useEffect } from 'react'
+import { useAliveController } from 'react-activation'
 import { RouteComponentProps, withRouter } from 'react-router-dom'
 import { apiProject } from "./api"
 import styles from './index.module.scss'
@@ -17,51 +18,50 @@ const initLoginState = {
 }
 
 type iState = typeof initLoginState
-class NormalLoginForm extends Component<iLoginProps, iState> {
-
-  constructor(props: iLoginProps) {
-    super(props)
-    this.state = initLoginState
-  }
-  onFinish = (values: iFromValues) => {
+const NormalLoginForm:React.FC<iLoginProps> = () => {
+  const { clear } = useAliveController()
+  useEffect(() => {
+    clear()
+  }, [])
+  const [ state, setState ] = useState<iState>(initLoginState)
+  const onFinish = (values: iFromValues) => {
     userStore.login(values)
   }
 
-  handleProjectCode = async (e: any) => {
+
+  const handleProjectCode = async (e: any) => {
     const projectCode = e.target?.value
     const { code = -1, data = [] } = await apiProject(projectCode)
     if (code === consts.RET_CODE.SUCCESS) {
       if (data.length && data[0].name) {
-        this.setState({ projectInfo: data[0].name })
+        setState({ ...state, projectInfo: data[0].name })
       }
     }
 
   }
 
-  setVisible = (label: boolean) => {
-    this.setState({ visible: label })
+  const setVisible = (label: boolean) => {
+    setState({ ...state, visible: label })
   }
 
-  handleForgetPsw = () => {
-    this.setState({ visible: !this.state.visible })
+  const handleForgetPsw = () => {
+    setState({ ...state, visible: !state.visible })
   }
 
-  render() {
-    const { projectInfo } = this.state
     return (
       <Form
         name="normal_login"
         className={styles.loginForm}
         // initialValues={{ password: '123456', code : '234' }}
-        onFinish={this.onFinish}
+        onFinish={onFinish}
       >
         <h4>纵横工程建设项目管理系统</h4>
-        <h5 className={[ 'project-title' ].join(' ')} >{projectInfo}</h5>
+        <h5 className={[ 'project-title' ].join(' ')} >{state.projectInfo}</h5>
         <Form.Item
           name="code"
           rules={[ { required: true, message: '请输入项目编号!' } ]}
         >
-          <Input placeholder="项目编号" onChange={this.handleProjectCode} autoFocus/>
+          <Input placeholder="项目编号" onChange={handleProjectCode} autoFocus/>
         </Form.Item>
         <Form.Item
           name="account"
@@ -82,10 +82,9 @@ class NormalLoginForm extends Component<iLoginProps, iState> {
         {/* <div className={styles.textRight}>
           <span onClick={this.handleForgetPsw}>忘记密码?</span>
         </div> */}
-        <RetrieveForm visible={this.state.visible} setVisible={this.setVisible} />
+        <RetrieveForm visible={state.visible} setVisible={setVisible} />
       </Form>
     )
-  }
 }
 
 // 找回密码Form表单

+ 8 - 6
src/pages/Management/Tender/List/components/ModalForm.tsx

@@ -13,7 +13,7 @@ interface Option {
 interface iModalFormProps {
   treeObj: TenderTree
   modalObj: iModalProps
-  onCreate: (values: iTenderFormValue, type: string ) => void
+  onCreate: (values: iTenderFormValue, type: string) => void
   onCancel: () => void
 }
 
@@ -73,6 +73,8 @@ const ModalForm: React.FC<iModalFormProps> = ({
   useEffect(() => {
     form.setFieldsValue({ [type === 'tender' ? 'folderId' : 'id']: id })
     if (type === 'move') {
+      console.log(mapTree(treeObj.children, id, isFolder) as Option[])
+
       setCascader(mapTree(treeObj.children, id, isFolder) as Option[])
     }
     if (type === 'move' || type.indexOf('del') !== -1) {
@@ -105,7 +107,7 @@ const ModalForm: React.FC<iModalFormProps> = ({
       <Form form={form} layout="vertical">
         <Form.Item name={type === 'tender' ? 'folderId' : 'id'} hidden ><Input /></Form.Item>
         {
-          showNameInput ? <Form.Item  name="name" label={modalObj[type].nameTitle} rules={[ { required: true, message: '请输入文件夹名称!' },{
+          showNameInput ? <Form.Item name="name" label={modalObj[type].nameTitle} rules={[ { required: true, message: '请输入文件夹名称!' }, {
             validator: async (_, names) => {
               if (names && names.length > 30) {
                 return Promise.reject(new Error('名称超过30个字,请缩减名称。'))
@@ -119,7 +121,7 @@ const ModalForm: React.FC<iModalFormProps> = ({
           showNameInput ? <Form.Item name="depth" hidden><Input /></Form.Item> : null
         }
         {
-          type === 'move' ? <Form.Item name="targetFolderId"><TreeSelect treeData={cascader} placeholder={modalObj[type].namePlaceholder} allowClear  /></Form.Item> : null
+          type === 'move' ? <Form.Item name="targetFolderId"><TreeSelect treeData={cascader} placeholder={modalObj[type].namePlaceholder} allowClear /></Form.Item> : null
         }
         {
           type.indexOf('del') !== -1 ? <div><p>确认删除「{name}」?</p><p>删除后,数据无法恢复,请谨慎操作。</p></div> : null
@@ -129,8 +131,8 @@ const ModalForm: React.FC<iModalFormProps> = ({
   )
 }
 
-function mapTree(treeArr:TenderTree[], id: string, isFolder: boolean) {
-  const arr =  treeArr?.map((tree:TenderTree) => {
+function mapTree(treeArr: TenderTree[], id: string, isFolder: boolean) {
+  const arr = treeArr?.map((tree: TenderTree) => {
     if (!tree.isfolder) return
     const newTree: Option = { value: tree.id, title: tree.name, disabled: tree.id === id }
     // 要移动的是文件夹
@@ -142,7 +144,7 @@ function mapTree(treeArr:TenderTree[], id: string, isFolder: boolean) {
       if (tree.children.findIndex(item => item.id === id) !== -1) {
         newTree.disabled = true
       }
-      newTree.children = mapTree(tree.children, id, Boolean(tree.isfolder)) as Option[]
+      newTree.children = mapTree(tree.children, id, isFolder) as Option[]
     }
     return newTree
   }).filter(item => item) // filter过滤滤掉map可能产生的underfined item

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

@@ -2,17 +2,22 @@ import Header from '@/components/Header'
 import Slot from '@/components/Header/slot'
 import SvgIcon from '@/components/SvgIcon'
 import { iModalProps, iTenderFormValue, TenderTree } from '@/types/tender'
+import { useAutoTable } from '@/utils/common/customHooks'
 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 { useActivate } from 'react-activation'
 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 needSubtractHeight =  34 + 32 + 32 // 需要被裁掉的高度
+
+  const [ y ] = useAutoTable(needSubtractHeight)
   const [ tree, setTree ] = useState<TenderTree>({
     ancounts: 0,
     attribution: '',
@@ -160,6 +165,8 @@ const Tender: React.FC<{}> = () => {
   useEffect(() => {
     getTree()
   }, [])
+
+  // useActivate(() => getTree())
   const getTree = async () => {
     const { data = {}, code = -1 } = await apiTree()
     if (code === consts.RET_CODE.SUCCESS) {
@@ -186,6 +193,7 @@ const Tender: React.FC<{}> = () => {
               pagination={false}
               rowKey={record => record.id}
               indentSize={20}
+              scroll={{ y }}
               expandable={{ defaultExpandAllRows: true }}
               bordered
             />

+ 18 - 0
src/utils/common/customHooks.ts

@@ -109,3 +109,21 @@ export const useListModal = (dataType: number): [ListModal, (newData: ListModal)
   }
   return [ state, onChange ]
 }
+
+export const useAutoTable = (needSubtractHeight: number) => {
+  // console.log(collapsed)
+
+
+  const [ scroll, setScroll ] = useState({ y: document.body.clientHeight - needSubtractHeight })
+
+  useEffect(() => {
+    const handleScroll = () => setScroll({ ...scroll, y: document.body.clientHeight - needSubtractHeight })
+    window.addEventListener('resize', handleScroll)
+    return () => {
+      window.removeEventListener('resize', handleScroll)
+    }
+  }, [])
+
+  // 实际返回的宽度要大一点让table出现滚动条,反正折叠菜单栏卡顿
+  return [ scroll.y ]
+}