king
2020-07-31 9a9650c758bd84bef0739aa8949627af666bb1c1
2020-07-31
10个文件已修改
635 ■■■■ 已修改文件
src/api/index.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/login.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/login.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.scss 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/markcolumn/markform/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.scss 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/loginform.jsx 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -2,6 +2,7 @@
import qs from 'qs'
import { notification } from 'antd'
import md5 from 'md5'
import moment from 'moment'
import Utils from '@/utils/utils.js'
import options from '@/store/options.js'
@@ -66,10 +67,96 @@
   * @param {Object} param 查询及提交参数
   */
  dostarInterface (param) {
    param.userid = ''
    param.userid = param.userid || ''
    return axios({
      url: '/webapi/dostar',
      data: param
    })
  }
  /**
   * @description 使用dostar接口,跳转至dostars
   * @param {Object} param 查询及提交参数
   */
  dostarToDostars (param) {
    param.userid = param.userid || sessionStorage.getItem('UserID') || ''
    param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || ''
    param.nonc = Utils.getuuid()
    let keys = Object.keys(param).sort()
    let values = ''
    keys.forEach(key => {
      if (key === 'rduri' || key === 't') return
      if (typeof(param[key]) === 'object') {
        values += key + JSON.stringify(param[key])
      } else {
        values += key + param[key]
      }
    })
    param.sign  = md5(values)
    param.t = new Date().getTime()
    return axios({
      url: '/webapi/dostar',
      data: param
    })
  }
  /**
   * @description 游客登录
   */
  getTouristMsg () {
    let param = {
      func: 's_visitor_login',
      timestamp: moment().format('YYYY-MM-DD HH:mm:ss') + '.000',
      SessionUid: localStorage.getItem('SessionUid'),
      TypeCharOne: 'pc'
    }
    param.LText = md5(window.btoa(localStorage.getItem('SessionUid') + param.timestamp))
    param.secretkey = md5(param.LText + 'mingke' + param.timestamp)
    param.appkey = window.GLOB.appkey || ''
    if (window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
    }
    return axios({
      url: '/webapi/dologon',
      data: param
    })
  }
  /**
   * @description 手机号验证码登录
   */
  getphoneusermsg (phoneNo, checkcode, isCloud = false) {
    let param = {
      // func: 'webapi_login',
      mob: phoneNo,
      UserName: '',
      Password: '',
      check_code: checkcode,
      way_no: 'sms_vcode',
      systemType: options.sysType
    }
    param.appkey = window.GLOB.appkey || ''
    if (isCloud) {
      param.debug = 'Y'
      if (options.cloudServiceApi) {
        param.rduri = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
      }
    } else if (!isCloud && window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
    }
    return axios({
      url: '/webapi/dologon',
      data: param
    })
  }
