king
2020-04-01 56c0d6e2f83d72f622744fea76fdc64b09e30f1d
2020-04-01
11个文件已修改
1个文件已添加
419 ■■■■ 已修改文件
public/index.html 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/options.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/login.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/login.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.scss 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 196 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.scss 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/logincloudform.jsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/loginform.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html
@@ -5,8 +5,8 @@
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.png" />
    <!-- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.png" /> -->
    <script src="%PUBLIC_URL%/options.js"></script>
    <title></title>
  </head>
public/options.js
@@ -3,15 +3,16 @@
  appId: '201912040924165801464FF1788654BC5AC73',
  appkey: '20191106103859640976D6E924E464D029CF0',
  mainSystemApi: 'http://cloud.mk9h.cn/webapi/dostars',
  title: '',
  platTitle: '',
  platName: '',
  logo: '',
  favicon: '',
  loginlogo: '',
  mainlogo: '',
  bgImage: '',
  copyRight: '',
  icp: '',
  bgColor: '',
  ICP: '',
  lineColor: '',
  website: '',
  webSite: '',
  doclogo: '',
  style: ''
}
src/api/index.js
@@ -61,33 +61,17 @@
      // axios.defaults.baseURL = 'http://127.0.0.1:8888'
    }
  }
  /**
   * @description 系统授权
   */
  systemauth (appId, timestamp) {
    return axios({
      url: '/webapi/dostar',
      data: {
        rduri: 'http://minkesoft.com/mksepc/webapi/dostar',
        func: 'sEmpowerCloud_Get_LinkUrl',
        userid: '',
        AppID: appId,
        TimeStamp: timestamp
      }
    })
  }
  
  /**
   * @description 登录系统
   * @description 使用dostar接口,跳过验证
   * @param {Object} param 查询及提交参数
   */
  loginsystem (username, password) {
  dostarInterface (param) {
    param.userid = ''
    return axios({
      url: '/zh-CN/Home/LoginAndRedirect',
      data: {
        Username: username,
        Password: password
      }
      url: '/webapi/dostar',
      data: param
    })
  }
@@ -99,14 +83,16 @@
      // func: 'webapi_login',
      UserName: username,
      Password: password,
      systemType: options.systemType,
      Type: 'X'
    }
    param.Password = Utils.formatOptions(param.Password)
    param.appkey = window.GLOB.appkey || ''
    if (isCloud && options.cloudLoginApi) {
      param.rduri = options.cloudLoginApi
    } else if (window.GLOB.mainSystemApi) {
    } else if (!isCloud && window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
    }
src/components/header/index.jsx
@@ -20,7 +20,6 @@
import zhCN from '@/locales/zh-CN/header.js'
import enUS from '@/locales/en-US/header.js'
import Utils from '@/utils/utils.js'
import logourl from '@/assets/img/main-logo.png'
import avatar from '@/assets/img/avatar.jpg'
import Resetpwd from './resetpwd'
import LoginForm from './loginform'
@@ -43,7 +42,7 @@
    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
    confirmLoading: false,
    userName: sessionStorage.getItem('User_Name'),
    logourl: window.GLOB.mainlogo || logourl,
    logourl: window.GLOB.mainlogo,
    loginVisible: false,
    loginLoading: false,
    avatar: avatar,
