king
2023-02-01 61ab22d7b6be46c00e8813b00b2352a52cc252f3
2023-02-01
15个文件已修改
1个文件已删除
3个文件已添加
1012 ■■■■■ 已修改文件
src/components/header/index.jsx 95 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/resetpwd/index.jsx 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/resetPassword/index.jsx 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/resetPassword/index.scss 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/resetPassword/resetpwd/index.jsx 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/login.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/main.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/login.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/main.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/options.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontroller/styleInput/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/styleInput/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/styleInput/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/balcony/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/index.jsx 87 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/loginform.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx
@@ -3,7 +3,6 @@
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import moment from 'moment'
import { Dropdown, Menu, Modal, notification, Switch, Input } from 'antd'
import { SearchOutlined, DownOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
@@ -16,15 +15,13 @@
import Api from '@/api'
import MKEmitter from '@/utils/events.js'
import options from '@/store/options.js'
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import Utils from '@/utils/utils.js'
import avatar from '@/assets/img/avatar.jpg'
import './index.scss'
const { confirm } = Modal
const { Search } = Input
const Resetpwd = asyncComponent(() => import('./resetpwd'))
const Resetpwd = asyncComponent(() => import('@/components/resetPassword'))
const LoginForm = asyncComponent(() => import('./loginform'))
class Header extends Component {
@@ -33,9 +30,6 @@
  }
  state = {
    menulist: null, // 一级菜单
    visible: false, // 修改密码模态框
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    confirmLoading: false,
    userName: '',
    fullName: '',
    logourl: window.GLOB.mainlogo,
@@ -57,60 +51,12 @@
  changePassword = () => {
    // 点击修改密码,显示弹窗
    this.setState({
      visible: true
    })
  }
  resetPwdSubmit = () => {
    if (!this.formRef) return
    this.formRef.handleConfirm().then(res => {
      this.setState({
        confirmLoading: true
      })
      let _param = {
        func: 's_PwdUpt',
        LText: `select '${res.originpwd}','${res.password}'`
      }
      _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')          // 时间戳
      _param.LText = Utils.formatOptions(_param.LText)                   // 关键字符替换,base64加密
      _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)   // md5密钥
      Api.getSystemConfig(_param).then(result => {
        this.setState({
          visible: !result.status,
          confirmLoading: false
        })
        if (result.status) {
          notification.success({
            top: 92,
            message: '修改成功,请重新登录。',
            duration: 2
          })
          setTimeout(() => {
            sessionStorage.clear()
            this.props.logout()
            this.props.history.replace('/login')
          }, 2000)
        } else {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
        }
      })
    }, () => {})
  }
  handleCancel = () => {
    // 取消时关闭修改密码模态框,清空表单数据
    this.setState({
      visible: false
    MKEmitter.emit('resetpassword', () => {
      setTimeout(() => {
        sessionStorage.clear()
        this.props.logout()
        this.props.history.replace('/login')
      }, 2000)
    })
  }
@@ -118,7 +64,7 @@
    // 退出登录
    let _this = this
    confirm({
      title: this.state.dict['main.logout.hint'],
      title: '您确定要退出吗?',
      content: '',
      onOk() {
        sessionStorage.clear()
@@ -610,23 +556,23 @@
    const menu = (
      <Menu className="header-dropdown">
        {debug && <Menu.Item key="switch">
          {this.state.dict['main.edit']}
          编辑
          <Switch size="small" style={{marginLeft: '7px'}} checked={false} onChange={this.changeEditState} />
        </Menu.Item>}
        <Menu.Item key="password" onClick={this.changePassword}>{this.state.dict['main.password']}</Menu.Item>
        <Menu.Item key="password" onClick={this.changePassword}>修改密码</Menu.Item>
        {this.state.systems.length ? <Menu.SubMenu style={{minWidth: '110px'}} title="切换系统">
          {this.state.systems.map((system, index) => (
            <Menu.Item style={{minWidth: '100px', lineHeight: '30px'}} key={'sub' + index} onClick={() => {this.changeSystem(system)}}> {system.AppName} </Menu.Item>
          ))}
        </Menu.SubMenu> : null}
        <Menu.Item key="doc" onClick={this.gotoDoc}>{this.state.dict['main.doc']}</Menu.Item>
        <Menu.Item key="doc" onClick={this.gotoDoc}>文档中心</Menu.Item>
        <Menu.Item key="verup" onClick={this.verup}>
          页面更新
        </Menu.Item>
        {appVersion ? <Menu.Item key="version" onClick={this.about}>
          关于
        </Menu.Item> : null}
        <Menu.Item key="logout" onClick={this.logout}>{this.state.dict['main.logout']}</Menu.Item>
        <Menu.Item key="logout" onClick={this.logout}>退出</Menu.Item>
      </Menu>
    )
@@ -779,29 +725,20 @@
            </span>
          </div>
        </Dropdown>
        {/* 修改密码 */}
        <Modal
          title={this.state.dict['main.password']}
          visible={this.state.visible}
          onOk={this.resetPwdSubmit}
          confirmLoading={this.state.confirmLoading}
          onCancel={this.handleCancel}
          destroyOnClose
        >
          <Resetpwd dict={this.state.dict} wrappedComponentRef={(inst) => this.formRef = inst} resetPwdSubmit={this.resetPwdSubmit}/>
        </Modal>
        {/* 编辑状态登录 */}
        <Modal
          title={this.state.dict['main.login.develop']}
          title="登录开发机"
          visible={this.state.loginVisible}
          onOk={this.loginSubmit}
          width={'430px'}
          confirmLoading={this.state.loginLoading}
          onCancel={() => {this.setState({ loginVisible: false, loginLoading: false })}}
          destroyOnClose
        >
          >
          <LoginForm handleSubmit={() => this.loginSubmit()} wrappedComponentRef={(inst) => this.loginRef = inst}/>
        </Modal>
        {/* 修改密码 */}
        <Resetpwd />
      </header>
    )
  }
src/components/header/resetpwd/index.jsx
File was deleted
src/components/resetPassword/index.jsx
New file
@@ -0,0 +1,182 @@
import React, {Component} from 'react'
import { is, fromJS } from 'immutable'
import { Modal, notification } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import Resetpwd from './resetpwd'
import MKEmitter from '@/utils/events.js'
import './index.scss'
class ResetPassword extends Component {
  state = {
    visible: false,
    loading: false,
    type: 'account',
    okText: '确定',
    smsId: '',
    mob: '',
    code: ''
  }
  callback = null
  componentDidMount() {
    MKEmitter.addListener('resetpassword', this.resetpassword)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  componentWillUnmount() {
    MKEmitter.removeListener('resetpassword', this.resetpassword)
  }
  resetpassword = (callback) => {
    this.callback = callback
    this.setState({
      visible: true,
      loading: false,
      type: 'account',
      okText: '确定',
      mob: '',
      code: '',
      smsId: sessionStorage.getItem('mk_sms_id') || ''
    })
  }
  resetPwdSubmit = () => {
    const { type } = this.state
    if (type === 'account') {
      this.formRef.handleConfirm().then(res => {
        this.setState({
          loading: true
        })
        let _param = {
          func: 's_PwdUpt',
          LText: `select '${res.originpwd}','${res.password}'`
        }
        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')          // 时间戳
        _param.LText = Utils.formatOptions(_param.LText)                   // 关键字符替换,base64加密
        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)   // md5密钥
        Api.getSystemConfig(_param).then(result => {
          if (result.status) {
            this.setState({
              visible: false,
              loading: false
            })
            notification.success({
              top: 92,
              message: '修改成功,请重新登录。',
              duration: 2
            })
            this.callback && this.callback()
          } else {
            this.setState({
              loading: false
            })
            notification.warning({
              top: 92,
              message: result.message,
              duration: 5
            })
          }
        })
      }, () => {})
    } else if (type === 'mob') {
      this.formRef.handleConfirm().then(res => {
        if (!/^1[3456789]\d{9}$/.test(res.phone)) {
          notification.warning({
            top: 92,
            message: '手机号格式错误,请重填!',
            duration: 5
          })
          return
        }
        this.setState({
          mob: res.phone,
          type: 'code'
        })
      }, () => {})
    } else if (type === 'code') {
      this.formRef.handleConfirm().then(res => {
        this.setState({
          code: res.vercode,
          type: 'phonepwd',
          okText: '确定'
        })
      }, () => {})
    } else if (type === 'phonepwd') {
      this.formRef.handleConfirm().then(res => {
        this.setState({
          loading: true
        })
        let _param = {
          func: 's_PwdUpt',
          LText: `select '','${res.password}'`,
          mob: this.state.mob,
          check_code: this.state.code
        }
        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')          // 时间戳
        _param.LText = Utils.formatOptions(_param.LText)                   // 关键字符替换,base64加密
        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)   // md5密钥
        Api.getSystemConfig(_param).then(result => {
          if (result.status) {
            this.setState({
              visible: false,
              loading: false
            })
            notification.success({
              top: 92,
              message: '修改成功,请重新登录。',
              duration: 2
            })
            this.callback && this.callback()
          } else {
            this.setState({
              loading: false
            })
            notification.warning({
              top: 92,
              message: result.message,
              duration: 5
            })
          }
        })
      }, () => {})
    }
  }
  render() {
    const { visible, loading, okText, type, mob, smsId } = this.state
    return (
      <Modal
        title="修改密码"
        wrapClassName="reset-password-modal"
        visible={visible}
        maskClosable={false}
        onOk={this.resetPwdSubmit}
        onCancel={() => { this.setState({ visible: false })}}
        okText={okText}
        confirmLoading={loading}
        destroyOnClose
      >
        <Resetpwd type={type} mob={mob} smsId={smsId} wrappedComponentRef={(inst) => this.formRef = inst} resetPwdSubmit={this.resetPwdSubmit}/>
        {type === 'account' && smsId ? <div className="forget-pwd"><span onClick={() => this.setState({type: 'mob', okText: '下一步'})}>忘记密码?</span></div> : null}
      </Modal>
    )
  }
}
export default ResetPassword
src/components/resetPassword/index.scss
New file
@@ -0,0 +1,22 @@
.reset-password-modal {
  .ant-modal {
    top: 70px;
  }
  .ant-modal-body {
    min-height: 150px;
    .forget-pwd {
      text-align: right;
      padding-right: 40px;
      color: #1890ff;
      span {
        cursor: pointer;
      }
    }
    .vercode-line {
      .ant-form-item-control-wrapper {
        margin-left: 8.3%;
      }
    }
  }
}
src/components/resetPassword/resetpwd/index.jsx
New file
@@ -0,0 +1,317 @@
import React, {Component} from 'react'
import { Form, Input, Button, message } from 'antd'
import moment from 'moment'
import md5 from 'md5'
import Api from '@/api'
class Resetpwd extends Component {
  state = {
    confirmDirty: false,
    autoCompleteResult: [],
    level: localStorage.getItem(window.location.href.split('#')[0] + 'pwdlevel') || ''
  }
  LoginTimer = null
  onEnterSubmit = (e) => {
    // 表单回车提交
    if (e.key !== 'Enter') return
    if (!this.props.form.getFieldValue('originpwd')) {
      this.focusInput('originpwd')
    } else if (!this.props.form.getFieldValue('password')) {
      this.focusInput('password')
    } else if (!this.props.form.getFieldValue('confirm')) {
      this.focusInput('confirm')
    } else {
      this.props.resetPwdSubmit()
    }
  }
  focusInput = (selectId) => {
    let _form = document.getElementById('reset-password-form')
    let _inputs = _form.getElementsByTagName('input')
    _inputs = [..._inputs]
    _inputs.forEach(input => {
      if (!input || input.id !== selectId) return
      if (input.focus) {
        input.focus()
      }
    })
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  handleConfirmBlur = e => {
    const { value } = e.target
    this.setState({ confirmDirty: this.state.confirmDirty || !!value })
  }
  compareToFirstPassword = (rule, value, callback) => {
    const { form } = this.props
    if (value && value !== form.getFieldValue('password')) {
      callback('两次输入密码不一致!')
    } else {
      callback()
    }
  }
  validateToNextPassword = (rule, value, callback) => {
    const { form } = this.props
    const { level } = this.state
    if (value && this.state.confirmDirty) {
      form.validateFields(['confirm'], { force: true })
    }
    if (level === 'letter_num' && value && /^[0-9a-zA-Z!@#$%^&*()_]*$/.test(value) && /^([^0-9]*|[^a-zA-Z]*)$/.test(value)) {
      callback('密码中必须含有数字和字母。')
    } else if ((level === 'char_num' || level === 'char_num_90' || level === 'char_num_90_sms') && value && /^[0-9a-zA-Z!@#$%^&*()_]*$/.test(value) && /^([^0-9]*|[^a-zA-Z]*|[^!@#$%^&*()_]*)$/.test(value)) {
      callback('密码中必须含有数字、字母和特殊字符。')
    } else {
      callback()
    }
  }
  getvercode = () => {
    const { mob, smsId } = this.props
    let _param = {
      func: 'mes_sms_send_code_sso',
      send_type: 'reset_pwd',
      mob: mob,
      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') || ''
    Api.getSystemConfig(_param).then(res => {
      if (!res.status || !res.n_id) {
        message.warning(res.message || '验证码获取失败!')
        return
      }
      let param = {
        func: 'MSN_sms_send_code',
        send_type: 'reset_pwd',
        mob: mob,
        timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
        ID: smsId,
        n_id: res.n_id
      }
      param.LText = md5(`${mob}mingke${window.GLOB.appkey}${param.timestamp}`)
      param.secretkey = md5(`${param.LText}mingke${param.timestamp}`)
      param.rduri = 'https://sso.mk9h.cn/webapi/dostars'
      param.userid = 'bh0bapabtd45epsgra79segbch6c1ibk'
      param.LoginUID = 'bh0bapabtd45epsgra79segbch6c1ibk'
      this.setState({
        verdisabled: true,
        delay: 60
      })
      this.LoginTimer = setTimeout(this.resetVerCodeDelay, 1000)
      Api.genericInterface(param).then(res => {
        if (res.status) {
        } else {
          clearTimeout(this.LoginTimer)
          this.setState({
            verdisabled: false,
            delay: null
          })
          message.warning(res.message)
        }
      }, () => {
        clearTimeout(this.LoginTimer)
        this.setState({
          verdisabled: false,
          delay: null
        })
      })
    })
  }
  resetVerCodeDelay = () => {
    const { delay } = this.state
    if (delay && delay > 1) {
      this.setState({delay: delay - 1})
      this.LoginTimer = setTimeout(this.resetVerCodeDelay, 1000)
    } else {
      this.setState({
        verdisabled: false,
        delay: null
      })
    }
  }
  render() {
    const { type } = this.props
    const { getFieldDecorator } = this.props.form
    const { level, delay, verdisabled } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    let rules = []
    if (level) {
      rules.push({
        min: 8,
        message: '密码长度不可小于8位!'
      })
    }
    return (
      <>
        {type === 'account' ? <Form {...formItemLayout} onKeyDown={this.onEnterSubmit} id="reset-password-form">
          <Form.Item label="原密码">
            {getFieldDecorator('originpwd', {
              rules: [
                {
                  required: true,
                  message: '请输入原密码!'
                }
              ]
            })(<Input.Password autoFocus/>)}
          </Form.Item>
          <Form.Item label="新密码" hasFeedback>
            {getFieldDecorator('password', {
              rules: [
                {
                  required: true,
                  message: '请输入新密码!'
                },
                {
                  pattern: /^[0-9a-zA-Z!@#$%^&*()_]*$/ig,
                  message: '密码只允许包含数字、字母以及!@#$%&*()_。'
                },
                ...rules,
                {
                  max: 50,
                  message: '最大密码长度为50位!'
                },
                {
                  validator: this.validateToNextPassword
                }
              ]
            })(<Input.Password />)}
          </Form.Item>
          <Form.Item label="确认密码" hasFeedback>
            {getFieldDecorator('confirm', {
              rules: [
                {
                  required: true,
                  message: '请确认密码!'
                },
                {
                  validator: this.compareToFirstPassword
                }
              ]
            })(<Input.Password onBlur={this.handleConfirmBlur} />)}
          </Form.Item>
        </Form> : null}
        {type === 'phonepwd' ? <Form {...formItemLayout} onKeyDown={(e) => e.key === 'Enter' && this.props.resetPwdSubmit()}>
          <Form.Item label="新密码" hasFeedback>
            {getFieldDecorator('password', {
              rules: [
                {
                  required: true,
                  message: '请输入新密码!'
                },
                {
                  pattern: /^[0-9a-zA-Z!@#$%^&*()_]*$/ig,
                  message: '密码只允许包含数字、字母以及!@#$%&*()_。'
                },
                ...rules,
                {
                  max: 50,
                  message: '最大密码长度为50位!'
                },
                {
                  validator: this.validateToNextPassword
                }
              ]
            })(<Input.Password />)}
          </Form.Item>
          <Form.Item label="确认密码" hasFeedback>
            {getFieldDecorator('confirm', {
              rules: [
                {
                  required: true,
                  message: '请确认密码!'
                },
                {
                  validator: this.compareToFirstPassword
                }
              ]
            })(<Input.Password onBlur={this.handleConfirmBlur} />)}
          </Form.Item>
        </Form> : null}
        {type === 'mob' ? <Form {...formItemLayout} onKeyDown={(e) => e.key === 'Enter' && this.props.resetPwdSubmit()}>
          <Form.Item label="手机号">
            {getFieldDecorator('phone', {
              initialValue: '',
              rules: [
                {
                  required: true,
                  message: '请输入手机号!'
                }
              ]
            })(<Input placeholder="请输入手机号" autoComplete="off" />)}
          </Form.Item>
        </Form> : null}
        {type === 'code' ? <Form wrapperCol={{ xs: { span: 24 }, sm: { span: 20 }}} onKeyDown={(e) => e.key === 'Enter' && this.props.resetPwdSubmit()}>
          <Form.Item className="vercode-line" label="">
            {getFieldDecorator('vercode', {
              initialValue: '',
              rules: [
                {
                  required: true,
                  message: '请输入验证码!'
                }
              ]
            })(<Input
              addonAfter={
                <Button type="link" size="small" disabled={verdisabled} onClick={this.getvercode}>
                  {delay ? `${delay}s后重新获取` : '获取验证码'}
                </Button>
              }
              placeholder="请输入验证码"
              autoComplete="off"
            />)}
          </Form.Item>
        </Form> : null}
      </>
    )
  }
}
export default Form.create()(Resetpwd)
src/locales/en-US/login.js
@@ -8,8 +8,6 @@
  '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',
src/locales/en-US/main.js
@@ -1,17 +1,11 @@
export default {
  'main.search': 'Search',
  'main.reset': 'Reset',
  'main.edit': 'Edit',
  'main.confirm': 'OK',
  'main.submit': 'Submit',
  'main.return': 'Return',
  'main.close': 'Close',
  'main.cancel': 'Cancel',
  'main.logout': 'Logout',
  'main.doc': '文档中心',
  'main.logout.hint': 'Are you sure you want to log out?',
  'main.password': 'Change the password',
  'main.login.develop': 'Login developer',
  'main.revert.default': 'Restore default Settings',
  'main.copy.success': 'Copy success',
  'main.pagination.of': 'of',
src/locales/zh-CN/login.js
@@ -8,8 +8,6 @@
  'login.phone.empty': '请输入手机号!',
  'login.vercode': '验证码',
  'login.vercode.empty': '请输入验证码!',
  'login.vercode.query': '获取验证码',
  'login.vercode.queryagain': '@s后重新获取',
  'login.password': '密码',
  'login.password.empty': '请输入密码!',
  'login.remember': '记住密码',
src/locales/zh-CN/main.js
@@ -1,17 +1,11 @@
export default {
  'main.search': '搜索',
  'main.reset': '重置',
  'main.edit': '编辑',
  'main.confirm': '确定',
  'main.submit': '提交',
  'main.return': '返回',
  'main.close': '关闭',
  'main.cancel': '取消',
  'main.logout': '退出',
  'main.doc': '文档中心',
  'main.logout.hint': '您确定要退出吗?',
  'main.password': '修改密码',
  'main.login.develop': '登录开发机',
  'main.revert.default': '恢复默认设置',
  'main.copy.success': '复制成功',
  'main.pagination.of': '共',
src/menu/components/card/balcony/index.jsx
@@ -257,7 +257,7 @@
      }
    })
    return getWrapForm(card.wrap, buttons)
    return getWrapForm(card.wrap, buttons, card.columns)
  }
  updateWrap = (res) => {
src/menu/components/card/balcony/options.jsx
@@ -4,7 +4,7 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, buttons) {
export default function (wrap, buttons, columns) {
  let menu = window.GLOB.customMenu
  let modules = MenuUtils.getLinkModules(menu.components) || []
@@ -69,6 +69,7 @@
      controlFields: [
        {field: 'empty', values: ['dynamic']},
        {field: 'publicId', values: ['public']},
        {field: 'bgField', values: ['dynamic', 'public']},
      ]
    },
    {
@@ -248,6 +249,15 @@
      ],
    },
    {
      type: 'select',
      field: 'bgField',
      label: '背景图',
      initval: wrap.bgField || '',
      tooltip: '动态背景,背景图片由字段值控制。请注意调整背景样式。',
      required: false,
      options: columns
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
src/menu/stylecombcontroller/styleInput/index.scss
@@ -1,7 +1,7 @@
.style-input-box {
  line-height: 32px;
  .ant-select {
    width: 60px!important;
    width: 65px!important;
  }
  .single-unit {
    width: 38px;
src/menu/stylecontroller/index.jsx
@@ -435,12 +435,20 @@
  }
  changeWidth = (val) => {
    let _val = val
    if (_val === '0px') {
      _val = 'auto'
    const { card } = this.state
    let _style = {...card}
    if (val === '0px') {
      delete _style.width
    } else {
      _style.width = val
    }
    this.updateStyle({width: _val})
    this.setState({
      card: _style
    })
    this.callback && this.callback(_style)
  }
  changeHeight = (val) => {
@@ -495,7 +503,7 @@
                    label={<ColumnWidthOutlined title="宽度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.width || ''} options={['px', 'vh', 'vw', '%']} onChange={this.changeWidth}/>
                    <StyleInput defaultValue={card.width || ''} options={['px', 'vh', 'vw', '%', 'auto']} onChange={this.changeWidth}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
src/menu/stylecontroller/styleInput/index.jsx
@@ -48,6 +48,8 @@
        unit = 'vw'
      } else if (val.indexOf('vh') > -1) {
        unit = 'vh'
      } else if (val === 'auto' && _options.includes('auto')) {
        unit = 'auto'
      }
    }
@@ -135,8 +137,14 @@
    const { value } = this.state
    this.setState({unit: val})
    if (value && this.props.onChange) {
      this.props.onChange(`${value}${val}`)
    if (val === 'auto') {
      this.setState({value: ''})
      this.props.onChange('auto')
    } else {
      if (value && this.props.onChange) {
        this.props.onChange(`${value}${val}`)
      }
    }
  }
@@ -145,7 +153,7 @@
    return (
      <div className="style-input-box">
        <Input value={value} addonAfter={
        <Input value={value} disabled={unit === 'auto'} addonAfter={
          options.length > 1 ?
          <Select value={unit} onChange={this.changeUnit}>
            {options.map(item => <Option key={item} value={item}>{item}</Option>)}
src/menu/stylecontroller/styleInput/index.scss
@@ -1,7 +1,7 @@
.style-input-box {
  line-height: 32px;
  .ant-select {
    width: 60px!important;
    width: 65px!important;
  }
  .single-unit {
    width: 38px;
src/tabviews/custom/components/card/balcony/index.jsx
@@ -407,9 +407,14 @@
    const { config, loading, data, show, syncConfig, syncData, checked } = this.state
    if (config.wrap.empty === 'hidden' && (!data || data.$$empty)) return null
    let style = {...config.style}
    if (config.wrap.bgField) {
      style.backgroundImage = `url('${data[config.wrap.bgField] || ''}')`
    }
    
    return (
      <div className={'custom-balcony-box' + (!show ? ' hidden' : '')} id={'anchor' + config.uuid} style={config.style} onClick={this.triggerButton}>
      <div className={'custom-balcony-box' + (!show ? ' hidden' : '')} id={'anchor' + config.uuid} style={style} onClick={this.triggerButton}>
        {loading ?
          <div className="loading-mask" onClick={(e) => e.stopPropagation()}>
            <div className="ant-spin-blur"></div>
src/tabviews/custom/components/module/voucher/index.jsx
@@ -10,6 +10,7 @@
import './index.scss'
const { confirm } = Modal
const { TextArea } = Input
const VoucherTable = asyncComponent(() => import('./voucherTable'))
class VoucherModule extends Component {
@@ -30,6 +31,8 @@
    vouDate: null,
    book: null,
    username: sessionStorage.getItem('User_Name'),
    remark: '',
    remarkVisible: false,
    status: '' // 新建时,empty、change、saved
  }
@@ -310,7 +313,7 @@
  }
  voucherSave = (list, t) => {
    const { BID, config, charInt, charType, book } = this.state
    const { BID, config, charInt, charType, vouDate, book, remark } = this.state
    if (!book) {
      notification.warning({
@@ -326,7 +329,7 @@
      BID: BID,
      voucher_code: '',
      voucher_text: '',
      remark: '',
      remark: remark,
      account_year_code: '',
      voucher_type: '',
      voucher_type_text: '',
@@ -339,40 +342,61 @@
      voucher_char: charType,
      voucher_char_int: charInt,
      account_code: book.account_code || '',
      fibvoucherdate: '',
      fibvoucherdate: vouDate,
      UserName: sessionStorage.getItem('User_Name') || '',
      FullName: sessionStorage.getItem('Full_Name') || '',
      sup_data: '',
      subject_data: ''
    }
    Api.genericInterface(param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
    console.log(list)
    console.log(param)
    console.log(config)
      if (t === 'add') {
        this.setState({
          status: 'empty',
          tbdata: [],
          charInt: charInt + 1
        })
        MKEmitter.emit('cleartable', config.uuid)
      } else {
        this.setState({
          status: 'saved'
        })
      }
    })
    // Api.genericInterface(param).then(res => {
    //   if (!res.status) {
    //     notification.warning({
    //       top: 92,
    //       message: res.message,
    //       duration: 5
    //     })
    //     return
    //   }
    //   if (t === 'add') {
    //     this.setState({
    //       status: 'empty',
    //       remark: '',
    //       tbdata: [],
    //       charInt: charInt + 1
    //     })
    //     MKEmitter.emit('cleartable', config.uuid)
    //   } else {
    //     this.setState({
    //       status: 'saved'
    //     })
    //   }
    // })
  }
  triggerprint = () => {
    this.setState({remarkVisible: true})
  }
  remarkSubmit = () => {
    const { config } = this.state
    let node = document.getElementById(config.uuid + 'remark')
    let val = node.value
    if (val && val.length > 512) {
      notification.warning({
        top: 92,
        message: '当前内容超长,备注最多512个字符。',
        duration: 5
      })
      return
    }
    this.setState({remark: val, remarkVisible: false})
  }
  dataChange = (data) => {
@@ -383,7 +407,7 @@
  }
  render() {
    const { type, status, loading, config, typeOptions, charType, charInt, data, vouDate, username } = this.state
    const { type, status, loading, config, typeOptions, charType, charInt, data, vouDate, username, remark, remarkVisible } = this.state
    return (
      <div className="menu-voucher-wrap" style={config.style}>
@@ -415,6 +439,17 @@
          <VoucherTable config={config} loading={loading} data={data} onChange={this.dataChange}/>
        </div>
        <div className="user">制单人:{username}</div>
        <Modal
          title="备注"
          visible={remarkVisible}
          width={700}
          maskClosable={false}
          onOk={this.remarkSubmit}
          onCancel={() => { this.setState({ remarkVisible: false })}}
          destroyOnClose
        >
          <TextArea id={config.uuid + 'remark'} defaultValue={remark} rows={6}/>
        </Modal>
      </div>
    )
  }
src/views/login/index.jsx
@@ -5,6 +5,7 @@
import Api from '@/api'
import Utils from '@/utils/utils.js' 
import MKEmitter from '@/utils/events.js'
import options, { styles } from '@/store/options.js'
import zhCN from '@/locales/zh-CN/login.js'
import enUS from '@/locales/en-US/login.js'
@@ -13,7 +14,7 @@
import './index.scss'
const LoginForm = asyncLoadComponent(() => import('./loginform'))
const Resetpwd = asyncLoadComponent(() => import('@/components/header/resetpwd'))
const Resetpwd = asyncLoadComponent(() => import('@/components/resetPassword'))
const LoginCloudForm = asyncComponent(() => import('./logincloudform'))
const iszhCN = sessionStorage.getItem('lang') !== 'en-US'
@@ -38,8 +39,6 @@
    loginWays: null,
    touristLogin: false,
    syncing: false,
    visible: false,
    resetLoading: false
  }
  changelang (item) {
@@ -139,8 +138,14 @@
        if (visible) {
          message.warning(tip)
          this.setState({
            isDisabled: false,
            visible: true
            isDisabled: false
          })
          MKEmitter.emit('resetpassword', () => {
            const input = document.getElementById('password')
            if (input) {
              input.select()
            }
          })
          return
        }
@@ -647,7 +652,11 @@
                login_ways.push({
                  type: item.way_no,
                  smsId: item.sms_id
                })
                })
                if (item.way_no === 'sms_vcode' && item.sms_id) {
                  sessionStorage.setItem('mk_sms_id', item.sms_id)
                }
              })
            } else {
              login_ways.push({
@@ -828,48 +837,6 @@
    })
  }
  resetPwdSubmit = () => {
    this.formRef.handleConfirm().then(res => {
      this.setState({
        resetLoading: true
      })
      let _param = {
        func: 's_PwdUpt',
        LText: `select '${res.originpwd}','${res.password}'`
      }
      _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')          // 时间戳
      _param.LText = Utils.formatOptions(_param.LText)                   // 关键字符替换,base64加密
      _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)   // md5密钥
      Api.getSystemConfig(_param).then(result => {
        this.setState({
          visible: !result.status,
          resetLoading: false
        })
        if (result.status) {
          notification.success({
            top: 92,
            message: '修改成功,请重新登录。',
            duration: 2
          })
          const input = document.getElementById('password')
          if (input) {
            input.select()
          }
        } else {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
        }
      })
    }, () => {})
  }
  /**
   * @description 组件销毁,清除state更新
   */
@@ -929,18 +896,7 @@
          <LoginCloudForm handleSubmit={() => this.syncSubmit()} wrappedComponentRef={(inst) => this.logincloudRef = inst}/>
        </Modal>
        {/* 修改密码 */}
        <Modal
          title="修改密码"
          okText={this.state.dict['login.ok']}
          cancelText={this.state.dict['login.cancel']}
          visible={this.state.visible}
          onOk={this.resetPwdSubmit}
          confirmLoading={this.state.resetLoading}
          onCancel={() => this.setState({visible: false, resetLoading: false})}
          destroyOnClose
        >
          <Resetpwd wrappedComponentRef={(inst) => this.formRef = inst} resetPwdSubmit={this.resetPwdSubmit}/>
        </Modal>
        <Resetpwd />
      </div>
    )
  }
src/views/login/loginform.jsx
@@ -452,7 +452,7 @@
              <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后重新获取` : '获取验证码'}
                  </Button>
                }
                placeholder={this.props.dict['login.vercode']}