king
2021-04-09 92a9b175fda139d6608c53af62e4d8b7b1c926cf
2021-04-09
25个文件已修改
578 ■■■■ 已修改文件
src/assets/css/viewstyle.scss 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/settingform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/sysinterface/settingform/baseform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/index.scss 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/loginform.jsx 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/wrapsetting/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/wrapsetting/settingform/index.jsx 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/card.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/group/normal-group/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/tabtransfer/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/settingform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/menuconfig/editthdmenu/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/config.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.scss 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/loginform.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss
@@ -33,11 +33,8 @@
      button.vercode {
        color: $color6;
      }
      .ant-tabs {
        .ant-tabs-tab.ant-tabs-tab-active {
          color: $color6;
        }
        .ant-tabs-tab:hover {
      .login-way-wrap {
        .login-way.active, .login-way:hover {
          color: $color6;
        }
      }
src/menu/datasource/verifycard/settingform/index.jsx
@@ -182,6 +182,10 @@
                      required: true,
                      message: this.props.dict['form.required.input'] + '表名!'
                    },
                    {
                      max: 50,
                      message: '表名最长为50个字符!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" />)}
              </Form.Item>
src/menu/sysinterface/settingform/baseform/index.jsx
@@ -242,8 +242,8 @@
                      message: dict['form.required.input'] + '回调表名!'
                    },
                    {
                      max: formRule.input.max,
                      message: formRule.input.message
                      max: 50,
                      message: '表名最长为50个字符!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" />)}
src/pc/components/login/normal-login/index.jsx
@@ -41,11 +41,11 @@
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
        wrap: { name: card.name, width: card.width || 24, title: '', switch: 'false', datatype: 'static' },
        wrap: { name: card.name, width: card.width || 24, loginWays: ['uname_pwd', 'sms_vcode'] },
        style: { background: '#ffffff', width: '330px', borderRadius: '4px', marginLeft: '55vw' },
        loginWays: [
          {type: 'uname_pwd', label: '账号密码', remember: 'true', disabled: false, labelStyle: {}, submitStyle: {}, submitLabel: '登录'},
          {type: 'sms_vcode', label: '短信验证码', disabled: true, labelStyle: {}, submitStyle: {}, submitLabel: '登录'}
          {type: 'uname_pwd', label: '账号密码', remember: 'true', labelStyle: {}, submitStyle: {}, submitLabel: '登录'},
          {type: 'sms_vcode', label: '短信验证码', labelStyle: {}, submitStyle: {}, submitLabel: '登录'}
        ]
      }
@@ -140,7 +140,7 @@
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        <LoginForm loginWays={card.loginWays} dict={dict} />
        <LoginForm loginWays={card.loginWays} wrap={card.wrap} dict={dict} />
      </div>
    )
  }
