king
2021-08-17 76766991b5e2fd5c7e85fdb1c8323f4dbacb4eb3
2021-08-17
11个文件已修改
525 ■■■■■ 已修改文件
src/api/index.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/breadview/index.jsx 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/options.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.scss 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/loginform.jsx 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -141,7 +141,7 @@
  /**
   * @description 游客登录
   */
  getTouristMsg () {
  getTouristMsg (appid, openid, memberid, scanId) {
    let _SessionUid = localStorage.getItem('SessionUid')
    if (!_SessionUid) { // 手动清除SessionUid时,实时生成
@@ -161,6 +161,14 @@
    param.appkey = window.GLOB.appkey || ''
    if (appid) {
      param.binding_type = 'mk'
      param.thd_party_member_id = memberid
      param.thd_party_openid = openid
      param.thd_party_appid = appid
      param.id = scanId
    }
    let url = '/webapi/dologon/s_visitor_login'
    if (window.GLOB.mainSystemApi) {
      // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
src/components/breadview/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import { BackTop, Breadcrumb, Icon} from 'antd'
import { BackTop, Breadcrumb, Icon, notification} from 'antd'
import moment from 'moment'
import 'moment/locale/zh-cn'
@@ -11,6 +11,7 @@
import mzhCN from '@/locales/zh-CN/main.js'
import menUS from '@/locales/en-US/main.js'
import MKEmitter from '@/utils/events.js'
import { initActionPermission } from '@/store/action'
import Api from '@/api'
import './index.scss'
@@ -43,9 +44,46 @@
    window.GLOB.CacheMap = new Map()
    if (options.sysType === 'local' && window.GLOB.systemType !== 'production') {
      Api.getAppVersion().then(() => {
        MKEmitter.emit('reloadMenuView', tabview.MenuID)
      }, () => {
      let roledefer = new Promise(resolve => {
        Api.getSystemConfig({
          func: 's_Get_TrdMenu_Role',
          edition_type: 'A',
          pro_sys: ''
        }).then(result => {
          if (!result) return
          if (!result.status) {
            notification.error({
              top: 92,
              message: result.message,
              duration: 10
            })
          } else {
            let _permAction = {loaded: true} // 按钮权限
            if (result.UserRoles_Menu) {
              result.UserRoles_Menu.forEach(menu => {
                if (!menu.MenuID) return
                _permAction[menu.MenuID] = true
              })
            }
            this.props.initActionPermission(_permAction)
          }
          resolve()
        })
      })
      // 获取主菜单参数
      let menudefer = new Promise(resolve => {
        Api.getAppVersion().then(() => {
          resolve()
        }, () => {
          resolve()
        })
      })
      Promise.all([roledefer, menudefer]).then(() => {
        MKEmitter.emit('reloadMenuView', tabview.MenuID)
      })
    } else {
@@ -163,8 +201,10 @@
  }
}
const mapDispatchToProps = () => {
  return {}
const mapDispatchToProps = (dispatch) => {
  return {
    initActionPermission: (permAction) => dispatch(initActionPermission(permAction)),
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(BreadView)
src/components/tabview/index.jsx
@@ -2,11 +2,11 @@
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import {Tabs, Icon, BackTop} from 'antd'
import {Tabs, Icon, BackTop, notification} from 'antd'
import moment from 'moment'
import 'moment/locale/zh-cn'
import { modifyTabview, toggleIsiframe } from '@/store/action'
import { modifyTabview, toggleIsiframe, initActionPermission } from '@/store/action'
import asyncComponent from '@/utils/asyncLoadComponent'
import NotFount from '@/components/404'
import options from '@/store/options.js'
@@ -76,9 +76,46 @@
    window.GLOB.CacheMap = new Map()
    if (options.sysType === 'local' && window.GLOB.systemType !== 'production') {
      Api.getAppVersion().then(() => {
        MKEmitter.emit('reloadMenuView', menu.MenuID)
      }, () => {
      let roledefer = new Promise(resolve => {
        Api.getSystemConfig({
          func: 's_Get_TrdMenu_Role',
          edition_type: 'A',
          pro_sys: ''
        }).then(result => {
          if (!result) return
          if (!result.status) {
            notification.error({
              top: 92,
              message: result.message,
              duration: 10
            })
          } else {
            let _permAction = {loaded: true} // 按钮权限
            if (result.UserRoles_Menu) {
              result.UserRoles_Menu.forEach(menu => {
                if (!menu.MenuID) return
                _permAction[menu.MenuID] = true
              })
            }
            this.props.initActionPermission(_permAction)
          }
          resolve()
        })
      })
      // 获取主菜单参数
      let menudefer = new Promise(resolve => {
        Api.getAppVersion().then(() => {
          resolve()
        }, () => {
          resolve()
        })
      })
      Promise.all([roledefer, menudefer]).then(() => {
        MKEmitter.emit('reloadMenuView', menu.MenuID)
      })
    } else {
@@ -277,6 +314,7 @@
const mapDispatchToProps = (dispatch) => {
  return {
    modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)),
    initActionPermission: (permAction) => dispatch(initActionPermission(permAction)),
    toggleIsiframe: (isiframe) => dispatch(toggleIsiframe(isiframe))
  }
}
src/index.js
@@ -120,6 +120,8 @@
    if (localStorage.getItem(_href + 'lang')) {
      sessionStorage.setItem('lang', localStorage.getItem(_href + 'lang'))
    } else {
      sessionStorage.setItem('lang', config.defaultLang !== 'en-US' ? 'zh-CN' : 'en-US')
    }
    let _systemMsg = localStorage.getItem(_href + 'system')
src/menu/components/card/data-card/options.jsx
@@ -1,7 +1,7 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, subtype) {
export default function (wrap, subtype, columns) {
  let appType = sessionStorage.getItem('appType')
  let MenuType = ''
@@ -144,6 +144,16 @@
      forbid: subtype !== 'propcard' || MenuType !== 'billPrint'
    },
    {
      type: 'select',
      field: 'broadcast',
      label: '语音播报',
      initval: wrap.broadcast || '',
      tooltip: '语音播报在移动端app中有效。注:使用语音播报时,数据源不要使用同步查询,添加定时器时,可循环播报',
      required: false,
      options: columns,
      forbid: !columns || appType !== 'mob'
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -38,6 +38,7 @@
    funcType: null,  // 功能类型
    procMode: null,  // 参数方式
    pageTemplate: null,
    appType: sessionStorage.getItem('appType'),
    Ot: null,
    requireOptions: [{
      value: 'notRequired',
@@ -174,6 +175,8 @@
        } else if (_intertype === 'inner') {
          _options.push('innerFunc')
        }
      } else if (_funcType === 'mkBinding' || _funcType === 'mkUnBinding') {
        _options.push('execSuccess', 'execError')
      }
    } else if (_opentype !== 'popview' && _opentype !== 'tab') {
      if (_intertype === 'custom') {
@@ -193,7 +196,13 @@
    }
    if (_Ot !== 'notRequired' && _opentype !== 'excelOut') {
      _options.push('controlField', 'controlVal')
      if (this.state.appType === 'mob') {
        if (_opentype !== 'funcbutton') {
          _options.push('controlField', 'controlVal')
        }
      } else {
        _options.push('controlField', 'controlVal')
      }
    }
    if (_Ot === 'requiredSgl' && ['pop', 'prompt', 'exec'].includes(_opentype)) {
      _options.push('swipe')
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -82,7 +82,11 @@
    }
    if (appType === 'mob') {
      opentypes = opentypes.filter(item => ['pop', 'prompt', 'exec', 'innerpage'].includes(item.value))
      opentypes = opentypes.filter(item => ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton'].includes(item.value))
      funTypes = [
        { value: 'mkBinding', text: '开通扫码登录' },
        { value: 'mkUnBinding', text: '用户解绑' },
      ]
    } else {
      opentypes = opentypes.filter(item => item.value !== 'tab')
    }
src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -380,6 +380,177 @@
      // eslint-disable-next-line
      let func = new Function('data', 'form', 'printer', 'notification', btn.verify.printFunc)
      func(printlist, formdata, btn.verify, notification)
      // 自定义打印示例
      // let defaultPrinter = printer.defaultPrinter || 'lackprinter'
      // let printers = {}
      // if (printer.printerTypeList && printer.printerTypeList.length > 0) {
      //   printer.printerTypeList.forEach(cell => {
      //     if (cell.printer) {
      //       printers[cell.Value] = cell.printer
      //     }
      //   })
      // }
      // let jdList = []
      // let otherList = []
      // data.forEach(item => {
      //   if (item.CustomData) {
      //     item.CustomData = JSON.parse(item.CustomData.replace(/\n/g,"\\n").replace(/\r/g,"\\r"))
      //   }
      //   if (item.PrintData) {
      //     item.PrintData = JSON.parse(item.PrintData.replace(/\n/g,"\\n").replace(/\r/g,"\\r"))
      //     item.PrintData.data = {...form, ...item.PrintData.data}
      //   }
      //   if (!item.PrintData) {
      //     return
      //   }
      //   if (item.PrintData.ectype === 'jdpop') {
      //     jdList.push(item)
      //   } else {
      //     otherList.push(item)
      //   }
      // })
      // if (jdList.length === 0 && otherList.length === 0) {
      //   notification.warning({
      //     top: 92,
      //     message: '无打印数据!',
      //     duration: 5
      //   })
      //   return
      // }
      // let execPrint = (list, linkUrl) => {
      //   let printdata = {}
      //   list.forEach(res => {
      //     let _printer = defaultPrinter
      //     if (res.printType && printers[res.printType]) {
      //       _printer = printers[res.printType]
      //     }
      //     printdata[_printer] = printdata[_printer] || []
      //     printdata[_printer].push(res)
      //   })
      //   let printerList = []
      //   Object.keys(printdata).forEach(printer => {
      //     let _documents = []
      //     printdata[printer].forEach(item => {
      //       let _cell = {
      //         documentID: new Date().getTime().toString(),
      //         contents: []
      //       }
      //       if (item.PrintData) {
      //         _cell.contents.push(item.PrintData)
      //       }
      //       if (item.CustomData) {
      //         _cell.contents.push(item.CustomData)
      //       }
      //       for (let i = 0; i < item.printCount; i++) {
      //         _documents.push(_cell)
      //       }
      //     })
      //     printerList.push({
      //       cmd: 'print',
      //       requestID: '',
      //       version: '',
      //       task: {
      //         taskID: new Date().getTime().toString(),
      //         preview: false,
      //         printer: printer,
      //         documents: _documents
      //       }
      //     })
      //   })
      //   let lackItems = printerList.filter(cell => cell.task.printer === 'lackprinter')[0]
      //   let socket = new WebSocket('ws://' + linkUrl)
      //   // 打开Socket
      //   socket.onopen = () =>{
      //     if (lackItems) {
      //       let request  = {
      //         requestID: '',
      //         version: '',
      //         cmd: 'getPrinters'
      //       }
      //       socket.send(JSON.stringify(request))
      //     } else {
      //       printerList.forEach(cell => {
      //         socket.send(JSON.stringify(cell).replace(/\\r/g,"\r").replace(/\\n/g,"\n"))
      //       })
      //       notification.success({
      //         top: 92,
      //         message: '打印请求已发出。',
      //         duration: 2
      //       })
      //     }
      //   }
      //   // 监听消息
      //   socket.onmessage = (event) => {
      //     let data = ''
      //     if (event.data) {
      //       try {
      //         data = JSON.parse(event.data)
      //       } catch {
      //         notification.warning({
      //           top: 92,
      //           message: event.data,
      //           duration: 10
      //         })
      //         data = ''
      //       }
      //     }
      //     if (data && data.cmd === 'getPrinters' && data.status) {
      //       printerList.forEach(cell => {
      //         if (cell.task.printer === 'lackprinter') {
      //           cell.task.printer = data.defaultPrinter
      //         }
      //         socket.send(JSON.stringify(cell).replace(/\\r/g,"\r").replace(/\\n/g,"\n"))
      //       })
      //       notification.success({
      //         top: 92,
      //         message: '打印请求已发出。',
      //         duration: 2
      //       })
      //     } else if (data && data.message && !data.status) {
      //       notification.warning({
      //         top: 92,
      //         message: data.message,
      //         duration: 10
      //       })
      //     }
      //   }
      //   socket.onerror = () => {
      //     notification.warning({
      //       top: 92,
      //       message: '无法连接到:' + linkUrl,
      //       duration: 10
      //     })
      //   }
      // }
      // if (jdList.length > 0) {
      //   execPrint(jdList, '127.0.0.1:13529')
      // }
      // if (otherList.length > 0) {
      //   execPrint(otherList, '127.0.0.1:13528')
      // }
    } catch (e) {
      console.warn(e)
src/views/login/index.jsx
@@ -198,6 +198,53 @@
    }
  }
  authLogin = (appid, openid, memberid, scanId) => {
    if (options.sysType === 'local' && !window.GLOB.mainSystemApi) { // 业务系统必须设置单点地址
      Modal.warning({
        title: '未设置单点服务器地址,请联系管理员!'
      })
      return
    }
    Api.getTouristMsg(appid, openid, memberid, scanId).then(res => {
      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 || '')
        sessionStorage.setItem('dataM', res.dataM ? 'true' : '')
        sessionStorage.setItem('localDataM', res.dataM ? 'true' : '')
        sessionStorage.setItem('debug', res.debug || '')
        sessionStorage.setItem('role_id', res.role_id || '')
        sessionStorage.setItem('localRole_id', res.role_id || '')
        sessionStorage.removeItem('visitorUserID')
        sessionStorage.removeItem('visitorLoginUID')
        let _history = sessionStorage.getItem('history')
        if (_history) {
          sessionStorage.removeItem('history')
          // 查看是否为其他页面跳转,路径存在时,跳回原页面
          this.props.history.replace(_history)
        } 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
        })
      }
    })
  }
  jsonp(url) {
    return new Promise((resolve, reject) => {
      window.jsonCallBack = (result) => {
@@ -501,14 +548,12 @@
      try {
        loginWays = JSON.parse(window.decodeURIComponent(window.atob(loginWays)))
      } catch {
        localStorage.removeItem(window.location.href.split('#')[0] + 'loginways')
        loginWays = null
      }
      if (loginWays) {
        this.setState({
          loginWays: loginWays
        })
      }
      this.setState({
        loginWays: loginWays
      })
    }
  }
@@ -608,6 +653,7 @@
            isDisabled={this.state.isDisabled}
            changelang={(value) => this.changelang(value)}
            handleSubmit={() => this.handleSubmit()}
            authLogin={this.authLogin}
            wrappedComponentRef={(inst) => this.loginformRef = inst}
          /> : null}
        </div>
src/views/login/index.scss
@@ -210,6 +210,47 @@
  .ant-btn-primary[disabled] {
    color: #fff;
  }
  .form-scan-wrap {
    text-align: center;
    line-height: 45px;
    .qr-wrap {
      position: relative;
      width: 60%;
      padding-top: 60%;
      margin: 0 auto;
      .qrcode-box {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        canvas {
          width: 100%!important;
          height: 100%!important;
        }
      }
      .qrcode-out {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.7);
        padding-top: 30%;
        color: rgba(255, 255, 255, 0.7);
        line-height: 1.5;
        text-align: center;
        .anticon-redo {
          display: block;
          font-size: 24px;
          cursor: pointer;
          color: #ffffff;
        }
      }
    }
  }
}
.sync-cloud-application {
  .ant-modal-body {
src/views/login/loginform.jsx
@@ -1,22 +1,25 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Icon, Input, Button, Checkbox, Select, Modal, message } from 'antd'
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 './index.scss'
const { warning } = Modal
let LoginVerCodeTimer = null
const QrCode = asyncLoadComponent(() => import('@/components/qrcode'))
class LoginTabForm extends Component {
  static propTpyes = {
    isDisabled: PropTypes.bool,
    changelang: PropTypes.func,
    handleSubmit: PropTypes.func,
    authLogin: PropTypes.func,
    dict: PropTypes.object,
    auth: PropTypes.bool,
    authError: PropTypes.string,
@@ -29,14 +32,19 @@
  state = {
    activeKey: 'uname_pwd',
    scanId: '',
    username: '',
    password: '',
    remember: true,
    delay: null,
    loginWays: [],
    smsId: '',
    verdisabled: false
    verdisabled: false,
    timeout: false
  }
  timer = null
  splitTime = 0
  UNSAFE_componentWillMount () {
    const { loginWays } = this.props
@@ -55,36 +63,64 @@
        _loginWays.push(item)
      } else if (item.type === 'uname_pwd') {
        _loginWays.push(item)
      } else if (item.type === 'app_scan') {
        _loginWays.push(item)
      }
    })
    let activeKey = _loginWays[0].type
    this.setState({
      smsId: smsId,
      loginWays: _loginWays,
      activeKey: _loginWays[0].type,
      activeKey,
      scanId: activeKey === 'app_scan' ? Utils.getuuid() : '',
      timeout: false,
      remember
    })
    if (activeKey === 'app_scan') {
      this.splitTime = 0
      this.timer = setTimeout(() => {
        this.checkResult()
      }, 10000)
    }
  }
  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)
        }
      })
  checkResult = () => {
    const { scanId } = this.state
      this.setState({
        smsId: smsId,
        loginWays: _loginWays,
        activeKey: _loginWays[0].type
      })
    this.splitTime += 10000
    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) {
        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 = () => {
@@ -183,7 +219,29 @@
  }
  onChangeTab = (activeKey) => {
    this.setState({activeKey})
    this.setState({activeKey, scanId: activeKey === 'app_scan' ? Utils.getuuid() : ''})
    if (this.state.activeKey === 'app_scan') {
      this.timer && clearTimeout(this.timer)
    }
    if (activeKey === 'app_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 = () => {
@@ -297,7 +355,7 @@
  render() {
    const { getFieldDecorator } = this.props.form
    const { activeKey, verdisabled, delay, loginWays, remember } = this.state
    const { activeKey, verdisabled, delay, loginWays, remember, scanId, timeout } = this.state
    return (
      <Form className="login-form" id="login-form" onSubmit={this.handleSubmit}>
@@ -368,7 +426,7 @@
              initialValue: remember,
            })(<Checkbox onChange={this.rememberChange}>{this.props.dict['login.remember']}</Checkbox>)}
          </Form.Item> : null}
          {this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right">
          {activeKey !== 'app_scan' && this.props.langList && this.props.langList.length > 0 ? <Form.Item className="minline right">
            {getFieldDecorator('lang', {
              initialValue: this.props.lang,
            })(
@@ -387,6 +445,16 @@
              {this.props.dict['login.submit']}
            </Button>
          </Form.Item> : null}
          {activeKey === 'app_scan' ? <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">
                <Icon onClick={this.reCode} type="redo" />
                二维码已失效。
              </div> : null}
            </div>
            请使用客户端扫一扫登录
          </div> : null}
          {options.sysType === 'cloud' && options.cdomain.indexOf('mk9h') > -1 ? <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>