src/index.js
@@ -24,7 +24,37 @@
window.GLOB = window.GLOB || {}
document.title = window.GLOB.title || 'MinkeSoft'
let _systemMsg = localStorage.getItem(window.location.href.split('#')[0] + 'system')
if (_systemMsg) {
  try {
    _systemMsg = JSON.parse(window.decodeURIComponent(window.atob(_systemMsg)))
    window.GLOB.platTitle = _systemMsg.platTitle || window.GLOB.platTitle
    window.GLOB.platName = _systemMsg.platName || window.GLOB.platName
    window.GLOB.favicon = _systemMsg.favicon || window.GLOB.favicon
    window.GLOB.loginlogo = _systemMsg.loginlogo || window.GLOB.loginlogo
    window.GLOB.copyRight = _systemMsg.copyRight || window.GLOB.copyRight
    window.GLOB.ICP = _systemMsg.ICP || window.GLOB.ICP
    window.GLOB.mainlogo = _systemMsg.mainlogo || window.GLOB.mainlogo
    window.GLOB.doclogo = _systemMsg.doclogo || window.GLOB.doclogo
    window.GLOB.webSite = _systemMsg.webSite || window.GLOB.webSite
    if (window.GLOB.favicon) {
      let link = document.querySelector("link[rel*='icon']") || document.createElement('link')
      link.type = 'image/x-icon'
      link.rel = 'shortcut icon'
      link.href = window.GLOB.favicon
      document.getElementsByTagName('head')[0].appendChild(link)
    }
  } catch {
    console.warn('Parse Failure')
  }
}
document.title = window.GLOB.platTitle
const option = {
  white: 'mk-white'
src/locales/en-US/login.js
@@ -8,5 +8,6 @@
  'login.password.empty': 'Please input your Password!',
  'login.remember': 'Remember me',
  'login.submit': 'Log in',
  'login.copyright': 'Copyrights by'
  'login.copyright': 'Copyrights by',
  'login.sync.cloud': '同步云端应用'
}
src/locales/zh-CN/login.js
@@ -8,5 +8,6 @@
  'login.password.empty': '请输入密码!',
  'login.remember': '记住密码',
  'login.submit': '登录',
  'login.copyright': '所有相关版权归'
  'login.copyright': '所有相关版权归',
  'login.sync.cloud': '同步云端应用'
}
src/tabviews/zshare/normalTable/index.scss
@@ -123,6 +123,26 @@
            background: lightcoral;
          }
        }
        .orange {
          .content {
            color: orange;
          }
        }
        .orangebg {
          .background {
            background: lightsalmon;
          }
        }
        .green {
          .content {
            color: green;
          }
        }
        .greenbg {
          .background {
            background: lightgreen;
          }
        }
      }
      .ant-table-tbody > tr > td .content {
        p {
src/views/login/index.jsx
@@ -1,5 +1,5 @@
import React, {Component} from 'react'
import { message } from 'antd'
import { message, Modal } from 'antd'
import md5 from 'md5'
import moment from 'moment'
import Api from '@/api'
@@ -9,11 +9,10 @@
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncLoadComponent from '@/utils/asyncLoadComponent'
import logourl from '@/assets/img/login-logo.png'
import loginbg from '@/assets/img/loginbg.jpg'
import './index.scss'
const LoginForm = asyncLoadComponent(() => import('./loginform'))
const LoginCloudForm = asyncLoadComponent(() => import('./logincloudform'))
const Action = asyncComponent(() => import('@/tabviews/zshare/actionList'))
const iszhCN = !localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN'
@@ -23,15 +22,17 @@
    dict: iszhCN ? zhCN : enUS,
    isDisabled: false,
    auth: false,
    logo: window.GLOB.logo || logourl,
    bgImage: window.GLOB.bgImage || loginbg,
    platName: window.GLOB.platName || '明科商业智能开放平台',
    copyright: window.GLOB.copyRight || 'Copyright©2017    所有相关版权归    北京明科普华信息技术有限公司',
    ICP: window.GLOB.icp || 'ICP备案: 京ICP备12007830号',
    bgColor: window.GLOB.bgColor || '#000000',
    lineColor: window.GLOB.lineColor || '#1890ff',
    website: window.GLOB.website || (!window.GLOB.copyRight && 'http://minkesoft.com'),
    loaded: false
    loginlogo: window.GLOB.loginlogo,
    bgImage: window.GLOB.bgImage,
    platName: window.GLOB.platName,
    copyRight: window.GLOB.copyRight,
    ICP: window.GLOB.ICP,
    lineColor: window.GLOB.lineColor,
    webSite: window.GLOB.webSite,
    langList: [],
    loaded: false,
    syncApp: false,
    syncing: false
  }
  changelang (item) {
@@ -67,7 +68,7 @@
      sessionStorage.setItem('Full_Name', res.FullName)
      sessionStorage.setItem('avatar', res.icon || '')
      
      localStorage.setItem('lang', param.lang)
      localStorage.setItem('lang', param.lang || 'zh-CN')
      let _url = window.location.href.split('#')[0]
@@ -83,6 +84,13 @@
      } else {
        this.props.history.replace('/main')
      }
    } else if (res.ErrCode === 'Need_Get_Appkey' && options.systemType === 'SSO') {
      message.warning('应用尚未创建,请向云端同步应用!')
      this.setState({
        isDisabled: false,
        syncApp: true
      })
    } else {
      message.warning(res.message)
      this.setState({
@@ -100,7 +108,15 @@
    }
    let str = md5('MK19' + _appId + timeStamp)
    Api.systemauth(_appId, timeStamp).then(res => {
    let param = {
      rduri: 'http://minkesoft.com/mksepc/webapi/dostar',
      func: 'sEmpowerCloud_Get_LinkUrl',
      AppID: _appId,
      TimeStamp: timeStamp
    }
    Api.dostarInterface(param).then(res => {
      if (res.status) {
        if (res.EPC === str) {
          let box = []
@@ -131,26 +147,137 @@
      })
    }
    // let link = document.querySelector("link[rel*='icon']") || document.createElement('link')
    // link.type = 'image/x-icon'
    // link.rel = 'shortcut icon'
    // link.href = 'http://www.stackoverflow.com/favicon.ico'
    // document.getElementsByTagName('head')[0].appendChild(link)
    // 获取系统信息
    let _param = {
      func: 's_Get_style',
      Appkey: window.GLOB.appkey || '',
      TypeCharOne: 'PC',
      LText: `select '${window.GLOB.appkey}'`,
    }
    _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 => {
      if (res.status) {
        let _url = window.location.href.split('#')[0] + 'system'
        let systemMsg = {
          favicon: res.titlelogo || '',
          platTitle: res.titleName || '',
          platName: res.SysName || '',
          bgImage: res.Banner || '',
          loginlogo: res.loginlogo || '',
          copyRight: res.CopyRightYear && res.CopyRightOrg ? `Copyright©${res.CopyRightYear}    所有相关版权归    ${res.CopyRightOrg}` : '',
          ICP: res.ICP || '',
          mainlogo: res.indexlogo || '',
          doclogo: res.doclogo || '',
          webSite: res.WebSite || ''
        }
        try {
          localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify(systemMsg))))
        } catch {
          localStorage.removeItem(_url)
        }
        this.setState({
          langList: res.lang_data || [],
          ...systemMsg
        })
        if (res.titlelogo && window.GLOB.favicon !== res.titlelogo) {
          let link = document.querySelector("link[rel*='icon']") || document.createElement('link')
          link.type = 'image/x-icon'
          link.rel = 'shortcut icon'
          link.href = res.titlelogo
          document.getElementsByTagName('head')[0].appendChild(link)
        }
      } else {
        message.warning(res.message)
      }
    })
  }
  syncSubmit = () => {
    this.setState({
      syncing: true
    })
    let param = {
      func: 's_get_app_from_cloud',
      UserName: '',
      Password: '',
      systemType: options.systemType,
      Type: 'X',
      debug: 'Y'
    }
    param.appkey = window.GLOB.appkey || ''
    if (options.cloudServiceApi) {
      param.rduri = options.cloudServiceApi.replace('dostars', 'dostar')
    }
    this.logincloudRef.handleConfirm().then(result => {
      param.UserName = result.cloudusername
      param.Password = result.cloudpassword
      param.Password = Utils.formatOptions(param.Password)
      Api.dostarInterface(param).then(res => {
        if (res.status) {
          let _param = {
            func: 's_sDataDictb_TBBack',
            LTextOut: res.LTextOut,
            lid: res.Lid,
            Appkey: window.GLOB.appkey || ''
          }
          Api.dostarInterface(_param).then(response => {
            if (response.status) {
              message.success('应用创建成功。')
              this.setState({
                syncing: false,
                syncApp: false
              })
            } else {
              this.setState({
                syncing: false
              })
              message.warning(response.message)
            }
          })
        } else {
          this.setState({
            syncing: false
          })
          message.warning(res.message)
        }
      })
    })
  }
  render () {
    const { lineColor, bgImage, loginlogo, copyRight, webSite, ICP } = this.state
    return (
      <div className="login-container" style={{backgroundImage: 'url(' + this.state.bgImage + ')', backgroundColor: this.state.bgColor}}>
        <div className="logo" style={{borderColor: this.state.lineColor}}>
          <img src={this.state.logo} alt=""/>
      <div className="login-container" style={bgImage ? {backgroundImage: 'url(' + bgImage + ')'} : {}}>
        <div className="logo" style={lineColor ? {borderColor: lineColor} : {}}>
          {loginlogo ? <img src={loginlogo} alt=""/> : null}
        </div>
        <div className="login-middle" style={{borderColor: this.state.lineColor}}>
        <div className="login-middle" style={lineColor ? {borderColor: lineColor} : {}}>
          <LoginForm
            platName={this.state.platName}
            dict={this.state.dict}
            auth={this.state.auth}
            lang={this.state.selectedlang}
            langList={this.state.langList}
            isDisabled={this.state.isDisabled}
            changelang={(value) => this.changelang(value)}
            handleSubmit={() => this.handleSubmit()}
@@ -159,12 +286,27 @@
          />
        </div>
        <div className="login-bottom">
          {this.state.website ?
            <a target="blank" href={this.state.website} dangerouslySetInnerHTML={{ __html: this.state.copyright.replace(/\s/ig, '&nbsp;') }}></a> :
            <p dangerouslySetInnerHTML={{ __html: this.state.copyright.replace(/\s/ig, '&nbsp;') }}></p>
          {webSite && copyRight ?
            <a target="blank" href={webSite} dangerouslySetInnerHTML={{ __html: copyRight.replace(/\s/ig, '&nbsp;') }}></a> :
            <p dangerouslySetInnerHTML={{ __html: copyRight ? copyRight.replace(/\s/ig, '&nbsp;') : '' }}></p>
          }
          <p dangerouslySetInnerHTML={{ __html: this.state.ICP.replace(/\s/ig, '&nbsp;') }}></p>
          {ICP ? <p dangerouslySetInnerHTML={{ __html: ICP.replace(/\s/ig, '&nbsp;') }}></p> : null}
        </div>
        {/* 编辑状态登录 */}
        <Modal
          title={this.state.dict['login.sync.cloud']}
          okText={this.state.dict['login.auth.ok']}
          cancelText={this.state.dict['login.auth.cancel']}
          visible={this.state.syncApp}
          onOk={this.syncSubmit}
          className="sync-cloud-application"
          width={'430px'}
          confirmLoading={this.state.syncing}
          onCancel={() => {this.setState({ syncApp: false, syncing: false })}}
          destroyOnClose
        >
          <LoginCloudForm handleSubmit={() => this.syncSubmit()} wrappedComponentRef={(inst) => this.logincloudRef = inst}/>
        </Modal>
        {this.state.loaded ? <div style={{position: 'fixed', bottom: '-300px'}}>
          <Action
            BID=""
src/views/login/index.scss
@@ -1,6 +1,7 @@
.login-container {
  height: 100vh;
  min-height: 600px;
  background-color: #000000;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
@@ -8,17 +9,18 @@
    height: 100px;
    padding-top: 30px;
    line-height: 80px;
    border-bottom: 2px solid #06b4f7;
    border-bottom: 2px solid #1890ff;
    img {
      max-height: 100%;
    }
  }
  .login-middle {
    position: relative;
    height: calc(100vh - 194px);
    min-height: 420px;
    background-size: cover;
    background-position: center center;
    border-bottom: 2px solid #06b4f7;
    border-bottom: 2px solid #1890ff;
    .login-form {
      float: right;
@@ -93,6 +95,11 @@
        color: #1890ff;
      }
    }
    .login-sync-button {
      position: absolute;
      bottom: 10px;
      left: 20px;
    }
  }
  .login-bottom {
    text-align: center;
@@ -113,6 +120,11 @@
    border-color: #40a9ff;
  }
}
.sync-cloud-application {
  .ant-modal-body {
    min-height: 176px;
  }
}
.ant-message {
  top: 50px;
  z-index: 1080;
src/views/login/logincloudform.jsx
New file
@@ -0,0 +1,87 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Icon, Input } from 'antd'
import zhCN from '@/locales/zh-CN/login.js'
import enUS from '@/locales/en-US/login.js'
import './index.scss'
class HeaderLoginForm extends Component {
  static propTpyes = {
    handleSubmit: PropTypes.func
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  handleSubmit = (e, key) => {
    e.preventDefault()
    if (e.target.value) {
      if (!this.props.form.getFieldValue(key)) {
        const input = document.getElementById(key)
        if (input) {
          input.focus()
        }
        return
      }
      this.props.handleSubmit()
    } else {
      this.handleConfirm()
    }
  }
  componentDidMount () {
    const input = document.getElementById('username')
    if (input) {
      input.focus()
    }
  }
  render() {
    const { getFieldDecorator } = this.props.form
    return (
      <Form style={{margin: '0px 10px'}}>
        <Form.Item>
          {getFieldDecorator('cloudusername', {
            rules: [{ required: true, message: this.state.dict['login.username.empty'] }],
            initialValue: '',
          })(
            <Input
              prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
              placeholder={this.state.dict['login.username']}
              autoComplete="off"
              onPressEnter={(e) => {this.handleSubmit(e, 'cloudpassword')}}
            />
          )}
        </Form.Item>
        <Form.Item>
          {getFieldDecorator('cloudpassword', {
            initialValue: '',
            rules: [
              {
                required: true,
                message: this.state.dict['login.password.empty'],
              }
            ]
          })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'cloudusername')}} placeholder={this.state.dict['login.password']} prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
        </Form.Item>
      </Form>
    )
  }
}
export default Form.create()(HeaderLoginForm)
src/views/login/loginform.jsx
@@ -14,6 +14,7 @@
    dict: PropTypes.object,
    auth: PropTypes.bool,
    lang: PropTypes.string,
    langList: PropTypes.array,
    platName: PropTypes.string
  }
@@ -135,7 +136,7 @@
            initialValue: true,
          })(<Checkbox>{this.props.dict['login.remember']}</Checkbox>)}
        </Form.Item>
        <Form.Item className="minline right">
        {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right">
          {getFieldDecorator('lang', {
            initialValue: this.props.lang,
          })(
@@ -143,11 +144,12 @@
              onChange={(value) => {this.changelang(value)}}
              getPopupContainer={() => document.getElementById('login-form')}
            >
              <Select.Option value="zh-CN">中文简体</Select.Option>
              <Select.Option value="en-US">English</Select.Option>
              {this.props.langList.map((item, index) => {
                return <Select.Option key={index} value={item.Lang}>{item.LangName}</Select.Option>
              })}
            </Select>
          )}
        </Form.Item>
        </Form.Item> : null}
        <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']}