react hook 版本 定时器倒计时

 核心代码   直接复制我的核心代码去改就可以了。。。我这算是最简单的方法了

 const [codeLoading, setcodeLoading] = useState<boolean>(false) // 验证码的loading
const [timeTip, settimeTip] = useState<any>("60秒后重发") // 定时器倒计时提示 

// 倒计时  执行这个函数就行
    const setIntervalFn = () => {
      let defaultTime = 60
      let time = 60
      let tip = `${time}秒后重发`
      let timeObj2 = setInterval(() => {
        if (time === 0) {
          time = defaultTime
          tip = `${time}秒后重发`
          settimeTip(tip)
          setcodeLoading(false)
          clearInterval(timeObj2)
          return false
        }
        --time
        tip = `${time}秒后重发`
        settimeTip(tip)
      }, 1000)
    }

 完整代码 仅供参考修改

import React, { useState, useEffect } from "react"
import { history, connect, Dispatch } from "umi"
import { useLocation, useHistory } from "react-router"
import { Button, Form, Input, Upload, message, Modal, Popconfirm, Spin, Select, Checkbox } from "antd"
import { LoadingOutlined, PlusOutlined, MinusCircleFilled } from "@ant-design/icons"
import { userPopOut } from "@/services/components/treeGroupMemberSearch"
import { userHospitalApi, userSwitchApi, updatePasswordApi, setNewPasswordApi, sendVerifyCodeApi } from "@/services/login"
// import { GroupUser, IconsultGroupAddinPam } from "@/typings/consultationTeam.d"
import styles from "./index.less"
import { trim } from "lodash"

interface IseleType {
  label: string,
  value: any,
}