@@ -150,7 +237,7 @@
   * @description 获取或修改系统配置,增加appkey
   */
  getSystemConfig (param) {
    param.userid = sessionStorage.getItem('UserID')
    param.userid = sessionStorage.getItem('UserID') || ''
    param.lang = localStorage.getItem('lang') || ''
    param.SessionUid = localStorage.getItem('SessionUid') || ''
    param.LoginUID = sessionStorage.getItem('LoginUID') || ''
@@ -158,7 +245,7 @@
    if (sessionStorage.getItem('isEditState') === 'true' && options.cloudServiceApi) { // 编辑状态,且存在云端地址
      param.rduri = options.cloudServiceApi
      param.userid = sessionStorage.getItem('CloudUserID')
      param.userid = sessionStorage.getItem('CloudUserID') || ''
      param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
    } else if (window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi
src/locales/en-US/login.js
@@ -4,10 +4,16 @@
  'login.auth.cancel': 'Cancel',
  'login.username': 'Username',
  'login.username.empty': 'Please input your username!',
  'login.phone': 'Mobile phone no',
  'login.phone.empty': 'Please enter your cell phone number!',
  'login.vercode': 'Verification code',
  'login.vercode.empty': 'Please enter your verification code!',
  'login.vercode.query': 'Get verify code',
  'login.vercode.queryagain': 'Obtain again after @s',
  'login.password': 'Password',
  'login.password.empty': 'Please input your Password!',
  'login.remember': 'Remember me',
  'login.submit': 'Log in',
  'login.copyright': 'Copyrights by',
  'login.sync.cloud': '同步云端应用'
  'login.sync.cloud': 'Synchronous cloud application'
}
src/locales/zh-CN/login.js
@@ -4,6 +4,12 @@
  'login.auth.cancel': '取消',
  'login.username': '用户名',
  'login.username.empty': '请输入用户名!',
  'login.phone': '手机号',
  'login.phone.empty': '请输入手机号!',
  'login.vercode': '验证码',
  'login.vercode.empty': '请输入验证码!',
  'login.vercode.query': '获取验证码',
  'login.vercode.queryagain': '@s后重新获取',
  'login.password': '密码',
  'login.password.empty': '请输入密码!',
  'login.remember': '记住密码',
src/tabviews/subtable/index.scss
@@ -3,9 +3,9 @@
  min-height: 200px;
  > .top-search {
    padding: 0 0px 20px;
    padding: 0 0px 10px;
  }
  >.sub-action {
  .sub-action {
    min-height: 25px;
    .button-list {
      padding: 10px 0px 5px;
src/tabviews/subtabtable/index.scss
@@ -3,11 +3,14 @@
  min-height: 200px;
  padding-top: 16px;
  > .top-search {
    padding: 0 0px 20px;
    padding: 0 0px 10px;
  }
  > .button-list {
  .button-list.toolbar-button {
    padding: 10px 0px 5px;
  }
  .normal-data-table {
    padding: 0 0 30px;
  }
  .box404 {
    padding-top: 30px;
  }
src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -203,7 +203,9 @@
      } else {
        this.getprintdata(btn, data, formdata, formlist).then(result => {
          if (result.next) {
            printlist = result.list.map(cell => {
            result.list.forEach(cell => {
              if (!cell.data || cell.data.length === 0) return
              cell.templateID = cell.templateID || btn.verify.Template
              cell.printType = cell.printType || formdata.printType || ''
@@ -216,7 +218,7 @@
              templates.push(cell.templateID)
              return cell
              printlist.push(cell)
            })
          }
          
@@ -700,11 +702,11 @@
    let printerList = []
    Object.keys(printdata).forEach(printer => {
      let _documents = []
      Object.keys(template).forEach(key => {
        let _datalist = printdata[printer].filter(cell => cell.templateID === key)
  
        if (_datalist.length > 0) {
        if (_datalist.length === 0) return
          let _data = []
          _datalist.forEach(res => {
            res.data.forEach(_cell => {
@@ -729,16 +731,6 @@
            })
          })
  
          let _cell = {
            documentID: Utils.getuuid(),
            contents: [
              {
                data: _data,
                templateURL: JSON.stringify(template[key].config)
              }
            ]
          }
          if (lacks.length > 0 || emptys.length > 0) {
            lacks = Array.from(new Set(lacks))
            emptys = Array.from(new Set(emptys))
@@ -750,11 +742,23 @@
            })
          }
  
          _documents.push(_cell)
        let results = []
        let num = 100
        for(let i = 0, len = _data.length; i < len; i += num){
          results.push(_data.slice(i, i + num))
        }
      })
      if (_documents.length > 0) {
        results.forEach(result => {
          let _cell = {
            documentID: Utils.getuuid(),
            contents: [
              {
                data: result,
                templateURL: JSON.stringify(template[key].config)
              }
            ]
          }
        printerList.push({
          cmd: 'print',
          requestID: Utils.getuuid(),
@@ -763,10 +767,11 @@
            taskID: Utils.getuuid(),
            preview: false,
            printer: printer,
            documents: _documents
              documents: [_cell]
          }
        })
      }
        })
      })
    })
    if (list.length === 0) {
@@ -821,8 +826,8 @@
        }
        socket.send(JSON.stringify(request))
      } else {
        printerList.forEach(cell => {
          socket.send(JSON.stringify(cell))
        printerList.forEach((cell, index) => {
          setTimeout(() => {socket.send(JSON.stringify(cell))}, 500 * index)
        })
        this.execSuccess({
@@ -833,6 +838,7 @@
        })
      }
    }
    // 打开Socket
    socket.onopen = () =>{
      if (lackItems) {
@@ -843,8 +849,8 @@
        }
        socket.send(JSON.stringify(request))
      } else {
        printerList.forEach(cell => {
          socket.send(JSON.stringify(cell))
        printerList.forEach((cell, index) => {
          setTimeout(() => {socket.send(JSON.stringify(cell))}, 500 * index)
        })
        this.execSuccess({
@@ -875,11 +881,11 @@
      }
      if (data && data.cmd === 'getPrinters' && data.status) {
        printerList.forEach(cell => {
        printerList.forEach((cell, index) => {
          if (cell.task.printer === 'lackprinter') {
            cell.task.printer = data.defaultPrinter
          }
          socket.send(JSON.stringify(cell))
          setTimeout(() => {socket.send(JSON.stringify(cell))}, 500 * index)
        })
        this.execSuccess({
src/templates/sharecomponent/columncomponent/markcolumn/markform/index.jsx
@@ -40,12 +40,25 @@
    const { columns } = this.props
    let item = columns.filter(col => col.field === record.field)[0]
    let _type = 'background '
    if (record.signType === 'icon' || record.signType === 'font') {
      _type = 'font '
    }
    this.setState({
      originField: item || '',
      editItem: record,
      contrastType: record.contrastType || '',
      signType: record.signType || '',
      selectIcon: record.icon || ''
      selectIcon: record.icon || '',
      options: this.state.options.map(option => {
        option.children = option.children.map(cell => {
          cell.label = <div className={_type + cell.value}>{record.icon ? <Icon type={record.icon} /> : cell.value}</div>
          return cell
        })
        return option
      })
    }, () => {
      let fieldvalue = {}
      Object.keys(record).forEach(key => {
@@ -351,7 +364,7 @@
                <Cascader
                  options={options}
                  placeholder=""
                  displayRender={(label, selectedOptions) => selectedOptions[0] ? selectedOptions[0].label + ' / ' + selectedOptions[1].value : ''}
                  displayRender={(label, selectedOptions) => selectedOptions[0] ? selectedOptions[0].label + (selectedOptions[1] ? ' / ' + selectedOptions[1].value : '') : ''}
                  getPopupContainer={() => document.getElementById('model-mark-form-box')}
                />
              )}
src/views/login/index.jsx
@@ -32,6 +32,8 @@
    webSite: window.GLOB.webSite || '',
    langList: [],
    syncApp: false,
    loginWays: null,
    touristLogin: false,
    syncing: false
  }
@@ -53,7 +55,12 @@
      this.setState({
        isDisabled: true
      })
      if (res.type === 'uname_pwd') {
      this.loginsubmit(res)
      } else if (res.type === 'sms_vcode') {
        this.phoneloginsubmit(res)
      }
    })
  }
@@ -105,6 +112,46 @@
    }
  }
  async phoneloginsubmit (param) {
    if (options.sysType === 'local' && !window.GLOB.mainSystemApi) { // 业务系统必须设置单点地址
      Modal.warning({
        title: '未设置单点服务器地址,请联系管理员!'
      })
      return
    }
    // 登录提交
    let res = await Api.getphoneusermsg(param.phone, param.vercode)
    if (res.status) {
      sessionStorage.setItem('UserID', res.UserID)
      sessionStorage.setItem('LoginUID', res.LoginUID)
      sessionStorage.setItem('User_Name', res.UserName)
      sessionStorage.setItem('Full_Name', res.FullName)
      sessionStorage.setItem('avatar', res.icon || '')
      localStorage.setItem('lang', param.lang || 'zh-CN')
      if (this.props.location.state && this.props.location.state.from.pathname) {
        // 查看是否为其他页面跳转,路径存在时,跳回原页面
        this.props.history.replace(this.props.location.state.from.pathname)
      } else {
        this.props.history.replace('/main')
      }
    } else if (res.ErrCode === 'Need_Get_Appkey' && options.sysType === 'SSO') {
      message.warning('应用尚未创建,请向云端同步应用!')
      this.setState({
        isDisabled: false,
        syncApp: true
      })
    } else {
      message.warning(res.message)
      this.setState({
        isDisabled: false
      })
    }
  }
  componentDidMount () {
    let timeStamp = new Date().getTime()
    let _appId = window.GLOB.appId
@@ -116,13 +163,15 @@
    let str = md5('MK19' + _appId + timeStamp)
    let param = {
      rduri: 'http://minkesoft.com/mksepc/webapi/dostar',
      rduri: 'http://minkesoft.com/mksepc/webapi/dostars',
      func: 'sEmpowerCloud_Get_LinkUrl',
      AppID: _appId,
      TimeStamp: timeStamp
      TimeStamp: timeStamp,
      userid: 'bh0bapabtd45epsgra79segbch6c1ibk',
      LoginUID: 'bh0bapabtd45epsgra79segbch6c1ibk'
    }
    Api.dostarInterface(param).then(res => {
    Api.dostarToDostars(param).then(res => {
      if (res.status) {
        if (res.EPC === str) {
          let box = []
@@ -158,10 +207,22 @@
      })
    }
    Api.getTouristMsg().then(result => {
      if (result.status) {
        if (!sessionStorage.getItem('UserID') && result.UserID) {
          sessionStorage.setItem('UserID', result.UserID)
        }
        if (!sessionStorage.getItem('LoginUID') && result.LoginUID) {
          sessionStorage.setItem('LoginUID', result.LoginUID)
        }
        if (result.UserID && result.LoginUID) {
          this.setState({touristLogin: true})
        }
    // 获取系统信息
    let _param = {
      func: 's_Get_style',
      Appkey: window.GLOB.appkey || '',
      TypeCharOne: 'PC',
      LText: `select '${window.GLOB.appkey}'`,
    }
@@ -169,11 +230,7 @@
    _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
    if (window.GLOB.mainSystemApi) {
      _param.rduri = window.GLOB.mainSystemApi.replace('dostars', 'dostar')
    }
    Api.dostarInterface(_param).then(res => {
        Api.getSystemConfig(_param).then(res => {
      if (res.status) {
        let _url = window.location.href.split('#')[0] + 'system'
        let systemMsg = {
@@ -199,7 +256,39 @@
          localStorage.removeItem(_url)
        }
        
            let _loginurl = window.location.href.split('#')[0] + 'loginways'
            let login_ways = []
            let login_types = []
            if (res.login_ways && res.login_ways.length > 0) {
              res.login_ways.forEach(item => {
                // 短信验证码登录,必须设置短信Id
                if (item.way_no === 'sms_vcode' && !item.sms_id) return
                if (login_types.includes(item.way_no)) return
                login_types.push(item.way_no)
                login_ways.push({
                  label: item.way_name,
                  type: item.way_no,
                  smsId: item.sms_id
                })
              })
            } else {
              login_ways.push({
                label: '账号密码登录',
                type: 'uname_pwd',
                smsId: ''
              })
            }
            try {
              localStorage.setItem(_loginurl, window.btoa(window.encodeURIComponent(JSON.stringify(login_ways))))
            } catch {
              localStorage.removeItem(_loginurl)
            }
        this.setState({
              loginWays: login_ways,
          langList: res.lang_data || [],
          ...systemMsg
        })
@@ -224,6 +313,25 @@
        message.warning(res.message)
      }
    })
      } else {
        message.warning(result.message)
      }
    })
    let loginWays = localStorage.getItem(window.location.href.split('#')[0] + 'loginways')
    if (loginWays) {
      try {
        loginWays = JSON.parse(window.decodeURIComponent(window.atob(loginWays)))
      } catch {
        localStorage.removeItem(window.location.href.split('#')[0] + 'loginways')
      }
      if (loginWays) {
        this.setState({
          loginWays: loginWays
        })
      }
    }
  }
  syncSubmit = () => {
@@ -301,7 +409,7 @@
  }
  render () {
    const { lineColor, bgImage, loginlogo, copyRight, webSite, ICP } = this.state
    const { lineColor, bgImage, loginlogo, copyRight, webSite, ICP, loginWays, touristLogin } = this.state
    return (
      <div className="login-container" style={bgImage ? {backgroundImage: 'url(' + bgImage + ')'} : {}}>
@@ -309,17 +417,19 @@
          {loginlogo ? <img src={loginlogo} alt=""/> : null}
        </div>
        <div className="login-middle" style={lineColor ? {borderColor: lineColor} : {}}>
          <LoginForm
          {loginWays ? <LoginForm
            platName={this.state.platName}
            dict={this.state.dict}
            auth={this.state.auth}
            touristLogin={touristLogin}
            loginWays={loginWays}
            lang={this.state.selectedlang}
            langList={this.state.langList}
            isDisabled={this.state.isDisabled}
            changelang={(value) => this.changelang(value)}
            handleSubmit={() => this.handleSubmit()}
            wrappedComponentRef={(inst) => this.loginformRef = inst}
          />
          /> : null}
        </div>
        <div className="login-bottom">
          {webSite && copyRight ?
src/views/login/index.scss
@@ -14,6 +14,46 @@
      max-height: 100%;
    }
  }
  .ant-tabs.ant-tabs-card {
    .ant-tabs-card-bar {
      border-bottom: 0;
      .ant-tabs-nav-container {
        height: 50px;
        line-height: 50px;
      }
      margin-bottom: 10px;
      .ant-tabs-nav-scroll {
        .ant-tabs-nav {
          display: block;
          > div {
            display: flex;
            > .ant-tabs-tab {
              height: 50px;
              line-height: 50px;
              flex: 1;
            }
          }
        }
      }
      .ant-tabs-tab {
        display: block;
        margin-right: 0;
        border-radius: 0;
        text-align: center;
        font-size: 18px;
      }
      .ant-tabs-tab.ant-tabs-tab-active {
        cursor: default;
      }
    }
  }
  .login-form-1 {
    .ant-tabs-tab {
      text-align: left!important;
      padding-left: 1.6vw!important;
    }
  }
  .login-middle {
    position: relative;
    height: calc(100vh - 194px);
@@ -26,11 +66,15 @@
      float: right;
      margin-top: 5%;
      margin-right: 20%;
      padding: 1.6vw;
      background: #ffffff;
      width: 22vw;
      min-width: 300px;
      border-radius: 5px;
      overflow: hidden;
      .form-item-wrap {
        padding: 0.6vw 1.6vw 1.6vw;
      }
      h4 {
        font-size: 20px;
@@ -45,6 +89,23 @@
      }
      .btn-login {
        margin-bottom: 3vh;
        clear: both;
      }
      .register-line {
        font-size: 14px;
        margin-bottom: 10px;
        height: 25px;
        .ant-form-item-control {
          line-height: 25px;
        }
        .register {
          color: #1890ff;
        }
        .forgot {
          font-size: 14px;
          color: #1890ff;
          float: right;
        }
      }
      .minline {
        display: inline-block;
@@ -54,6 +115,7 @@
      .minline.right {
        float: right;
        width: 100px;
        margin-bottom: 2vh;
        .ant-select-selection {
          border: 0;
          box-shadow: none;
@@ -63,7 +125,10 @@
          }
        }
      }
      button {
      button.vercode {
        border: 0;
      }
      button:not(.vercode) {
        width: 100%;
        height: calc(2vw + 10px);
        min-height: 30px;
@@ -89,7 +154,7 @@
      .ant-form label {
        font-size: 16px;
      }
      .ant-btn {
      .ant-btn:not(.vercode) {
        font-size: 18px;
      }
      .anticon-eye {
@@ -141,3 +206,15 @@
    }
  }
}
@media screen and (min-width: 1550px) {
  .login-container {
    .ant-tabs.ant-tabs-card {
      .ant-tabs-card-bar {
        .ant-tabs-tab {
          font-size: 20px;
        }
      }
    }
  }
}
src/views/login/loginform.jsx
@@ -1,33 +1,91 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Icon, Input, Button, Checkbox, Select, Modal } from 'antd'
import { is, fromJS } from 'immutable'
import { Form, Icon, Input, Button, Checkbox, Select, Modal, Tabs, message } from 'antd'
import md5 from 'md5'
import moment from 'moment'
import Api from '@/api'
import options from '@/store/options.js'
import './index.scss'
const { warning } = Modal
const { TabPane } = Tabs
let LoginVerCodeTimer = null
class MainSearch extends Component {
class LoginTabForm extends Component {
  static propTpyes = {
    isDisabled: PropTypes.bool,
    changelang: PropTypes.func,
    handleSubmit: PropTypes.func,
    dict: PropTypes.object,
    auth: PropTypes.bool,
    touristLogin: PropTypes.bool,
    lang: PropTypes.string,
    langList: PropTypes.array,
    loginWays: PropTypes.array,
    platName: PropTypes.string
  }
  state = {
    activeKey: 'uname_pwd',
    username: '',
    password: ''
    password: '',
    delay: null,
    loginWays: [],
    smsId: '',
    verdisabled: false
  }
  UNSAFE_componentWillMount () {
    const { loginWays } = this.props
    let smsId = ''
    let _loginWays = []
    loginWays.forEach(item => {
      if (item.type === 'sms_vcode') {
        smsId = item.smsId
        _loginWays.push(item)
      } else if (item.type === 'uname_pwd') {
        _loginWays.push(item)
      }
    })
    this.setState({
      smsId: smsId,
      loginWays: _loginWays,
      activeKey: _loginWays[0].type
    })
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.loginWays), fromJS(nextProps.loginWays))) {
      let smsId = ''
      let _loginWays = []
      nextProps.loginWays.forEach(item => {
        if (item.type === 'sms_vcode') {
          smsId = item.smsId
          _loginWays.push(item)
        } else if (item.type === 'uname_pwd') {
          _loginWays.push(item)
        }
      })
      this.setState({
        smsId: smsId,
        loginWays: _loginWays,
        activeKey: _loginWays[0].type
      })
    }
  }
  handleConfirm = () => {
    const { activeKey } = this.state
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
          resolve({type: activeKey, ...values})
        } else {
          reject(err)
        }
@@ -40,6 +98,7 @@
  }
  handleSubmit = e => {
    const { activeKey } = this.state
    // 登录参数检验
    e.preventDefault()
    if (!this.props.auth) {
@@ -53,6 +112,7 @@
      return
    }
    if (activeKey === 'uname_pwd') {
    if (!this.props.form.getFieldValue('username')) {
      const input = document.getElementById('username')
      if (input) {
@@ -65,6 +125,21 @@
      }
    } else {
      this.props.handleSubmit()
      }
    } else if (activeKey === 'sms_vcode') {
      if (!this.props.form.getFieldValue('phone')) {
        const input = document.getElementById('phone')
        if (input) {
          input.focus()
        }
      } else if (!this.props.form.getFieldValue('vercode')) {
        const input = document.getElementById('vercode')
        if (input) {
          input.focus()
        }
      } else {
        this.props.handleSubmit()
      }
    }
  }
@@ -99,13 +174,98 @@
    }
  }
  onChangeTab = (activeKey) => {
    this.setState({activeKey})
  }
  getvercode = () => {
    const { smsId } = this.state
    let _phone = this.props.form.getFieldValue('phone')
    if (!_phone) {
      message.warning('请输入手机号!')
      return
    } else if (!/^1[3456789]\d{9}$/.test(_phone)) {
      message.warning('手机号格式错误,请重填!')
      return
    } else if (!this.props.touristLogin) {
      message.warning('未获取验证码设置,请稍后或刷新重试!')
      return
    }
    let param = {
      func: 'MSN_sms_send_code',
      send_type: 'login',
      mob: _phone,
      timestamp: moment().format('YYYY-MM-DD HH:mm:ss') + '.000',
      ID: smsId
    }
    param.LText = md5(`${_phone}mingke${window.GLOB.appkey}${param.timestamp}`)
    param.secretkey = md5(`${param.LText}mingke${param.timestamp}`)
    this.setState({
      verdisabled: true,
      delay: 60
    })
    LoginVerCodeTimer = setTimeout(this.resetVerCodeDelay, 1000)
    Api.getSystemConfig(param).then(res => {
      if (res.status) {
      } else {
        if (LoginVerCodeTimer) {
          clearTimeout(LoginVerCodeTimer)
        }
        this.setState({
          verdisabled: false,
          delay: null
        })
        message.warning(res.message)
      }
    }, () => {
      if (LoginVerCodeTimer) {
        clearTimeout(LoginVerCodeTimer)
      }
      this.setState({
        verdisabled: false,
        delay: null
      })
    })
  }
  resetVerCodeDelay = () => {
    const { delay } = this.state
    if (delay && delay > 1) {
      this.setState({delay: delay - 1})
      LoginVerCodeTimer = setTimeout(this.resetVerCodeDelay, 1000)
    } else {
      this.setState({
        verdisabled: false,
        delay: null
      })
    }
  }
  /**
   * @description 组件销毁,清除state更新
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const { activeKey, verdisabled, delay, loginWays } = this.state
    return (
      <Form onSubmit={this.handleSubmit} className="login-form" id="login-form">
        <h4>{this.props.platName}</h4>
        <Form.Item>
      <Form className={`login-form login-form-${loginWays.length}`} id="login-form" onSubmit={this.handleSubmit}>
        <Tabs type="card" activeKey={activeKey} onChange={this.onChangeTab}>
          {loginWays.map(item => (<TabPane tab={item.label} key={item.type}></TabPane>))}
        </Tabs>
        <div className="form-item-wrap">
          {activeKey === 'uname_pwd' ? <Form.Item>
          {getFieldDecorator('username', {
            rules: [{ required: true, message: this.props.dict['login.username.empty'] }],
            initialValue: this.state.username || '',
@@ -116,8 +276,8 @@
              autoComplete="off"
            />,
          )}
        </Form.Item>
        <Form.Item>
          </Form.Item> : null}
          {activeKey === 'uname_pwd' ? <Form.Item>
          {getFieldDecorator('password', {
            initialValue: this.state.password || '',
            rules: [
@@ -127,13 +287,45 @@
              }
            ]
          })(<Input.Password placeholder={this.props.dict['login.password']} prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
        </Form.Item>
        <Form.Item className="minline">
          </Form.Item> : null}
          {activeKey === 'sms_vcode' ? <Form.Item>
            {getFieldDecorator('phone', {
              rules: [{ required: true, message: this.props.dict['login.phone.empty'] }],
              initialValue: '',
            })(
              <Input
                placeholder={this.props.dict['login.phone']}
                autoComplete="off"
              />
            )}
          </Form.Item> : null}
          {activeKey === 'sms_vcode' ? <Form.Item>
            {getFieldDecorator('vercode', {
              initialValue: '',
              rules: [
                {
                  required: true,
                  message: this.props.dict['login.vercode.empty'],
                }
              ]
            })(
              <Input
                addonAfter={
                  <Button type="link" className="vercode" size="small" disabled={verdisabled} onClick={this.getvercode}>
                    {delay ? this.props.dict['login.vercode.queryagain'].replace('@', delay) : this.props.dict['login.vercode.query']}
                  </Button>
                }
                placeholder={this.props.dict['login.vercode']}
                autoComplete="off"
              />
            )}
          </Form.Item> : null}
          {activeKey === 'uname_pwd' ? <Form.Item className="minline">
          {getFieldDecorator('remember', {
            valuePropName: 'checked',
            initialValue: true,
          })(<Checkbox>{this.props.dict['login.remember']}</Checkbox>)}
        </Form.Item>
          </Form.Item> : null}
        {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right">
          {getFieldDecorator('lang', {
            initialValue: this.props.lang,
@@ -148,14 +340,19 @@
            </Select>
          )}
        </Form.Item> : null}
        <Form.Item className="btn-login">
          {['uname_pwd', 'sms_vcode'].includes(activeKey) ? <Form.Item className="btn-login">
          <Button type="primary" htmlType="submit" className="login-form-button" disabled={this.props.isDisabled} loading={this.props.isDisabled}>
            {this.props.dict['login.submit']}
          </Button>
        </Form.Item>
          </Form.Item> : null}
          {options.sysType === 'cloud' ? <Form.Item className="register-line">
            <a href="http://minkesoft.com/#/signup" target="_blank" rel="noopener noreferrer" className="register">注册</a>
            <a href="http://minkesoft.com/#/forgotPwd" target="_blank" rel="noopener noreferrer" className="forgot">忘记密码?</a>
          </Form.Item> : null}
        </div>
      </Form>
    )
  }
}
export default Form.create()(MainSearch)
export default Form.create()(LoginTabForm)