src/pc/components/login/normal-login/index.scss
@@ -1,4 +1,5 @@
.login-edit-box {
  display: inline-block;
  position: relative;
  box-sizing: border-box;
  background: #ffffff;
@@ -28,11 +29,13 @@
    background: rgba(255, 255, 255, 0.55);
  }
  .login-edit-form {
    border-radius: inherit;
    .ant-form-item {
      font-size: 16px;
      margin: 0 15px 15px;
      .ant-input {
        height: 35px;
        background: transparent;
      }
    }
    button:not(.vercode) {
@@ -46,6 +49,50 @@
      margin-bottom: 0;
    }
  }
  .login-way-wrap {
    height: 50px;
    line-height: 50px;
    margin-bottom: 10px;
    display: flex;
    border-radius: inherit;
    .login-way {
      flex: 1;
      width: 50%;
      font-size: 17px;
      text-align: center;
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
      padding: 0 16px;
      transition: all 0.3s;
      border: 1px solid transparent;
      border-top: 0!important;
    }
    .login-way.active, .login-way:hover {
      color: #1890ff;
    }
    .login-way:not(.active) {
      cursor: pointer;
      background: #fafafa;
      border: 1px solid #e8e8e8;
    }
    .login-way:first-child {
      border-left: 0;
      border-top-left-radius: inherit;
    }
    .login-way:last-child {
      border-right: 0;
      border-top-right-radius: inherit;
    }
  }
  .login-way-wrap.simple {
    .login-way {
      font-size: 18px;
      text-align: left;
      padding: 0 15px;
      line-height: 60px;
    }
  }
}
.login-edit-box::after {
  display: block;
src/pc/components/login/normal-login/loginform.jsx
@@ -1,71 +1,58 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Icon, Input, Button, Checkbox, Tabs } from 'antd'
import { Form, Icon, Input, Button, Checkbox } from 'antd'
import './index.scss'
const { TabPane } = Tabs
class LoginTabForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,
    loginWays: PropTypes.array,
    wrap: PropTypes.array,
  }
  state = {
    activeKey: 'uname_pwd',
    username: '',
    password: '',
    activeWay: null,
    loginWays: [],
    smsId: '',
    verdisabled: false
  }
  UNSAFE_componentWillMount () {
    const { loginWays } = this.props
    const { loginWays, wrap } = this.props
    let smsId = ''
    let _loginWays = []
    loginWays.forEach(item => {
      if (item.type === 'sms_vcode') {
        smsId = item.smsId
        _loginWays.push(item)
      } else if (item.type === 'uname_pwd') {
      if (!wrap.loginWays || wrap.loginWays.includes(item.type)) {
        _loginWays.push(item)
      }
    })
    this.setState({
      smsId: smsId,
      loginWays: _loginWays,
      activeKey: _loginWays[0].type,
      activeWay: _loginWays[0],
    })
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.loginWays), fromJS(nextProps.loginWays))) {
      let smsId = ''
    const { loginWays, wrap } = this.props
    if (!is(fromJS(wrap), fromJS(nextProps.wrap))) {
      let _loginWays = []
      nextProps.loginWays.forEach(item => {
        if (item.type === 'sms_vcode') {
          smsId = item.smsId
          _loginWays.push(item)
        } else if (item.type === 'uname_pwd') {
      loginWays.forEach(item => {
        if (!nextProps.wrap.loginWays || nextProps.wrap.loginWays.includes(item.type)) {
          _loginWays.push(item)
        }
      })
      this.setState({
        smsId: smsId,
        loginWays: _loginWays,
        activeKey: _loginWays[0].type
        activeWay: _loginWays[0],
      })
    }
  }
  onChangeTab = (activeKey) => {
    this.setState({activeKey})
  onChangeTab = (activeWay) => {
    this.setState({activeWay})
  }
  /**
@@ -78,50 +65,59 @@
  }
  render() {
    const { activeKey, verdisabled, loginWays } = this.state
    const { activeWay, loginWays } = this.state
    return (
      <Form className="login-edit-form">
        <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>
        <div className={'login-way-wrap ' + (loginWays.length === 1 ? 'simple' : '')}>
          {loginWays.map(item => (
            <div className={'login-way' + (activeWay.type === item.type ? ' active' : '')} onClick={() => this.onChangeTab(item)} key={item.type}>{item.label}</div>
          ))}
        </div>
        {activeWay.type === 'uname_pwd' ? <div className="form-item-wrap">
          <Form.Item>
            <Input
              prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
              placeholder="用户名"
              autoComplete="off"
            />
          </Form.Item> : null}
          {activeKey === 'uname_pwd' ? <Form.Item>
          </Form.Item>
          <Form.Item>
            <Input.Password placeholder="密码" prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} />
          </Form.Item> : null}
          {activeKey === 'sms_vcode' ? <Form.Item>
          </Form.Item>
          <Form.Item className="minline">
            <Checkbox>记住密码</Checkbox>
          </Form.Item>
          <Form.Item className="btn-login">
            <Button type="primary" htmlType="submit" className="login-form-button">
              登录
            </Button>
          </Form.Item>
        </div> : null}
        {activeWay.type === 'sms_vcode' ? <div className="form-item-wrap">
          <Form.Item>
            <Input
              placeholder="手机号"
              autoComplete="off"
            />
          </Form.Item> : null}
          {activeKey === 'sms_vcode' ? <Form.Item>
          </Form.Item>
          <Form.Item style={{marginBottom: '35px'}}>
            <Input
              addonAfter={
                <Button type="link" className="vercode" size="small" disabled={verdisabled}>
                <Button type="link" className="vercode" size="small">
                  获取验证码
                </Button>
              }
              placeholder="验证码"
              autoComplete="off"
            />
          </Form.Item> : null}
          {activeKey === 'uname_pwd' ? <Form.Item className="minline">
            <Checkbox>记住密码</Checkbox>
          </Form.Item> : null}
          {['uname_pwd', 'sms_vcode'].includes(activeKey) ? <Form.Item className="btn-login">
          </Form.Item>
          <Form.Item className="btn-login">
            <Button type="primary" htmlType="submit" className="login-form-button">
              登录
            </Button>
          </Form.Item> : null}
        </div>
          </Form.Item>
        </div> : null}
      </Form>
    )
  }
src/pc/components/login/wrapsetting/index.jsx
@@ -27,7 +27,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState))
  }
  editDataSource = () => {
@@ -50,7 +50,6 @@
  }
  render () {
    const { config } = this.props
    const { visible, dict, wrap } = this.state
    return (
@@ -58,7 +57,7 @@
        <Icon type="edit" title="编辑" onClick={() => this.editDataSource()} />
        <Modal
          wrapClassName="popview-modal"
          title={config.type === 'table' ? '表格设置' : '卡片设置'}
          title="登录设置"
          visible={visible}
          width={800}
          maskClosable={false}
@@ -70,7 +69,6 @@
          <SettingForm
            dict={dict}
            wrap={wrap}
            config={config}
            inputSubmit={this.verifySubmit}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
          />
src/pc/components/login/wrapsetting/settingform/index.jsx
@@ -1,23 +1,26 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd'
import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select, Checkbox, notification } from 'antd'
import StyleInput from '@/menu/stylecontroller/styleInput'
import './index.scss'
class SettingForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,      // 字典项
    config: PropTypes.object,    // 卡片行信息
    wrap: PropTypes.object,      // 数据源配置
    inputSubmit: PropTypes.func  // 回车事件
  }
  state = {
    roleList: []
    roleList: [],
    msgTemps: []
  }
  UNSAFE_componentWillMount () {
    let roleList = sessionStorage.getItem('sysRoles')
    let msgTemps = sessionStorage.getItem('msgTemplate')
    if (roleList) {
      try {
        roleList = JSON.parse(roleList)
@@ -28,7 +31,17 @@
      roleList = []
    }
    this.setState({roleList})
    if (msgTemps) {
      try {
        msgTemps = JSON.parse(msgTemps)
      } catch {
        msgTemps = []
      }
    } else {
      msgTemps = []
    }
    this.setState({roleList, msgTemps})
  }
  handleConfirm = () => {
@@ -36,6 +49,14 @@
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          if (values.loginWays.includes('sms_vcode') && !values.tempId) {
            notification.warning({
              top: 92,
              message: '使用短信验证码登录时,需要选择短信模板!',
              duration: 5
            })
            return
          }
          resolve(values)
        } else {
          reject(err)
@@ -53,9 +74,9 @@
  }
  render() {
    const { wrap, config } = this.props
    const { wrap } = this.props
    const { getFieldDecorator } = this.props.form
    const { roleList } = this.state
    const { roleList, msgTemps } = this.state
    const formItemLayout = {
      labelCol: {
@@ -73,13 +94,6 @@
        <Form {...formItemLayout}>
          <Row gutter={24}>
            <Col span={12}>
              <Form.Item label="标题">
                {getFieldDecorator('title', {
                  initialValue: wrap.title || ''
                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="用于组件间的区分。">
                  <Icon type="question-circle" />
@@ -95,6 +109,26 @@
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="登录方式">
                {getFieldDecorator('loginWays', {
                  initialValue: wrap.loginWays || [],
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.select'] + '登录方式!'
                    }
                  ]
                })(
                  <Checkbox.Group
                    options={[
                      { label: '账号密码', value: 'uname_pwd' },
                      { label: '短信验证码', value: 'sms_vcode' },
                    ]}
                  />
                )}
              </Form.Item>
            </Col>
            <Col span={12}>
@@ -115,117 +149,35 @@
                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)}
              </Form.Item>
            </Col>
            {config.subtype === 'propcard' ? <Col span={12}>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择静态值,无需配置数据源。">
                  <Icon type="question-circle" />
                  数据来源
                </Tooltip>
              }>
                {getFieldDecorator('datatype', {
                  initialValue: wrap.datatype || 'dynamic'
                })(
                  <Radio.Group>
                    <Radio value="dynamic">动态</Radio>
                    <Radio value="static">静态</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'datacard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="数据源中选择分页时有效。">
                  <Icon type="question-circle" />
                  分页风格
                </Tooltip>
              }>
                {getFieldDecorator('pagestyle', {
                  initialValue: wrap.pagestyle || 'page'
                })(
                  <Radio.Group>
                    <Radio value="page">页码</Radio>
                    <Radio value="switch">左右切换</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label="卡片属性">
                {getFieldDecorator('cardType', {
                  initialValue: wrap.cardType || ''
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
                    <Radio key="" value=""> 不可选 </Radio>
                    <Radio key="radio" value={'radio'}> 单选 </Radio>
                    {config.subtype !== 'propcard' ? <Radio key="checkbox" value={'checkbox'}> 多选 </Radio> : null}
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="设置为居中对齐或右对齐,只在卡片为1行时有效。">
                  <Icon type="question-circle" />
                  卡片排列
                </Tooltip>
              }>
                {getFieldDecorator('cardFloat', {
                  initialValue: wrap.cardFloat || 'left'
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
                    <Radio key="left" value="left"> 左对齐 </Radio>
                    <Radio key="center" value="center"> 居中 </Radio>
                    <Radio key="right" value="right"> 右对齐 </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="鼠标悬浮于卡片上方时,卡片放大1.05倍。">
                  <Icon type="question-circle" />
                  卡片放大
                </Tooltip>
              }>
                {getFieldDecorator('scale', {
                  initialValue: wrap.scale || 'false'
                })(
                  <Radio.Group>
                    <Radio key="false" value="false"> 否 </Radio>
                    <Radio key="true" value="true"> 是 </Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="表格高度,超出时滚动,高度为空时根据内容自适应。">
                <Tooltip placement="topLeft" title="组件占用的最小高度,用于页面布局。">
                  <Icon type="question-circle" />
                  高度
                </Tooltip>
              }>
                {getFieldDecorator('height', {
                  initialValue: wrap.height
                })(<InputNumber min={100} max={2000} precision={0} onPressEnter={this.handleSubmit} />)}
                })(<StyleInput options={['px', 'vh', 'vw', '%']}/>)}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'propcard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择类型为《页眉/页脚》时,打印的每页里都会带有该组件。">
                  <Icon type="question-circle" />
                  组件类型
                </Tooltip>
              }>
                {getFieldDecorator('printType', {
                  initialValue: wrap.printType || 'content'
            </Col>
            <Col span={12}>
              <Form.Item label="短信模板">
                {getFieldDecorator('tempId', {
                  initialValue: wrap.tempId || ''
                })(
                  <Radio.Group>
                    <Radio value="content">内容</Radio>
                    <Radio value="headerOrfooter">页眉/页脚</Radio>
                  </Radio.Group>
                  <Select
                    showSearch
                    allowClear
                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  >
                    {msgTemps.map(option =>
                      <Select.Option key={option.ID} value={option.ID}>{option.SignName + ' - ' + option.TemplateCode}</Select.Option>
                    )}
                  </Select>
                )}
              </Form.Item>
            </Col> : null}
            </Col>
            <Col span={12}>
              <Form.Item label="黑名单">
                {getFieldDecorator('blacklist', {
src/pc/components/navbar/normal-navbar/index.jsx
@@ -138,6 +138,10 @@
  }
  changeMenu = (menu) => {
    if (menu.property === 'link') {
      window.open(menu.link)
      return
    }
    MKEmitter.emit('changeEditMenu', {
      fixed: menu.property === 'menu',
      MenuID: menu.property === 'linkmenu' ? menu.linkMenuId : menu.MenuID,
src/pc/menushell/card.jsx
@@ -90,7 +90,10 @@
    } else if (card.type === 'code') {
      return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'login') {
      return (<NormalLogin card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
      return (<>
        <NormalLogin card={card} updateConfig={updateConfig} deletecomponent={delCard}/>
        <div style={{float: 'right', height: card.wrap ? card.wrap.height : ''}}></div>
      </>)
    }
  }
  return (
src/tabviews/commontable/index.jsx
@@ -1076,7 +1076,7 @@
                  </div>
                  <div className="main-table-box">
                    {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && this.state.data && this.state.data.length > 0 ?
                      <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
                      <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" checked={pickup} onChange={this.pickupChange} /> : null
                    }
                    <MainTable
                      tableId="mainTable"
src/tabviews/custom/components/group/normal-group/index.jsx
@@ -17,6 +17,7 @@
const AntvPie = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-pie'))
const DataCard = asyncComponent(() => import('@/tabviews/custom/components/card/data-card'))
const TableCard = asyncComponent(() => import('@/tabviews/custom/components/card/table-card'))
const NormalTable = asyncComponent(() => import('@/tabviews/custom/components/table/normal-table'))
const PropCard = asyncComponent(() => import('@/tabviews/custom/components/card/prop-card'))
const BraftEditor = asyncComponent(() => import('@/tabviews/custom/components/editor/braft-editor'))
const SandBox = asyncComponent(() => import('@/tabviews/custom/components/code/sand-box'))
@@ -270,6 +271,12 @@
            <TableCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'normaltable') {
        return (
          <Col span={item.width} key={item.uuid}>
            <NormalTable config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
          </Col>
        )
      } else if (item.type === 'editor') {
        return (
          <Col span={item.width} key={item.uuid}>
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -805,7 +805,7 @@
    return (
      <div className={'normal-custom-table ' + setting.tableHeader} id={tableId}>
        {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && data && data.length > 0 ?
          <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
          <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" checked={pickup} onChange={this.pickupChange} /> : null
        }
        <Table
          components={components}
src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -19,6 +19,7 @@
const AntvTabs = asyncComponent(() => import('@/tabviews/custom/components/tabs/antv-tabs'))
const DataCard = asyncComponent(() => import('@/tabviews/custom/components/card/data-card'))
const TableCard = asyncComponent(() => import('@/tabviews/custom/components/card/table-card'))
const NormalTable = asyncComponent(() => import('@/tabviews/custom/components/table/normal-table'))
const PropCard = asyncComponent(() => import('@/tabviews/custom/components/card/prop-card'))
const NormalGroup = asyncComponent(() => import('@/tabviews/custom/components/group/normal-group'))
const BraftEditor = asyncComponent(() => import('@/tabviews/custom/components/editor/braft-editor'))
@@ -301,6 +302,12 @@
            <TableCard config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'normaltable') {
        return (
          <Col span={item.width} key={item.uuid}>
            <NormalTable config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
          </Col>
        )
      } else if (item.type === 'group' && item.subtype === 'normalgroup') {
        return (
          <Col span={item.width} key={item.uuid}>
src/tabviews/subtable/index.jsx
@@ -973,7 +973,7 @@
                  </div>
                  <div className="subtable-box">
                    {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && this.state.data && this.state.data.length > 0 ?
                      <Switch title="收起" className="subtable-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
                      <Switch title="收起" className="subtable-pickup" checkedChildren="开" unCheckedChildren="关" checked={pickup} onChange={this.pickupChange} /> : null
                    }
                    <SubTable
                      tableId={this.props.Tab.uuid}
src/templates/formtabconfig/settingform/index.jsx
@@ -197,8 +197,8 @@
                    message: dict['form.required.input'] + '表名!'
                  },
                  {
                    max: formRule.input.max,
                    message: formRule.input.message
                    max: 50,
                    message: '表名最长为50个字符!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
src/templates/menuconfig/editthdmenu/index.jsx
@@ -673,6 +673,7 @@
            })
  
            this.props.reload()
            document.getElementById('root').style.overflowY = 'unset'
          } else {
            this.setState({
              confirmLoading: false
@@ -725,6 +726,7 @@
            })
  
            this.props.reload()
            document.getElementById('root').style.overflowY = 'unset'
          } else {
            this.setState({
              confirmLoading: false
src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx
@@ -184,6 +184,10 @@
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '表名!'
                    },
                    {
                      max: 50,
                      message: '表名最长为50个字符!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" />)}
src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
@@ -216,6 +216,10 @@
                      required: true,
                      message: dict['form.required.input'] + '表名!'
                    },
                    {
                      max: 50,
                      message: '表名最长为50个字符!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" />)}
              </Form.Item>
src/templates/sharecomponent/treesettingcomponent/settingform/datasource/index.jsx
@@ -201,8 +201,8 @@
                      message: dict['form.required.input'] + '表名!'
                    },
                    {
                      max: formRule.input.max,
                      message: formRule.input.message
                      max: 50,
                      message: '表名最长为50个字符!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit}/>)}
src/views/design/sidemenu/config.jsx
@@ -170,20 +170,20 @@
    MenuID: '1589788042787ffdt9hle4s45k9r1nvs',
    MenuNo: 'bd_msn_email_tempM',
    MenuName: '邮件模板',
  }, {
    src: '',
    PageParam: {OpenType: 'newtab', Template: 'ManageTable'},
    type: 'ManageTable',
    MenuID: '15900310928174dro07ihfckghpb5h13',
    MenuNo: 'bd_msn_sms_tempM',
    MenuName: '大于短信模板',
  // }, {
  //   src: '',
  //   PageParam: {OpenType: 'newtab', Template: 'ManageTable'},
  //   type: 'ManageTable',
  //   MenuID: '1599613340050c8nu6rbst9d4emnnbsq',
  //   MenuNo: 's_sms_qxM',
  //   MenuName: '奇云短信模板',
  //   MenuID: '15900310928174dro07ihfckghpb5h13',
  //   MenuNo: 'bd_msn_sms_tempM',
  //   MenuName: '大于短信模板',
  }, {
    src: '',
    PageParam: {OpenType: 'newtab', Template: 'ManageTable'},
    type: 'ManageTable',
    MenuID: '1599613340050c8nu6rbst9d4emnnbsq',
    MenuNo: 's_sms_qxM',
    MenuName: '奇云短信模板',
  }]
}, {
  MenuID: 'systemPayManage',
src/views/login/index.jsx
@@ -51,12 +51,6 @@
      dict: item === 'zh-CN' ? zhCN : enUS
    })
  }
  md5Password (pwd) {
    // md5密码加密
    const salt = 'minkesoft'
    return md5(md5(pwd + salt))
  }
  handleSubmit = () => {
    this.loginformRef.handleConfirm().then(res => {
src/views/login/index.scss
@@ -26,61 +26,6 @@
    }
  }
  .ant-tabs.ant-tabs-card {
    .ant-tabs-card-bar {
      border-bottom: 0;
      .ant-tabs-nav-container {
        height: 50px;
        line-height: 50px;
      }
      margin-bottom: 10px;
      .ant-tabs-nav-scroll {
        .ant-tabs-nav {
          display: block;
          > div {
            display: flex;
            > .ant-tabs-tab {
              height: 50px;
              line-height: 50px;
              flex: 1;
            }
          }
        }
      }
      .ant-tabs-tab {
        display: block;
        margin-right: 0;
        border-radius: 0;
        text-align: center;
        font-size: 17px;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        border-top: 0;
      }
      .ant-tabs-tab:first-child {
        border-left: 0;
      }
      .ant-tabs-tab:last-child {
        border-right: 0;
      }
      .ant-tabs-tab.ant-tabs-tab-active {
        cursor: default;
      }
    }
  }
  .login-form-1 {
    .ant-tabs.ant-tabs-card {
      .ant-tabs-card-bar {
        .ant-tabs-tab {
          font-size: 18px;
          text-align: left!important;
          padding-left: 1.6vw!important;
          line-height: 60px!important;
        }
      }
    }
  }
  .login-middle {
    position: relative;
    height: calc(100vh - 194px);
@@ -100,6 +45,47 @@
      overflow: hidden;
      border: 1px solid #bfbfbf;
      .login-way-wrap {
        height: 50px;
        line-height: 50px;
        margin-bottom: 10px;
        display: flex;
        .login-way {
          flex: 1;
          width: 50%;
          font-size: 17px;
          text-align: center;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
          padding: 0 16px;
          transition: all 0.3s;
          border: 1px solid transparent;
          border-top: 0!important;
        }
        .login-way.active, .login-way:hover {
          color: #1890ff;
        }
        .login-way:not(.active) {
          cursor: pointer;
          background: #fafafa;
          border: 1px solid #e8e8e8;
        }
        .login-way:first-child {
          border-left: 0;
        }
        .login-way:last-child {
          border-right: 0;
        }
      }
      .login-way-wrap.simple {
        .login-way {
          font-size: 18px;
          text-align: left!important;
          padding-left: 1.6vw!important;
          line-height: 60px!important;
        }
      }
      .form-item-wrap {
        padding: 0.6vw 1.6vw 1.6vw;
      }
src/views/login/loginform.jsx
@@ -1,7 +1,7 @@
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, Icon, Input, Button, Checkbox, Select, Modal, message } from 'antd'
import md5 from 'md5'
import moment from 'moment'
@@ -10,7 +10,6 @@
import './index.scss'
const { warning } = Modal
const { TabPane } = Tabs
let LoginVerCodeTimer = null
class LoginTabForm extends Component {
@@ -278,10 +277,12 @@
    const { activeKey, verdisabled, delay, loginWays, remember } = 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>
      <Form className="login-form" id="login-form" onSubmit={this.handleSubmit}>
        <div className={'login-way-wrap ' + (loginWays.length === 1 ? 'simple' : '')}>
          {loginWays.map(item => (
            <div className={'login-way' + (activeKey === item.type ? ' active' : '')} onClick={() => this.onChangeTab(item.type)} key={item.type}>{item.label}</div>
          ))}
        </div>
        <div className="form-item-wrap">
          {activeKey === 'uname_pwd' ? <Form.Item>
            {getFieldDecorator('username', {
src/views/pcdesign/index.jsx
@@ -127,6 +127,7 @@
    setTimeout(() => {
      this.updateCustomComponent()
      this.getAppPictures()
      this.getSmStemp()
    }, 1000)
  }
@@ -249,6 +250,37 @@
    })
  }
  getSmStemp = () => {
    let _sql = `select ID,TemplateCode,SignName from bd_msn_sms_temp where deleted=0 and appkey='${window.GLOB.appkey}'`
    _sql = Utils.formatOptions(_sql)
    let param = {
      func: 'sPC_Get_SelectedList',
      LText: _sql,
      obj_name: 'data',
      arr_field: 'ID,TemplateCode,SignName'
    }
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp) // 云端数据验证
    Api.getSystemConfig(param).then(res => {
      let msgs = []
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else if (res.data) {
        msgs = res.data
      }
      sessionStorage.setItem('msgTemplate', JSON.stringify(msgs))
    })
  }
  getAppPictures = () => {
    if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return
@@ -261,6 +293,12 @@
    }).then(res => {
      if (res.status) {
        sessionStorage.setItem('app_pictures', JSON.stringify(res.data || []))
      } else if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
      Api.getSystemConfig({
@@ -272,6 +310,12 @@
      }).then(res => {
        if (res.status) {
          sessionStorage.setItem('app_videos', JSON.stringify(res.data || []))
        } else if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
    })
@@ -283,7 +327,13 @@
      typecharone: ''
    }).then(res => {
      let coms = []
      if (res.cus_list && res.cus_list.length > 0) {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else if (res.cus_list && res.cus_list.length > 0) {
        res.cus_list.forEach(item => {
          let config = ''