From 400fee62fb40006a9839f1c3a8244b82566b5057 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 08 五月 2025 16:30:39 +0800
Subject: [PATCH] Merge branch 'develop'

---
 src/views/login/loginform.jsx |  593 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 455 insertions(+), 138 deletions(-)

diff --git a/src/views/login/loginform.jsx b/src/views/login/loginform.jsx
index f7887f3..508acd3 100644
--- a/src/views/login/loginform.jsx
+++ b/src/views/login/loginform.jsx
@@ -1,90 +1,218 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { Form, Icon, Input, Button, Checkbox, Select, Modal, Tabs, message } from 'antd'
+import { Form, Input, Button, Checkbox, Select, Modal, message, AutoComplete, Tooltip } from 'antd'
+import { UserOutlined, LockOutlined, QrcodeOutlined, RedoOutlined, CloseCircleOutlined } from '@ant-design/icons'
 import md5 from 'md5'
 import moment from 'moment'
 
 import Api from '@/api'
+import Utils from '@/utils/utils.js'
 import options from '@/store/options.js'
+import asyncLoadComponent from '@/utils/asyncLoadComponent'
+import wxicon from '@/assets/img/wx-icon.png'
 import './index.scss'
 
 const { warning } = Modal
-const { TabPane } = Tabs
 let LoginVerCodeTimer = null
+const QrCode = asyncLoadComponent(() => import('@/components/qrcode'))
+
+const CheckWrap = ({checked, prolType, onChange, prolCont}) => {
+  const change = (e) => {
+    onChange(e.target.checked)
+
+    if (prolType === 'once') {
+      localStorage.setItem(window.GLOB.sysSign + 'protocol', e.target.checked)
+    }
+  }
+
+  return (
+    <>
+      <Checkbox defaultChecked={checked} onChange={change} style={{marginRight: '8px'}}></Checkbox>
+      <span dangerouslySetInnerHTML={{__html: prolCont}}></span>
+    </>
+  )
+}
 
 class LoginTabForm extends Component {
   static propTpyes = {
     isDisabled: PropTypes.bool,
-    changelang: PropTypes.func,
     handleSubmit: PropTypes.func,
-    dict: PropTypes.object,
+    authLogin: PropTypes.func,
     auth: PropTypes.bool,
-    touristLogin: PropTypes.bool,
-    lang: PropTypes.string,
+    authError: PropTypes.string,
     langList: PropTypes.array,
-    loginWays: PropTypes.array,
-    platName: PropTypes.string
+    loginWays: PropTypes.array
   }
 
   state = {
     activeKey: 'uname_pwd',
+    scanId: '',
     username: '',
     password: '',
+    remember: true,
+    protocol: null,
     delay: null,
     loginWays: [],
     smsId: '',
-    verdisabled: false
+    verdisabled: false,
+    hasScan: false,
+    timeout: false,
+    vispwd: window.GLOB.vispwd,
+    wayLabels: {},
+    dict: window.GLOB.dict,
+    users: [],
+    lang: sessionStorage.getItem('lang')
   }
 
+  timer = null
+  splitTime = 0
+  scanParam = null
+
   UNSAFE_componentWillMount () {
-    const { loginWays } = this.props
+    const { loginWays, prolType } = this.props
+
+    let protocol = null
+
+    if (prolType === 'once') {
+      protocol = localStorage.getItem(window.GLOB.sysSign + 'protocol') === 'true'
+    } else if (prolType === 'every_time') {
+      protocol = false
+    }
+
+    let remember = true
+    
+    if (localStorage.getItem(window.GLOB.sysSign + 'remember') === 'false') {
+      remember = false
+    }
+    if (!window.GLOB.keepKey) {
+      remember = false
+    }
 
     let smsId = ''
+    let hasScan = false
     let _loginWays = []
+    let wayLabels = {app_scan: 'APP鎵爜', weixin_scan: '寰俊鎵爜', uname_pwd: '璐﹀彿鐧诲綍', sms_vcode: '鐭俊鐧诲綍'}
+
     loginWays.forEach(item => {
+      item.label = window.GLOB.dict[item.type] || wayLabels[item.type]
+      wayLabels[item.type] = item.label
       if (item.type === 'sms_vcode') {
         smsId = item.smsId
         _loginWays.push(item)
       } else if (item.type === 'uname_pwd') {
         _loginWays.push(item)
+      } else if (item.type === 'app_scan') {
+        _loginWays.push(item)
+        hasScan = true
+      } else if (item.type === 'weixin_scan') {
+        _loginWays.push(item)
+        hasScan = true
       }
     })
 
+    let activeKey = _loginWays[0].type
+    
+    let users = localStorage.getItem(window.GLOB.sysSign + 'users')
+    let _user = null
+    
+    if (users) {
+      try {
+        users = JSON.parse(window.decodeURIComponent(window.atob(users)))
+      } catch (e) {
+        users = []
+      }
+    } else {
+      users = []
+    }
+
+    if (users[0] && activeKey === 'uname_pwd') {
+      _user = users[0]
+    }
+
     this.setState({
+      users: users,
+      username: _user ? _user.username : '',
+      password: _user ? _user.password : '',
       smsId: smsId,
       loginWays: _loginWays,
-      activeKey: _loginWays[0].type
+      activeKey,
+      scanId: activeKey === 'app_scan' || activeKey === 'weixin_scan' ? Utils.getuuid() : '',
+      timeout: false,
+      remember,
+      protocol,
+      wayLabels,
+      hasScan
     })
-  }
 
-  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
-      })
+    if (activeKey === 'app_scan' || activeKey === 'weixin_scan') {
+      this.splitTime = 0
+      this.timer = setTimeout(() => {
+        this.checkResult()
+      }, 10000)
     }
   }
 