const Index: React.FC<any> = (props) => {

  const { userInfo } = props

  let query = history.location.query as any

  const [current, setCurrent] = useState<number>(1) // 默认个人信息1   修改密码2
  const [loading, setLoading] = useState<boolean>(false)

  const [seleOption, setSeleOption] = useState<IseleType[]>([])
  const [seleValue, setSeleValue] = useState<string>("") // 切换的医院
  const [hospitalId, setHospitalId] = useState<string>("") // 医院id


  const activeChange = (num: number) => {
    setCurrent(num)
  }

  // 切换医院
  const seleChange = (value: any, obj: any) => {
    console.log(111122, value, obj)
    setSeleValue(obj.label)
    setHospitalId(obj.value)
  }

  // 根据手机号查询所在医院
  const userHospitalApiFn = async () => {
    setLoading(true)
    let phone = userInfo.contactPhone
    const [err, res] = await userHospitalApi(phone)
    setLoading(false)
    if (err) {
      console.log("userHospitalApi:err", err)
      // return message.error(err.message)
    }
    let arr: IseleType[] = []
    let isAdd = false
    if (res.data && res.data.length >= 1) {
      res.data.forEach((i) => {
        if (String(userInfo.hospitalId) === i.id) {
          isAdd = true
          setSeleValue(i.hospitalName)
          setHospitalId(i.id)
        }
        let obj = { value: i.id, label: i.hospitalName }
        arr.push(obj)
      })
      setSeleOption(arr)

      if (!isAdd) {
        setSeleValue(arr[0].label)
        setHospitalId(arr[0].value)
      }

    }

  }

  // 切换所选的医院
  const switchFn = async () => {
    if (String(userInfo.hospitalId) === hospitalId) {
      return message.error("当前已经是该单位,无需切换")
    }
    setLoading(true)
    const [err, res] = await userSwitchApi(hospitalId)
    setLoading(false)
    if (err) {
      return message.error(err.message)
    }
    props.dispatch({
      type: "indexModel/updateUserInfo",
      payload: res.data
    })
    // 获取数据字典
    props.dispatch({
      type: "indexModel/getAllEnum",
      payload: {}
    })
    setLoading(false)

    history.push({
      pathname: "/index",
      query: {

      },
    })

  }



  // 个人信息界面
  const InfoView = () => {
    return (
      <div style={{ padding: "0 40px" }}>
        {loading ? <Spin className="spinClass" tip="加载中..." /> : null}
        <div className={styles.mgb30}>
          <span className={styles.leftT}>用户名</span>: <span className={styles.rightV}>{userInfo.name}</span>
        </div>
        <div className={styles.mgb30}>
          <span className={styles.leftT}>手机号</span>: <span className={styles.rightV}>{userInfo.contactPhone}</span>
        </div>
        <div className={styles.mgb30}>
          <span className={styles.leftT}>单位</span>: <Select value={seleValue} onChange={seleChange} options={seleOption} className={styles.selectClass} />

        </div>
        <div className={styles.mgb30}>
          <span className={styles.leftT}>部门</span>: <span className={styles.rightV}>{userInfo.deptName}</span>
        </div>

        <div style={{ textAlign: "center", paddingTop: "1.5rem" }}>
          <Button className={styles.cancel}  >
            取消
          </Button>
          <Button onClick={switchFn} disabled={loading} className={styles.determine} style={{ marginLeft: "16px" }} type="primary"  >
            保存
          </Button>
        </div>
      </div >
    )
  }


  const [passType, setPassType] = useState<number>(1) // 1原密码 2动态密码

  const passOnChange = (e: any, type: number) => {
    // let c = e.target.checked
    setPassType(type)
  }

  // 原密码
  const Ymm = () => {
    interface IpassType {
      oldPwd: string
      newPwd: string
      confirmNewPwd: string
    }

    const [loading1, setLoading1] = useState<boolean>(false)

    const [oldPwd, setoldPwd] = useState<string>("")
    const [newPwd, setnewPwd] = useState<string>("")
    const [confirmNewPwd, setconfirmNewPwd] = useState<string>("")
    // 密码长度6-24位,至少包含字母,数字,符号2种组合

    const [form] = Form.useForm()
    const layout = {
      labelCol: { span: 5 },
      // wrapperCol: { span: 16 },
    }
    // 验证正确后回调
    const onFinish = async (obj: IpassType) => {
      console.log(11, obj)
      if (obj.newPwd !== obj.confirmNewPwd) {
        return message.error("2次数输入密码不相同")
      }
      setLoading1(true)
      const [err, res] = await updatePasswordApi(obj)
      setLoading1(false)
      if (err) {
        return message.error(err.message)
      }
      message.success(res.message)
      history.replace({
        pathname: "/login",
        query: {

        },
      })

    }
    // 触发提交
    const submit = () => {
      form.submit()
    }
    return (
      <div>
        {loading1 ? <Spin className="spinClass" tip="加载中..." /> : null}
        <Form
          {...layout}
          form={form}
          onFinish={onFinish}
          name="basic"
        >
          <Form.Item
            label="原密码"
            name="oldPwd"
            rules={[
              {
                required: true,
                validator: async (_, names) => {
                  let reg = new RegExp(/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,24}$/) // 6-24位,至少带字母数字符号中的两种的正则
                  let result = reg.test(oldPwd)
                  if (oldPwd.indexOf(" ") !== -1) {
                    return Promise.reject(new Error("不允许输入空格"))
                  }
                  // if (!result) {
                  //   return Promise.reject(new Error("请输入密码长度6-24位,至少包含字母,数字,符号2种组合"))
                  // }
                },
              }
            ]}
          >
            <Input maxLength={24} placeholder="请输入原密码" value={oldPwd} onChange={(e) => setoldPwd(e.target.value)} />
          </Form.Item>

          <Form.Item
            label="新密码"
            name="newPwd"
            rules={[
              {
                required: true,
                validator: async (_, names) => {
                  let reg = new RegExp(/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,24}$/) // 6-24位,至少带字母数字符号中的两种的正则
                  let result = reg.test(newPwd)
                  if (newPwd.indexOf(" ") !== -1) {
                    return Promise.reject(new Error("不允许输入空格"))
                  }
                  if (!result) {
                    return Promise.reject(new Error("请输入密码长度6-24位,至少包含字母,数字,符号2种组合"))
                  }
                },
              }
            ]}
          >
            <Input.Password maxLength={24} placeholder="请输入新密码" value={newPwd} onChange={(e) => setnewPwd(e.target.value)} />
          </Form.Item>
          <Form.Item
            label="确认密码"
            name="confirmNewPwd"
            rules={[
              {
                required: true,
                validator: async (_, names) => {
                  let reg = new RegExp(/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,24}$/) // 6-24位,至少带字母数字符号中的两种的正则
                  let result = reg.test(confirmNewPwd)
                  if (confirmNewPwd.indexOf(" ") !== -1) {
                    return Promise.reject(new Error("不允许输入空格"))
                  }
                  if (!result) {
                    return Promise.reject(new Error("请输入密码长度6-24位,至少包含字母,数字,符号2种组合"))
                  }
                },
              }
            ]}
          >
            <Input.Password maxLength={24} placeholder="请输入确认密码" value={confirmNewPwd} onChange={(e) => setconfirmNewPwd(e.target.value)} />
          </Form.Item>

        </Form>
        <div style={{ textAlign: "center", paddingTop: "1.5rem" }}>
          <Button className={styles.cancel}  >
            取消
          </Button>
          <Button onClick={submit} disabled={loading1} className={styles.determine} style={{ marginLeft: "16px" }} type="primary"  >
            保存
          </Button>
        </div>
      </div >
    )
  }

  // 动态密码
  const Dtmm = () => {
    interface IpassType {
      phone?: string
      verifyCode: string
      newPwd: string
      confirmNewPwd: string
    }
    const [loading2, setLoading2] = useState<boolean>(false)

    const [codeLoading, setcodeLoading] = useState<boolean>(false) // 验证码的loading
    const [timeTip, settimeTip] = useState<any>("60秒后重发") // 定时器倒计时提示

    const [phone, setphone] = useState<string>("")
    const [verifyCode, setverifyCode] = useState<string>("")
    const [newPwd, setnewPwd] = useState<string>("")
    const [confirmNewPwd, setconfirmNewPwd] = useState<string>("")

    const [form2] = Form.useForm()
    const layout = {
      labelCol: { span: 5 },
      // wrapperCol: { span: 16 },
    }
    // 验证正确后回调
    const onFinish = async (obj: IpassType) => {
      obj.phone = userInfo.contactPhone
      console.log(11, obj)
      if (obj.newPwd !== obj.confirmNewPwd) {
        return message.error("2次数输入密码不相同")
      }
      setLoading2(true)
      const [err, res] = await setNewPasswordApi(obj)
      setLoading2(false)
      if (err) {
        return message.error(err.message)
      }
      message.success(res.message)
      history.replace({
        pathname: "/login",
        query: {

        },
      })

    }

    // 倒计时
    const setIntervalFn = () => {
      let defaultTime = 60
      let time = 60
      let tip = `${time}秒后重发`
      let timeObj2 = setInterval(() => {
        if (time === 0) {
          time = defaultTime
          tip = `${time}秒后重发`
          settimeTip(tip)
          setcodeLoading(false)
          clearInterval(timeObj2)
          return false
        }
        --time
        tip = `${time}秒后重发`
        settimeTip(tip)
      }, 1000)
    }

    // 发送验证码api
    const getCodeApi = async () => {
      let obj = {
        type: "newPwd",
        phone: userInfo.contactPhone
      }
      setLoading2(true)
      const [err, res] = await sendVerifyCodeApi(obj)
      setLoading2(false)
      if (err) {
        return message.error(err.message)
      }
      setIntervalFn()

      message.success(res.message)

    }

    // 获取验证码
    const getCode = () => {
      if (userInfo.contactPhone === "" || userInfo.contactPhone === null) {
        return message.error("暂无手机号,不能发送验证码")
      }
      setcodeLoading(true)
      getCodeApi()
    }

    // 触发提交
    const submit = () => {
      form2.submit()
    }
    return (
      <div>
        {loading2 ? <Spin className="spinClass" tip="加载中..." /> : null}
        <Form
          {...layout}
          form={form2}
          onFinish={onFinish}
          name="basic2"
        >
          <Form.Item label="手机号码">
            <span style={{ color: "rgba(0, 0, 0, 0.45)" }}>{userInfo.contactPhone}</span>
          </Form.Item>

          <Form.Item
            label="验证码"
            name="verifyCode"
            rules={[
              {
                required: true,
                validator: async (_, names) => {
                  if (verifyCode.indexOf(" ") !== -1) {
                    return Promise.reject(new Error("不允许输入空格"))
                  }
                  if (verifyCode.length !== 4 || verifyCode === null) {
                    return Promise.reject(new Error("请输入4位验证码"))
                  }
                },
              }
            ]}
          >
            <div style={{ display: "flex" }}>
              <Input placeholder="请输入验证码" maxLength={4} value={verifyCode} onChange={(e) => setverifyCode(e.target.value)} />
              <Button disabled={codeLoading} onClick={getCode} style={{ marginLeft: "10px", width: "110px" }} type="primary"  >
                {codeLoading ? timeTip : "获取验证码"}
              </Button>
            </div>
          </Form.Item>

          <Form.Item
            label="新密码"
            name="newPwd"
            rules={[
              {
                required: true,
                validator: async (_, names) => {
                  let reg = new RegExp(/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,24}$/) // 6-24位,至少带字母数字符号中的两种的正则
                  let result = reg.test(newPwd)
                  if (newPwd.indexOf(" ") !== -1) {
                    return Promise.reject(new Error("不允许输入空格"))
                  }
                  if (!result) {
                    return Promise.reject(new Error("请输入密码长度6-24位,至少包含字母,数字,符号2种组合"))
                  }
                },
              }
            ]}
          >
            <Input.Password placeholder="请输入新密码" maxLength={24} onChange={(e) => setnewPwd(e.target.value)} />
          </Form.Item>
          <Form.Item
            label="确认密码"
            name="confirmNewPwd"
            rules={[
              {
                required: true,
                validator: async (_, names) => {
                  let reg = new RegExp(/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,24}$/) // 6-24位,至少带字母数字符号中的两种的正则
                  let result = reg.test(confirmNewPwd)
                  if (confirmNewPwd.indexOf(" ") !== -1) {
                    return Promise.reject(new Error("不允许输入空格"))
                  }
                  if (!result) {
                    return Promise.reject(new Error("请输入密码长度6-24位,至少包含字母,数字,符号2种组合"))
                  }
                },
              }
            ]}
          >
            <Input.Password placeholder="请输入确认密码" maxLength={24} value={confirmNewPwd} onChange={(e) => setconfirmNewPwd(e.target.value)} />
          </Form.Item>

        </Form>
        <div style={{ textAlign: "center", paddingTop: "1.5rem" }}>
          <Button className={styles.cancel}  >
            取消
          </Button>
          <Button onClick={submit} disabled={loading2} className={styles.determine} style={{ marginLeft: "16px" }} type="primary"  >
            保存
          </Button>
        </div>
      </div >
    )
  }

  // 修改密码界面
  const PassView = () => {
    return (
      <div>
        <div style={{ textAlign: "center", marginBottom: "1.5rem" }}>
          <Checkbox checked={passType === 1 ? true : false} onChange={(e) => passOnChange(e, 1)}><span>原密码</span></Checkbox>
          <Checkbox checked={passType === 2 ? true : false} style={{ marginLeft: "22%" }} onChange={(e) => passOnChange(e, 2)}><span>动态密码</span></Checkbox>
        </div>

        {
          passType === 1 ? <Ymm /> : <Dtmm />
        }

      </div>
    )
  }




  useEffect(() => {
    userHospitalApiFn()
  }, [])






  return (
    <div className={styles.informationWrap}>


      <div className={styles.setWrap}>
        <div className={styles.topBar}>
          <div onClick={() => activeChange(1)} className={`${styles.leftBtn}    ${current === 1 ? styles.activeLeft : null}  `}>个人信息</div>
          <div onClick={() => activeChange(2)} className={`${styles.rightBtn}   ${current === 2 ? styles.activeRight : null} `}>修改密码</div>
        </div>
      </div>

      <div className={styles.conten}>
        <div className={styles.conWrap}>
          {
            current === 1 ? <InfoView /> : <PassView />
          }
        </div>
      </div>


    </div >
  )
}

function mapStateToProps(state: any) {
  return state.indexModel
}


export default connect(mapStateToProps)(Index)

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值