import { Button , Col , Input , Row , Form , message } from 'antd' ; import React , { useState , useCallback , useEffect } from 'react' ; import omit from 'omit.js' ; import type { FormItemProps } from 'antd/es/form/FormItem' ; import { getFakeCaptcha } from '@/services/login' ; import ItemMap from './map' ; import type { LoginContextProps } from './LoginContext' ; import LoginContext from './LoginContext' ; import styles from './index.less' ; export type WrappedLoginItemProps = LoginItemProps ; export type LoginItemKeyType = keyof typeof ItemMap ; export type LoginItemType = { UserName : React . FC < WrappedLoginItemProps > ; Password : React . FC < WrappedLoginItemProps > ; Mobile : React . FC < WrappedLoginItemProps > ; Captcha : React . FC < WrappedLoginItemProps > ; } ; export type LoginItemProps = { name ? : string ; style ? : React . CSSProperties ; placeholder ? : string ; buttonText ? : React . ReactNode ; countDown ? : number ; getCaptchaButtonText ? : string ; getCaptchaSecondText ? : string ; updateActive ? : LoginContextProps [ 'updateActive' ] ; type ? : string ; defaultValue ? : string ; customProps ? : Record < string , unknown > ; onChange ? : ( e : React . ChangeEvent < HTMLInputElement > ) => void ; tabUtil ? : LoginContextProps [ 'tabUtil' ] ; } & Partial < FormItemProps > ; const FormItem = Form . Item ; const getFormItemOptions = ( { onChange , defaultValue , customProps = { } , rules , } ) => { const options = { rules : rules || ( customProps . rules as LoginItemProps [ 'rules' ] ) , } ; if ( onChange ) { options . onChange = onChange ; } if ( defaultValue ) { options . initialValue = defaultValue ; } return options ; } ; const LoginItem = ( props ) => { const [ count , setCount ] = useState < number > ( props . countDown || 0 ) ; const [ timing , setTiming ] = useState ( false ) ; const { onChange , customProps , defaultValue , rules , name , getCaptchaButtonText , getCaptchaSecondText , updateActive , type , tabUtil , ... restProps } = props ; const onGetCaptcha = useCallback ( async ( mobile ) => { const result = await getFakeCaptcha ( mobile ) ; if ( result === false ) { return ; } message . success ( '获取验证码成功！验证码为：1234' ) ; setTiming ( true ) ; } , [ ] ) ; useEffect ( ( ) => { let interval = 0 ; const { countDown } = props ; if ( timing ) { interval = window . setInterval ( ( ) => { setCount ( ( preSecond ) => { if ( preSecond <= 1 ) { setTiming ( false ) ; clearInterval ( interval ) ; return countDown || 60 ; } return preSecond - 1 ; } ) ; } , 1000 ) ; } return ( ) => { clearInterval ( interval ) ; } ; } , [ timing ] ) ; if ( ! name ) { return null ; } const options = getFormItemOptions ( props ) ; const otherProps = restProps || { } ; if ( type === 'Captcha' ) { const inputProps = omit ( otherProps , [ 'onGetCaptcha' , 'countDown' ] ) ; return ( < FormItem shouldUpdate > { ( { getFieldValue } ) => ( < Row gutter = { 8 } > < Col span = { 16 } > < FormItem name = { name } { ... options } > < Input { ... customProps } { ... inputProps } /> < /FormItem> < /Col> < Col span = { 8 } > < Button disabled = { timing } className = { styles . getCaptcha } size = "large" onClick = { ( ) => { const value = getFieldValue ( 'mobile' ) ; onGetCaptcha ( value ) ; } } > { timing ? `${ count } 秒` : '获取验证码' } < /Button> < /Col> < /Row>)} < /FormItem>); } return ( < FormItem name = { name } { ... options } > < Input { ... customProps } { ... otherProps } /> < /FormItem>); } ; const LoginItems = { } ; Object . keys ( ItemMap ) . forEach ( ( key ) => { const item = ItemMap [ key ] ; LoginItems [ key ] = ( props ) => ( < LoginContext . Consumer > { ( context ) => ( < LoginItem customProps = { item . props } rules = { item . rules } { ... props } type = { key } { ... context } updateActive = { context . updateActive } / > ) } < /LoginContext.Consumer>); } ) ; export default LoginItems as LoginItemType ;