+  checkResult = () => {
+    const { scanId, protocol, dict } = this.state
+
+    this.splitTime += 10000
+    this.scanParam = null
+
+    let _param = {
+      func: 'webapi_get_binding_key',
+      scan_type: 'pc',
+      id: scanId,
+      UserName: ''
+    }
+
+    _param.userid = sessionStorage.getItem('visitorUserID')
+    _param.LoginUID = sessionStorage.getItem('visitorLoginUID')
+
+    if (this.splitTime >= 180000) {
+      this.setState({
+        timeout: true
+      })
+      return
+    }
+
+    Api.getSystemConfig(_param).then(res => {
+      if (!res.status) {
+        message.warning(res.message)
+        return
+      } else if (res.thd_party_appid && res.thd_party_member_id && res.thd_party_openid) {
+        if (protocol === false) {
+          this.scanParam = {
+            ...res,
+            scanId
+          }
+          message.warning(dict['protocol_check'] || '璇烽槄璇诲苟鍚屾剰鍗忚锛�')
+          return
+        }
+        this.props.authLogin(res.thd_party_appid, res.thd_party_openid, res.thd_party_member_id, scanId)
+      } else {
+        this.timer = setTimeout(() => {
+          this.checkResult()
+        }, 10000)
+      }
+    })
+  }
+
   handleConfirm = () => {
-    const { activeKey } = this.state
+    const { activeKey, protocol } = this.state
+
+    if (protocol === false) return Promise.reject()
+
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
+          if (activeKey === 'uname_pwd') {
+            values.username = values.username.replace(/\t+|\v+|\s+/g, '')
+            values.password = values.password.replace(/\t+|\v+|\s+/g, '')
+          } else if (activeKey === 'sms_vcode') {
+            values.phone = values.phone.replace(/\t+|\v+|\s+/g, '')
+            values.vercode = values.vercode.replace(/\t+|\v+|\s+/g, '')
+          }
           resolve({type: activeKey, ...values})
         } else {
           reject(err)
@@ -93,19 +221,21 @@
     })
   }
 
-  changelang = (item) => {
-    this.props.changelang(item)
+  changelang = (val) => {
+    localStorage.setItem(window.location.href.split('#')[0] + 'lang', val)
+    sessionStorage.setItem('lang', val)
+
+    window.location.reload()
   }
 
   handleSubmit = e => {
-    const { activeKey } = this.state
+    const { activeKey, dict } = this.state
     // 鐧诲綍鍙傛暟妫�楠�
-    e.preventDefault()
+    e && e.preventDefault()
     if (!this.props.auth) {
       warning({
-        title: this.props.dict['login.auth.tip'],
-        okText: this.props.dict['login.auth.ok'],
-        cancelText: this.props.dict['login.auth.cancel'],
+        title: this.props.authError || dict['auth_tip'] || '绯荤粺鏈巿鏉冿紝璇疯仈绯荤鐞嗗憳銆�',
+        okText: dict['got_it'] || '鐭ラ亾浜�',
         onOk() {},
         onCancel() {}
       })
@@ -114,7 +244,8 @@
 
     if (activeKey === 'uname_pwd') {
       if (!this.props.form.getFieldValue('username')) {
-        const input = document.getElementById('username')
+        const wrap = document.getElementById('username')
+        const input = wrap ? wrap.getElementsByTagName('input')[0] : null
         if (input) {
           input.focus()
         }
@@ -144,75 +275,137 @@
   }
 
   componentDidMount () {
-    let _url = window.location.href.split('#')[0]
-    let _user = localStorage.getItem(_url)
-    
-    if (_user) {
-      try {
-        _user = JSON.parse(window.decodeURIComponent(window.atob(_user)))
-      } catch {
-        console.warn('Parse Failure')
-        _user = ''
-      }
-    }
-
-    if (_user) {
-      this.setState({
-        username: _user.username,
-        password: _user.password
-      }, () => {
-        const input = document.getElementById('username')
-        if (input) {
-          input.focus()
-        }
-      })
-    } else {
-      const input = document.getElementById('username')
-      if (input) {
-        input.focus()
-      }
+    const wrap = document.getElementById('username')
+    const input = wrap ? wrap.getElementsByTagName('input')[0] : null
+    if (input) {
+      input.focus()
     }
   }
 
-  onChangeTab = (activeKey) => {
-    this.setState({activeKey})
+  onChangeTab = (key) => {
+    const { activeKey, loginWays } = this.state
+
+    if (key === 'scan') {
+      key = loginWays.filter(item => item.type === 'app_scan' || item.type === 'weixin_scan')[0].type
+    }
+
+    this.setState({activeKey: key, scanId: key === 'app_scan' || key === 'weixin_scan' ? Utils.getuuid() : ''})
+
+    if (activeKey === 'app_scan' || activeKey === 'weixin_scan') {
+      this.timer && clearTimeout(this.timer)
+    }
+
+    if (key === 'app_scan' || key === 'weixin_scan') {
+      this.splitTime = 0
+      this.setState({timeout: false})
+      this.timer = setTimeout(() => {
+        this.checkResult()
+      }, 10000)
+    }
+  }
+
+  reCode = () => {
+    this.splitTime = 0
+
+    this.setState({timeout: false, scanId: Utils.getuuid()})
+
+    this.timer = setTimeout(() => {
+      this.checkResult()
+    }, 10000)
   }
 
   getvercode = () => {
-    const { smsId } = this.state
+    const { smsId, dict } = this.state
     let _phone = this.props.form.getFieldValue('phone')
     if (!_phone) {
-      message.warning('璇疯緭鍏ユ墜鏈哄彿锛�')
+      message.warning(dict['phone_no_required'] || '璇疯緭鍏ユ墜鏈哄彿锛�')
       return
     } else if (!/^1[3456789]\d{9}$/.test(_phone)) {
-      message.warning('鎵嬫満鍙锋牸寮忛敊璇紝璇烽噸濉紒')
+      message.warning(dict['phone_error'] || '鎵嬫満鍙锋牸寮忛敊璇紝璇烽噸濉紒')
       return
-    } else if (!this.props.touristLogin) {
-      message.warning('鏈幏鍙栭獙璇佺爜璁剧疆锛岃绋嶅悗鎴栧埛鏂伴噸璇曪紒')
+    } else if (!sessionStorage.getItem('visitorUserID') || !sessionStorage.getItem('visitorLoginUID')) {
+      message.warning(dict['vercode_error'] || '鏈幏鍙栭獙璇佺爜璁剧疆锛岃绋嶅悗鎴栧埛鏂伴噸璇曪紒')
       return
     }
 
-    let param = {
-      func: 'MSN_sms_send_code',
+    let _param = {
+      func: 'mes_sms_send_code_sso',
       send_type: 'login',
       mob: _phone,
-      timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
       ID: smsId
     }
+    _param.LText = 'minke'
+    _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    _param.secretkey = md5(`${_param.LText}mingke${_param.timestamp}`)
+    
+    _param.userid = sessionStorage.getItem('visitorUserID') || ''
+    _param.LoginUID = sessionStorage.getItem('visitorLoginUID') || ''
 
-    param.LText = md5(`${_phone}mingke${window.GLOB.appkey}${param.timestamp}`)
-    param.secretkey = md5(`${param.LText}mingke${param.timestamp}`)
+    Api.getSystemConfig(_param).then(res => {
+      if (!res.status || !res.n_id) {
+        message.warning(res.message || '楠岃瘉鐮佽幏鍙栧け璐ワ紒')
+        return
+      }
 
-    this.setState({
-      verdisabled: true,
-      delay: 60
-    })
-    LoginVerCodeTimer = setTimeout(this.resetVerCodeDelay, 1000)
+      let param = {
+        func: 'MSN_sms_send_code',
+        send_type: 'login',
+        mob: _phone,
+        timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
+        ID: smsId,
+        n_id: res.n_id
+      }
+  
+      param.LText = md5(`${_phone}mingke${window.GLOB.appkey}${param.timestamp}`)
+      param.secretkey = md5(`${param.LText}mingke${param.timestamp}`)
 
-    Api.getSystemConfig(param).then(res => {
-      if (res.status) {
+      param.rduri = 'https://sso.mk9h.cn/webapi/dostars'
+      param.userid = 'bh0bapabtd45epsgra79segbch6c1ibk'
+      param.LoginUID = 'bh0bapabtd45epsgra79segbch6c1ibk'
+  
+      this.setState({
+        verdisabled: true,
+        delay: 60
+      })
+      LoginVerCodeTimer = setTimeout(this.resetVerCodeDelay, 1000)
+  
+      Api.genericInterface(param).then(res => {
+        if (res.status) {
+  
+        } else {
+          if (LoginVerCodeTimer) {
+            clearTimeout(LoginVerCodeTimer)
+          }
+          this.setState({
+            verdisabled: false,
+            delay: null
+          })
+          message.warning(res.message)
+        }
+      }, (error) => {
+        if (error && error.ErrCode === 'LoginError') {
+          let param = {
+            func: 's_visitor_login',
+            timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), 
+            SessionUid: 'bh0bapabtd45epsgra79segbch6c1ibk',
+            TypeCharOne: 'pc',
+            appkey: '202004041613277377A6A2456D34A4948AE84'
+          }
+          
+          param.LText = md5(window.btoa('bh0bapabtd45epsgra79segbch6c1ibk' + param.timestamp))
+          param.secretkey = md5(param.LText + 'mingke' + param.timestamp)
+  
+          let params = {
+            url: 'https://sso.mk9h.cn/webapi/dologon',
+            method: 'post',
+            data: JSON.stringify(param)
+          }
 
-      } else {
+          Api.directRequest(params)
+
+          return
+        }
+
         if (LoginVerCodeTimer) {
           clearTimeout(LoginVerCodeTimer)
         }
@@ -220,15 +413,6 @@
           verdisabled: false,
           delay: null
         })
-        message.warning(res.message)
-      }
-    }, () => {
-      if (LoginVerCodeTimer) {
-        clearTimeout(LoginVerCodeTimer)
-      }
-      this.setState({
-        verdisabled: false,
-        delay: null
       })
     })
   }
@@ -246,6 +430,48 @@
     }
   }
 
+  rememberChange = (e) => {
+    let val = e.target.checked
+
+    localStorage.setItem(window.GLOB.sysSign + 'remember', val)
+  }
+
+  complete = (val) => {
+    const { users } = this.state
+
+    let user = users.filter(m => m.username === val)[0]
+    let password = user && user.password ? user.password : ''
+
+    this.props.form.setFieldsValue({password: password})
+
+    if (!password) {
+      const input = document.getElementById('password')
+      if (input) {
+        input.focus()
+      }
+    }
+  }
+
+  deleteUser = (e, val) => {
+    const { users } = this.state
+
+    e.stopPropagation()
+
+    let _users = users.filter(m => m.username !== val)
+    
+    this.setState({users: _users})
+
+    localStorage.setItem(window.GLOB.sysSign + 'users', window.btoa(window.encodeURIComponent(JSON.stringify(_users))))
+  }
+
+  changeAgree = (val) => {
+    this.setState({protocol: val})
+
+    if (this.scanParam && val) {
+      this.props.authLogin(this.scanParam.thd_party_appid, this.scanParam.thd_party_openid, this.scanParam.thd_party_member_id, this.scanParam.scanId)
+    }
+  }
+
   /**
    * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
    */
@@ -253,102 +479,193 @@
     this.setState = () => {
       return
     }
+    this.timer && clearTimeout(this.timer)
   }
 
   render() {
+    const { langList, isDisabled, prolType, prolCont } = this.props
     const { getFieldDecorator } = this.props.form
-    const { activeKey, verdisabled, delay, loginWays } = this.state
+    const { activeKey, verdisabled, delay, loginWays, remember, scanId, timeout, hasScan, users, wayLabels, dict, lang, vispwd, protocol } = this.state
 
     return (
-      <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>
+      <Form className="login-form" id="login-form" onSubmit={this.handleSubmit}>
+        <div className="login-way-title">{wayLabels[activeKey]}</div>
+        {hasScan && activeKey !== 'app_scan' && activeKey !== 'weixin_scan' ? <div className="scan-icon" onClick={() => this.onChangeTab('scan')}><QrcodeOutlined /></div> : null}
+        {activeKey === 'uname_pwd' ? <div className="form-item-wrap">
+          <Form.Item>
             {getFieldDecorator('username', {
-              rules: [{ required: true, message: this.props.dict['login.username.empty'] }],
+              rules: [{ required: true, message: dict['username_required'] || '璇疯緭鍏ョ敤鎴峰悕' }],
               initialValue: this.state.username || '',
             })(
-              <Input
-                prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
-                placeholder={this.props.dict['login.username']}
-                autoComplete="off"
-              />,
+              <AutoComplete
+                className
+                dataSource={users.map((cell, i) => <AutoComplete.Option className="mk-user-option" value={cell.username} key={i}>
+                  {cell.username}
+                  <CloseCircleOutlined onClick={(e) => this.deleteUser(e, cell.username)}/>
+                </AutoComplete.Option>)}
+                filterOption={false}
+                onSelect={this.complete}
+                defaultActiveFirstOption={false}
+                defaultOpen={false}
+                optionLabelProp="value"
+              >
+                <Input
+                  prefix={<UserOutlined style={{ color: 'rgba(0,0,0,.25)' }} />}
+                  placeholder={dict['username'] || '鐢ㄦ埛鍚�'}
+                  autoComplete="off"
+                />
+              </AutoComplete>
             )}
-          </Form.Item> : null}
-          {activeKey === 'uname_pwd' ? <Form.Item>
+          </Form.Item>
+          <Form.Item>
             {getFieldDecorator('password', {
               initialValue: this.state.password || '',
               rules: [
                 {
                   required: true,
-                  message: this.props.dict['login.password.empty'],
+                  message: dict['password_required'] || '璇疯緭鍏ュ瘑鐮�',
                 }
               ]
-            })(<Input.Password placeholder={this.props.dict['login.password']} prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
+            })(<Input.Password placeholder={dict['password'] || '瀵嗙爜'} visibilityToggle={vispwd} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
+          </Form.Item>
+          {window.GLOB.keepKey ? <Form.Item className="minline">
+            {getFieldDecorator('remember', {
+              valuePropName: 'checked',
+              initialValue: remember,
+            })(<Checkbox onChange={this.rememberChange}>{dict['remember_me'] || '璁颁綇瀵嗙爜'}</Checkbox>)}
+          </Form.Item> : <div style={{height: '30px', float: 'left'}}></div>}
+          {langList && langList.length > 0 ? <Form.Item className="minline right">
+            {getFieldDecorator('lang', {
+              initialValue: lang,
+            })(
+              <Select
+                onChange={(value) => {this.changelang(value)}}
+                getPopupContainer={() => document.getElementById('login-form')}
+              >
+                {langList.map((item, index) => {
+                  return <Select.Option key={index} value={item.Lang}>{item.LangName}</Select.Option>
+                })}
+              </Select>
+            )}
           </Form.Item> : null}
-          {activeKey === 'sms_vcode' ? <Form.Item>
+          {prolType ? <Form.Item className="proline">
+            <CheckWrap checked={protocol} onChange={(val) => this.setState({protocol: val})} prolCont={prolCont} prolType={prolType}/>
+          </Form.Item> : null}
+          <Form.Item className="btn-login">
+            {protocol === false ? <Tooltip overlayStyle={{maxWidth: 500}} placement="top" trigger="click" title={dict['protocol_check'] || '璇烽槄璇诲苟鍚屾剰鍗忚锛�'}>
+              <Button type="primary" htmlType="submit" className="login-form-button disabled">
+                {dict['log_in'] || '鐧诲綍'}
+              </Button>
+            </Tooltip> : <Button type="primary" htmlType="submit" className="login-form-button" disabled={isDisabled} loading={isDisabled}>
+            {dict['log_in'] || '鐧诲綍'}
+            </Button>}
+          </Form.Item>
+          {window.GLOB.sysType === 'cloud' && options.cdomain.indexOf('mk9h') > -1 ? <Form.Item className="register-line">
+            <a href="http://www.minkesoft.com/signup" target="_blank" rel="noopener noreferrer" className="register">娉ㄥ唽</a>
+            <a href="http://www.minkesoft.com/forgotPwd" target="_blank" rel="noopener noreferrer" className="forgot">蹇樿瀵嗙爜锛�</a>
+          </Form.Item> : null}
+        </div> : null}
+        {activeKey === 'sms_vcode' ? <div className="form-item-wrap">
+          <Form.Item>
             {getFieldDecorator('phone', {
-              rules: [{ required: true, message: this.props.dict['login.phone.empty'] }],
+              rules: [{ required: true, message: dict['phone_no_required'] || '璇疯緭鍏ユ墜鏈哄彿' }],
               initialValue: '',
             })(
               <Input
-                placeholder={this.props.dict['login.phone']}
+                placeholder={dict['phone_no'] || '鎵嬫満鍙�'}
                 autoComplete="off"
               />
             )}
-          </Form.Item> : null}
-          {activeKey === 'sms_vcode' ? <Form.Item>
+          </Form.Item>
+          <Form.Item className="vercode">
             {getFieldDecorator('vercode', {
               initialValue: '',
               rules: [
                 {
                   required: true,
-                  message: this.props.dict['login.vercode.empty'],
+                  message: dict['vercode_required'] || '璇疯緭鍏ラ獙璇佺爜',
                 }
               ]
             })(
               <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']}
+                    {delay ? `${delay}s` : dict['query_vercode'] || '鑾峰彇楠岃瘉鐮�'}
                   </Button>
                 }
-                placeholder={this.props.dict['login.vercode']}
+                placeholder={dict['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> : null}
-          {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right">
+          </Form.Item>
+          {langList && langList.length > 0 ? <Form.Item className="minline right">
             {getFieldDecorator('lang', {
-              initialValue: this.props.lang,
+              initialValue: lang,
             })(
               <Select
                 onChange={(value) => {this.changelang(value)}}
                 getPopupContainer={() => document.getElementById('login-form')}
               >
-                {this.props.langList.map((item, index) => {
+                {langList.map((item, index) => {
                   return <Select.Option key={index} value={item.Lang}>{item.LangName}</Select.Option>
                 })}
               </Select>
             )}
           </Form.Item> : null}
-          {['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>
+          {prolType ? <Form.Item className="proline">
+            <CheckWrap checked={protocol} onChange={(val) => this.setState({protocol: val})} prolCont={prolCont} prolType={prolType}/>
           </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 className="btn-login">
+            {protocol === false ? <Tooltip overlayStyle={{maxWidth: 500}} placement="top" trigger="click" title={dict['protocol_check'] || '璇烽槄璇诲苟鍚屾剰鍗忚锛�'}>
+              <Button type="primary" htmlType="submit" className="login-form-button disabled">
+                {dict['log_in'] || '鐧诲綍'}
+              </Button>
+            </Tooltip> : <Button type="primary" htmlType="submit" className="login-form-button" disabled={isDisabled} loading={isDisabled}>
+              {dict['log_in'] || '鐧诲綍'}
+            </Button>}
+          </Form.Item>
+          {window.GLOB.sysType === 'cloud' && options.cdomain.indexOf('mk9h') > -1 ? <Form.Item className="register-line">
+            <a href="http://www.minkesoft.com/signup" target="_blank" rel="noopener noreferrer" className="register">娉ㄥ唽</a>
+            <a href="http://www.minkesoft.com/forgotPwd" target="_blank" rel="noopener noreferrer" className="forgot">蹇樿瀵嗙爜锛�</a>
           </Form.Item> : null}
+        </div> : null}
+        {activeKey === 'weixin_scan' ? <div className="form-item-wrap">
+          <div className="form-scan-wrap">
+            <div className="qr-wrap">
+              {scanId ? <QrCode card={{qrWidth: 500, color: '#000000'}} value={`https://cloud.mk9h.cn/mob/mknotice.html?originurl=${window.btoa(window.GLOB.baseurl + 'mob/index.html#/wx/' + scanId)}`}/> : null}
+              {timeout ? <div className="qrcode-out">
+                <RedoOutlined onClick={this.reCode} />
+                {dict['code_expired'] || '浜岀淮鐮佸凡澶辨晥銆�'}
+              </div> : null}
+            </div>
+            <img src={wxicon} alt=""/>{dict['wechat_scan'] || '璇蜂娇鐢ㄥ井淇℃壂涓�鎵櫥褰�'}
+          </div>
+          {prolType ? <Form.Item className="proline">
+            <CheckWrap checked={protocol} onChange={this.changeAgree} prolCont={prolCont} prolType={prolType}/>
+          </Form.Item> : null}
+        </div> : null}
+        {activeKey === 'app_scan' ? <div className="form-item-wrap">
+          <div className="form-scan-wrap">
+            <div className="qr-wrap">
+              {scanId ? <QrCode card={{qrWidth: 500, color: '#000000'}} value={`mkpcscan,${window.GLOB.appkey},${scanId}`}/> : null}
+              {timeout ? <div className="qrcode-out">
+                <RedoOutlined onClick={this.reCode} />
+                {dict['code_expired'] || '浜岀淮鐮佸凡澶辨晥銆�'}
+              </div> : null}
+            </div>
+            {dict['client_scan'] || '璇蜂娇鐢ㄥ鎴风鎵竴鎵櫥褰�'}
+          </div>
+          {prolType ? <Form.Item className="proline">
+            <CheckWrap checked={protocol} onChange={this.changeAgree} prolCont={prolCont} prolType={prolType}/>
+          </Form.Item> : null}
+        </div> : null}
+        <div className={'login-ways ' + (activeKey === 'app_scan' || activeKey === 'weixin_scan' ? 'center' : '')}>
+          {loginWays.map(item => {
+            if (activeKey === item.type) return null
+            if (item.type === 'app_scan' && activeKey !== 'weixin_scan') return null
+            if (item.type === 'weixin_scan' && activeKey !== 'app_scan') return null
+            return (<span key={item.type} onClick={() => this.onChangeTab(item.type)}>{item.label}</span>)
+          })}
         </div>
       </Form>
     )

--
Gitblit v1.8.0