king
2023-12-10 cc810edac6aec3c858fb352091ad8c11332447a5
Merge branch 'develop'
87个文件已修改
5个文件已添加
2933 ■■■■■ 已修改文件
public/README.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/manifest.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/media/excel.png 补丁 | 查看 | 原始文档 | blame | 历史
public/media/pdf.png 补丁 | 查看 | 原始文档 | blame | 历史
public/media/rar.png 补丁 | 查看 | 原始文档 | blame | 历史
public/media/txt.png 补丁 | 查看 | 原始文档 | blame | 历史
public/media/word.png 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.jsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/mkRadio/index.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/mkSelect/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/formconfig.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/options.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/doublecardcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx 446 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/index.jsx 748 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/index.scss 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/editorcode/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/options.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/options.jsx 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecontroller/index.jsx 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/basetable/index.jsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.jsx 297 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/code/sand-box/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/simple-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/step-form/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/form/tab-form/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tabs/antv-tabs/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tabs/antv-tabs/index.scss 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/mkSelect/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/uniqueform/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/searchform/index.jsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/codemirror/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/baseform/index.jsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/billcodeform/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/callbackcustomscript/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/contrastform/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/customscript/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/fullScripts/index.scss 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/uniqueform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-datamanage.js 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/interface/history/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/menuform/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/rolemanage/index.jsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/rolemanage/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/README.txt
@@ -17,4 +17,5 @@
probation         -- 试用期(YYYY-MM-DD),在正式系统中,试用期内调用系统接口的脚本会记录下来
transfer          -- 是否使用转接口,使用转接口时请设置为 true, 使用转接口时,外部接口调用前不会做登录验证
keepPassword      -- 记住密码,默认开启,当值为 false 时禁用
updateStatus      -- 是否更新开发状态,默认开启,当值为 false 时禁用
platforms         -- 移动端可使用的平台类型,默认为 ["H5", "wechat", "android", "ios", "wxMiniProgram"] 分别代表H5页面、微信公众号、安卓APP、苹果APP、微信小程序
public/manifest.json
@@ -6,5 +6,5 @@
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "mk_version": "20230712"
  "mk_version": "20231201"
}
public/media/excel.png
public/media/pdf.png
public/media/rar.png
public/media/txt.png
public/media/word.png
src/api/index.js
@@ -852,9 +852,6 @@
      param.fullname = sessionStorage.getItem('Full_Name') || ''
    }
    let login = false
    let rduri = null
    if (param.rduri && /\s|\n/.test(param.rduri)) {
      param.rduri = param.rduri.replace(/\s|\n/g, '')
      if (!param.rduri) {
@@ -862,31 +859,32 @@
      }
    }
    if (param.$login && !window.GLOB.transfer) {
      login = true
      rduri = param.rduri || ''
    }
    delete param.$login
    if (param.$login) {
      let rduri = param.rduri || ''
    let url = '/webapi/dostars'
    if (param.rduri && !window.GLOB.transfer && /\/dostars/.test(param.rduri) && param.func !== 'webapi_ChangeUser') {
      url = param.rduri
      delete param.$login
      delete param.rduri
    }
    param = this.encryptParam(param)
      param = this.encryptParam(param)
    if (login) {
      let time = +sessionStorage.getItem(rduri)
      let c_time = Math.round(new Date().getTime() / 1000)
      if (time && c_time - time <= 1800) {
        sessionStorage.setItem(rduri, c_time)
        return axios({
          url: `${url}${param.func ? '/' + param.func : ''}`,
          method: 'post',
          data: JSON.stringify(param)
        return new Promise((resolve, reject) => {
          axios({
            url: `${rduri}${param.func ? '/' + param.func : ''}`,
            method: 'post',
            data: JSON.stringify(param)
          }).then(result => {
            if (result && result.ErrCode === 'LoginError') {
              sessionStorage.removeItem(rduri)
            }
            resolve(result)
          }, () => {
            reject()
          })
        })
      }
@@ -895,11 +893,13 @@
          if (res.status) {
            sessionStorage.setItem(rduri, c_time)
            axios({
              url: `${url}${param.func ? '/' + param.func : ''}`,
              url: `${rduri}${param.func ? '/' + param.func : ''}`,
              method: 'post',
              data: JSON.stringify(param)
            }).then(result => {
              resolve(result)
            }, () => {
              reject()
            })
          } else {
            resolve(res)
@@ -918,6 +918,14 @@
        })
      })
    } else {
      let url = '/webapi/dostars'
      if (param.rduri && !window.GLOB.transfer && /\/dostars/.test(param.rduri) && param.func !== 'webapi_ChangeUser') {
        url = param.rduri
        delete param.rduri
      }
      param = this.encryptParam(param)
      return axios({
        url: `${url}${param.func ? '/' + param.func : ''}`,
        method: 'post',
src/assets/css/viewstyle.scss
@@ -41,6 +41,17 @@
        }
      }
    }
    .data-zoom.radio.deepBackFont, .data-zoom.checkbox.deepBackFont {
      .mk-card:hover, .mk-card.active, .mk-card.selected {
        > .card-item-box {
          border-color: $color6!important;
          background-color: $color6!important;
          .ant-mk-text:not(.sign-font) {
            color: #ffffff;
          }
        }
      }
    }
    .data-zoom.radio.font, .data-zoom.checkbox.font {
      .mk-card:hover, .mk-card.active, .mk-card.selected {
        > .card-item-box {
src/components/normalform/modalform/index.jsx
@@ -7,6 +7,7 @@
import asyncComponent from '@/utils/asyncComponent'
import MKEInput from './mkInput'
import MKNumberInput from './mkNumberInput'
import MKEmitter from '@/utils/events.js'
import MKSelect from './mkSelect'
import './index.scss'
@@ -17,14 +18,16 @@
const MKCheckbox = asyncComponent(() => import('./mkCheckbox'))
const StyleInput = asyncComponent(() => import('./styleInput'))
const MKFileUpload = asyncComponent(() => import('@/tabviews/zshare/fileupload'))
const MKColor = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkColor'))
const MKColor = asyncComponent(() => import('@/mob/colorsketch'))
// const MKColor = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkColor'))
const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
class ModalForm extends Component {
  static propTpyes = {
    formlist: PropTypes.array,   // 表单列表
    inputSubmit: PropTypes.func  // input回车提交
    formlist: PropTypes.array,
    inputSubmit: PropTypes.func,
    transVals: PropTypes.func,
  }
  state = {
@@ -70,7 +73,7 @@
          required: item.required,
          message: item.label + '不可为空!'
        }, {
          validator: (rule, value, callback) => this.handleConfirmPassword(rule, value, callback, item)
          validator: (rule, value, callback) => this.checkNumber(rule, value, callback, item)
        }]
      } else if (item.type === 'textarea') {
        item.rules = [
@@ -108,7 +111,7 @@
      let supItem = fieldMap.get(key)
      let supval = supItem.initval
      if (supItem.initval && supItem.type !== 'checkbox' && JSON.stringify(supItem.initval) === '[]') {
      if (supval && JSON.stringify(supval) === '[]') {
        supval = ''
      }
@@ -124,13 +127,13 @@
        } else if (supItem.hidden) {
          cell.hidden = true
        } else if (supItem.type === 'checkbox') {
          let vals = [...supval, ...item.values]
        } else if (item.notNull) {
          cell.hidden = !supval
        } else if (supItem.type === 'checkbox' || supItem.type === 'multiselect') {
          let vals = [...(supval || []), ...item.values]
          if (vals.length === new Set(vals).size) {
            cell.hidden = true
          }
        } else if (item.notNull) {
          cell.hidden = !supval
        } else if (!item.values.includes(supval)) {
          cell.hidden = true
        }
@@ -162,7 +165,7 @@
    this.setState({ formlist })
  }
  handleConfirmPassword = (rule, value, callback, item) => {
  checkNumber = (rule, value, callback, item) => {
    let val = parseFloat(value)
    if (!isNaN(val)) {
@@ -179,6 +182,10 @@
    this.record = {...this.record, ...values}
    if (!item) return
    if (item.$trans) {
      this.props.transVals && this.props.transVals(values, item.field)
    }
    
    if (item.controlFields) {
      let map = new Map()
@@ -190,7 +197,7 @@
      let reset = (current) => {
        let val = this.record[current.field]
        if (val && current.type !== 'checkbox' && JSON.stringify(val) === '[]') {
        if (val && JSON.stringify(val) === '[]') {
          val = ''
        }
@@ -199,15 +206,15 @@
          if (current.hidden) {
            m.hidden = true
          } else if (current.type === 'checkbox') {
            let vals = [...val, ...cell.values]
          } else if (cell.notNull) {
            m.hidden = !val
          } else if (current.type === 'checkbox' || current.type === 'multiselect') {
            let vals = [...(val || []), ...cell.values]
            if (vals.length !== new Set(vals).size) {
              m.hidden = false
            } else {
              m.hidden = true
            }
          } else if (cell.notNull) {
            m.hidden = !val
          } else {
            m.hidden = !cell.values.includes(val)
          }
@@ -248,7 +255,7 @@
        map.set(cell.field, cell)
      })
      item.callback(map, this.record)
      item.callback(map, this.record, MKEmitter)
      this.setState({
        formlist: this.state.formlist.map(cell => {
@@ -281,7 +288,7 @@
      } else if (item.type === 'select' || item.type === 'multiselect') {
        content = (<MKSelect config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)} />)
      } else if (item.type === 'color') {
        content = (<MKColor config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
        content = (<MKColor config={item} allowClear={item.allowClear} onChange={(val) => this.recordChange({[item.field]: val})}/>)
      } else if (item.type === 'styleInput') {
        content = (<StyleInput config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
      } else if (item.type === 'radio') {
src/components/normalform/modalform/index.scss
@@ -42,6 +42,7 @@
    overflow: hidden;
    .color-sketch-block-box {
      min-width: 50px;
      max-width: 100px;
      .color-sketch-block-inner {
        box-shadow: 0 0 0 1px rgba(0, 0, 0, .1) inset;
      }
src/components/normalform/modalform/mkRadio/index.jsx
@@ -19,10 +19,22 @@
  componentDidMount () {
    MKEmitter.addListener('mkFP', this.mkFormHandle)
    MKEmitter.addListener('mkFC', this.mkFormControl)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { config } = this.state
    if (!is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) {
      this.setState({
        config: fromJS(nextProps.config).toJS(),
        options: fromJS(nextProps.config.options).toJS()
      })
    }
  }
  componentWillUnmount () {
@@ -30,6 +42,16 @@
      return
    }
    MKEmitter.removeListener('mkFP', this.mkFormHandle)
    MKEmitter.removeListener('mkFC', this.mkFormControl)
  }
  mkFormControl = (type, field, value) => {
    if (field !== this.props.config.field) return
    if (type === 'input') {
      this.setState({value})
      this.props.onChange(value, {})
    }
  }
  mkFormHandle = (field, parentId) => {
@@ -45,7 +67,7 @@
      value: val
    })
    this.props.onChange(val)
    this.props.onChange(val, {})
    config.linkFields && config.linkFields.forEach((m, i) => {
      setTimeout(() => {
src/components/normalform/modalform/mkSelect/index.jsx
@@ -159,8 +159,8 @@
        filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
        onChange={this.mutilselectChange}
      >
        {options.map(option =>
          <Select.Option key={option.value} disabled={option.disabled} value={option.value}>{option.label || option.text}</Select.Option>
        {options.map((option, i) =>
          <Select.Option key={i} disabled={option.disabled} value={option.value || option.field}>{option.label || option.text}</Select.Option>
        )}
      </Select>)
    }
src/index.js
@@ -57,6 +57,7 @@
    GLOB.mkHS = false
    GLOB.debugger = false
    GLOB.dataFormat = false
    GLOB.upStatus = false
    GLOB.navBar = 'shutter' // 默认为百叶窗
    GLOB.style = 'bg_black_style_blue'
@@ -94,6 +95,7 @@
      GLOB.probation = true
      GLOB.debugger = true
      GLOB.systemType = ''
      GLOB.upStatus = config.updateStatus + '' !== 'false'
      // GLOB.mainSystemApi = 'https://cloud.positecgroup.com/webapi/dostars'
src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -60,6 +60,7 @@
  let linkTypes = [
    { value: 'tel', text: '电话' },
    { value: 'email', text: '邮箱' },
    { value: 'download', text: '下载' },
    { value: 'other', text: '其他' }
  ]
@@ -69,6 +70,7 @@
      { value: 'email', text: '邮箱' },
      { value: 'qywx', text: '企业微信' },
      { value: 'linkmenu', text: '关联菜单' },
      { value: 'download', text: '下载' },
      { value: 'other', text: '其他' }
    ]
  } else if (appType === 'pc') {
@@ -76,6 +78,7 @@
      { value: 'tel', text: '电话' },
      { value: 'email', text: '邮箱' },
      { value: 'linkmenu', text: '关联菜单' },
      { value: 'download', text: '下载' },
      { value: 'other', text: '其他' }
    ]
  }
src/menu/components/card/cardcellcomponent/index.jsx
@@ -454,11 +454,11 @@
              let style = {}
              if (res.class === 'default') {
                style.color = 'rgba(0, 0, 0, 0.65)'
                style.backgroundColor = '#fff'
                style.backgroundColor = 'transparent'
                style.borderColor = '#d9d9d9'
              } else if (res.class.indexOf('border') > -1) {
                style.color = color[cl]
                style.backgroundColor = '#fff'
                style.backgroundColor = 'transparent'
                style.borderColor = color[cl]
              } else {
                style.color = '#ffffff'
src/menu/components/card/cardcomponent/index.jsx
@@ -157,7 +157,7 @@
    const { card, side } = this.state
    let _style = null
    let options = ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear']
    let options = ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear', 'overflow']
    if (side === 'front') {
      _style = card.style ? fromJS(card.style).toJS() : {}
    } else if (side === 'back') {
src/menu/components/card/data-card/options.jsx
@@ -267,7 +267,8 @@
      options: [
        {value: 'none', label: '无'},
        {value: 'active', label: '外阴影'},
        {value: 'backFont', label: '背景+文字'},
        {value: 'backFont', label: '背景(浅)+文字(深)'},
        {value: 'deepBackFont', label: '背景(深)+文字(浅)'},
        {value: 'font', label: '文字'},
        {value: 'tabs', label: '标签页'},
        ...(subtype === 'datacard' ? [
src/menu/components/card/doublecardcomponent/index.jsx
@@ -122,7 +122,7 @@
    const { card } = this.state
    let _style = null
    let options = ['height', 'background', 'border', 'padding', 'margin', 'shadow']
    let options = ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'overflow']
    if (type === 'sub') {
      _style = fromJS(card.backStyle).toJS()
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -46,78 +46,77 @@
  return [
    {
      type: 'text',
      key: 'title',
      field: 'title',
      label: '标题',
      initVal: card.title,
      initval: card.title,
      required: false
    },
    {
      type: 'text',
      key: 'name',
      field: 'name',
      label: '组件名称',
      initVal: card.name,
      initval: card.name,
      tooltip: '用于组件间的区分。',
      required: true
    },
    {
      type: 'number',
      key: 'width',
      field: 'width',
      label: '宽度',
      initVal: card.width,
      initval: card.width,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      decimal: 0,
      precision: 0,
      required: true
    },
    {
      type: 'styleInput',
      key: 'height',
      field: 'height',
      label: '图表高度',
      initVal: card.height,
      initval: card.height,
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
      key: 'permission',
      field: 'permission',
      label: '权限验证',
      initVal: card.permission || 'false',
      initval: card.permission || 'false',
      required: false,
      options: [
        {value: 'true', text: '启用'},
        {value: 'false', text: '禁用'},
        {value: 'true', label: '启用'},
        {value: 'false', label: '禁用'},
      ],
      forbid: !appType || ispop || isprint
    },
    {
      type: 'radio',
      key: 'cacheLocal',
      field: 'cacheLocal',
      label: '本地缓存',
      initVal: card.cacheLocal || 'true',
      initval: card.cacheLocal || 'true',
      required: false,
      options: [
        {value: 'true', text: '继承菜单'},
        {value: 'false', text: '禁用'},
        {value: 'true', label: '继承菜单'},
        {value: 'false', label: '禁用'},
      ],
      forbid: ispop || isprint
    },
    {
      type: 'select',
      key: 'blacklist',
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
      initVal: card.blacklist || [],
      multi: true,
      initval: card.blacklist || [],
      required: false,
      options: roleList,
      forbid: !!appType || isprint
    },
    {
      type: 'radio',
      key: 'click',
      field: 'click',
      label: '点击事件',
      initVal: card.click || '',
      initval: card.click || '',
      tooltip: '点击柱子时触发的事件,启用自定义设置时无效。',
      required: false,
      forbid: appType === 'mob' || card.chartType !== 'bar',
@@ -125,13 +124,20 @@
        {value: '', label: '数据切换'},
        {value: 'menu', label: '菜单'},
        {value: 'menus', label: '菜单组'}
      ],
      controlFields: [
        {field: 'menu', values: ['menu']},
        {field: 'open', values: ['menu', 'menus']},
        {field: 'joint', values: ['menu', 'menus']},
        {field: 'menuType', values: ['menus']},
        {field: 'menus', values: ['menus']},
      ]
    },
    {
      type: appType === '' ? 'cascader' : 'select',
      key: 'menu',
      field: 'menu',
      label: '关联菜单',
      initVal: card.menu || (appType === '' ? [] : ''),
      initval: card.menu || (appType === '' ? [] : ''),
      tooltip: '在使用柱形图且未启用自定义设置时有效。',
      required: true,
      forbid: appType === 'mob' || card.chartType !== 'bar',
@@ -140,9 +146,9 @@
    },
    {
      type: 'select',
      key: 'menuType',
      field: 'menuType',
      label: '菜单类型',
      initVal: card.menuType || '',
      initval: card.menuType || '',
      required: true,
      forbid: appType === 'mob' || card.chartType !== 'bar',
      hidden: card.click !== 'menus',
@@ -150,9 +156,9 @@
    },
    {
      type: 'radio',
      key: 'open',
      field: 'open',
      label: '打开方式',
      initVal: card.open || 'blank',
      initval: card.open || 'blank',
      required: false,
      options: [
        {value: 'blank', label: '新窗口'},
@@ -163,9 +169,9 @@
    },
    {
      type: 'radio',
      key: 'joint',
      field: 'joint',
      label: '参数拼接',
      initVal: card.joint || 'true',
      initval: card.joint || 'true',
      required: false,
      options: [
        {value: 'true', label: '是'},
@@ -176,9 +182,9 @@
    },
    {
      type: 'table',
      key: 'menus',
      field: 'menus',
      label: '菜单组',
      initVal: card.menus || [],
      initval: card.menus || [],
      required: true,
      span: 24,
      actions: ['view'],
@@ -234,10 +240,11 @@
    shapes = [
      { field: 'rect', label: 'rect(矩形)' },
      { field: 'hollow-rect', label: 'hollow-rect(空心矩形)' },
      { field: 'line', label: 'line(线条)' },
      { field: 'tick', label: 'tick(波动)' },
      // { field: 'funnel', label: 'funnel' },
      { field: 'pyramid', label: 'pyramid(角锥)' }
      // { field: 'hollow', label: 'hollow(空心矩形)' },
      // { field: 'line', label: 'line(线条)' },
      // { field: 'tick', label: 'tick(波动)' },
      // { field: 'funnel', label: 'funnel(漏斗图)' },
      { field: 'pyramid', label: 'pyramid(金字塔)' }
    ]
  }
@@ -246,68 +253,92 @@
  let labelOptions = [{
    value: 'false',
    text: '隐藏'
    label: '隐藏'
  }, {
    value: 'true',
    text: '显示'
    label: '显示'
  }]
  if (card.chartType === 'bar') {
    labelOptions[1].text = '外部'
    labelOptions[1].label = '外部'
    labelOptions.push(...[{
      value: 'top',
      text: '顶部'
      label: '顶部'
    }, {
      value: 'middle',
      text: '中间'
      label: '中间'
    }, {
      value: 'bottom',
      text: '底部'
      label: '底部'
    }])
  }
  let _label = card.label || 'false'
  let axis = []
  if (card.grid !== 'hidden') {
    axis.push('grid')
  }
  if (card.x_line !== 'hidden') {
    axis.push('x_line')
  }
  if (card.y_line !== 'hidden') {
    axis.push('y_line')
  }
  if (card.tick !== 'hidden') {
    axis.push('tick')
  }
  let tickVals = []
  if (card.x_label !== 'hidden') {
    tickVals.push('x_label')
  }
  if (card.y_label !== 'hidden') {
    tickVals.push('y_label')
  }
  return [
    {
      type: 'radio',
      key: 'datatype',
      field: 'datatype',
      label: '数据类型',
      initVal: card.datatype || 'query',
      initval: card.datatype || 'query',
      tooltip: '统计图表适用于展示数据类型为动态值。',
      required: false,
      $trans: true,
      options: [
        { value: 'query', text: '查询' },
        { value: 'statistics', text: '统计' }
        { value: 'query', label: '查询' },
        { value: 'statistics', label: '统计' }
      ],
      controlFields: [
        {field: 'InfoType', values: ['statistics']},
        {field: 'InfoValue', values: ['statistics']},
        {field: 'Yaxis', values: ['query']},
      ]
    }, {
      type: 'select',
      key: 'Xaxis',
      field: 'Xaxis',
      label: 'X-轴',
      initVal: card.Xaxis || '',
      initval: card.Xaxis || '',
      required: true,
      options: xfields
    }, {
      type: 'select',
      key: 'InfoType',
      field: 'InfoType',
      label: '类型',
      initVal: card.InfoType || '',
      hidden: card.datatype !== 'statistics',
      initval: card.InfoType || '',
      required: true,
      options: xfields
    }, {
      type: 'select',
      key: 'InfoValue',
      field: 'InfoValue',
      label: '值',
      initVal: card.InfoValue || '',
      hidden: card.datatype !== 'statistics',
      initval: card.InfoValue || '',
      required: true,
      options: yfields
    }, {
      type: 'select',
      key: 'legend',
      field: 'legend',
      label: '图例位置',
      initVal: card.legend || 'bottom',
      initval: card.legend || 'bottom',
      required: false,
      options: [
        { field: 'bottom', label: '下' },
@@ -325,310 +356,341 @@
        { field: 'hidden', label: '隐藏' }
      ]
    }, {
      type: 'select',
      key: 'Yaxis',
      type: 'multiselect',
      field: 'Yaxis',
      label: 'Y-轴',
      initVal: card.Yaxis || [],
      multi: true, // 多选
      hidden: card.datatype === 'statistics',
      initval: card.Yaxis || [],
      required: true,
      options: yfields
    }, {
      type: 'select',
      key: 'shape',
      field: 'shape',
      label: '形状',
      initVal: card.shape || (shapes[0] && shapes[0].field),
      initval: card.shape || (shapes[0] && shapes[0].field),
      required: false,
      options: shapes
    }, {
      type: 'radio',
      key: 'tooltip',
      field: 'tooltip',
      label: '悬浮提示',
      initVal: card.tooltip || 'true',
      initval: card.tooltip || 'true',
      required: false,
      options: [{
        value: 'true',
        text: '显示'
        label: '显示'
      }, {
        value: 'false',
        text: '隐藏'
        label: '隐藏'
      }]
    }, {
      type: 'radio',
      key: 'point',
      field: 'point',
      label: '点图',
      initVal: card.point || 'false',
      initval: card.point || 'false',
      required: false,
      forbid: !['line'].includes(card.chartType),
      options: [{
        value: 'true',
        text: '显示'
        label: '显示'
      }, {
        value: 'false',
        text: '隐藏'
        label: '隐藏'
      }]
    }, {
      type: 'radio',
      key: 'transpose',
      field: 'transpose',
      label: '变换',
      initVal: card.transpose || 'false',
      initval: card.transpose || 'false',
      tooltip: '横纵坐标轴交换',
      forbid: card.chartType === 'line',
      required: false,
      options: [{
        value: 'true',
        text: '是'
        label: '是'
      }, {
        value: 'false',
        text: '否'
        label: '否'
      }]
    }, {
      type: 'radio',
      key: 'show',
      field: 'show',
      label: '显示',
      initVal: card.show || 'value',
      initval: card.show || 'value',
      tooltip: '当使用自定义设置时,可在显示(值/%)处单独设置显示类型。注:自定义为空时使用此处设置。',
      required: false,
      options: [{
        value: 'value',
        text: '数值'
        label: '数值'
      }, {
        value: 'percent',
        text: '百分比'
        label: '百分比'
      }, {
        value: 'thdSeparator',
        label: '千分位'
      }]
    }, {
      type: labelOptions.length > 20 ? 'select' : 'radio',
      key: 'label',
      type: 'radio',
      field: 'label',
      label: '标注',
      initVal: _label,
      initval: card.label || 'false',
      tooltip: '图形节点处的数值。',
      required: false,
      options: labelOptions
      options: labelOptions,
      controlFields: [
        {field: 'labelColor', values: ['true']}
      ]
    }, {
      type: 'radio',
      key: 'labelColor',
      field: 'labelColor',
      label: '标注颜色',
      initVal: card.labelColor || 'system',
      initval: card.labelColor || 'system',
      tooltip: '使用系统色时,使用色系选项设置的系统颜色,使用自定义为颜色设置中定义的图形颜色。',
      required: false,
      hidden: _label !== 'true',
      options: [{
        value: 'system',
        text: '系统'
        label: '系统'
      }, {
        value: 'custom',
        text: '自定义'
        label: '自定义'
      }]
    // }, {
    //   type: 'radio',
    //   field: 'labelValue',
    //   label: '标注值',
    //   initval: card.labelValue || 'default',
    //   tooltip: '标注值的显示规则。',
    //   required: false,
    //   options: [{
    //     value: 'default',
    //     label: '默认'
    //   }, {
    //     value: 'zero',
    //     label: '隐藏 0 值'
    //   }],
    }, {
      type: 'radio',
      key: 'labelValue',
      label: '标注值',
      initVal: card.labelValue || 'default',
      tooltip: '标注值的显示规则。',
      required: false,
      hidden: _label === 'false',
      options: [{
        value: 'default',
        text: '默认'
      }, {
        value: 'zero',
        text: '隐藏 0 值'
      }],
    }, {
      type: 'radio',
      key: 'adjust',
      field: 'adjust',
      label: '多柱排列',
      initVal: card.adjust || 'dodge',
      initval: card.adjust || 'dodge',
      required: false,
      forbid: !['bar'].includes(card.chartType),
      options: [{
        value: 'dodge',
        text: '分组'
        label: '分组'
      }, {
        value: 'stack',
        text: '堆叠'
        label: '堆叠'
      }]
    }, {
      type: 'radio',
      key: 'area',
      field: 'area',
      label: '面积图',
      initVal: card.area || 'false',
      // tooltip: '仅在形状为smooth时有效。',
      initval: card.area || 'false',
      required: false,
      forbid: ['bar'].includes(card.chartType),
      options: [{
        value: 'true',
        text: '显示'
        label: '显示'
      }, {
        value: 'false',
        text: '不显示'
        label: '不显示'
      }]
    }, {
      type: 'radio',
      key: 'repeat',
      field: 'repeat',
      label: '重复数据',
      initVal: card.repeat || 'unrepeat',
      initval: card.repeat || 'unrepeat',
      required: false,
      options: [{
        value: 'unrepeat',
        text: '去重'
        label: '去重'
      }, {
        value: 'average',
        text: '平均'
        label: '平均'
      }, {
        value: 'cumsum',
        text: '累加'
        label: '累加'
      }]
    }, {
      type: 'radio',
      key: 'coordinate',
      field: 'coordinate',
      label: '坐标',
      initVal: card.coordinate || 'angle',
      initval: card.coordinate || 'angle',
      required: false,
      forbid: card.chartType === 'line',
      options: [{
        value: 'angle',
        text: '二维坐标'
        label: '二维坐标'
      }, {
        value: 'polar',
        text: '极坐标'
        label: '极坐标'
      }]
    }, {
      type: 'radio',
      key: 'grid',
      label: '网格线',
      initVal: card.grid || 'show',
      type: 'checkbox',
      field: 'axis',
      label: '坐标轴',
      initval: axis,
      required: false,
      options: [{
        value: 'show',
        text: '显示'
        value: 'grid',
        label: '网格线'
      }, {
        value: 'hidden',
        text: '隐藏'
      }]
        value: 'x_line',
        label: 'X轴'
      }, {
        value: 'y_line',
        label: 'Y轴'
      }, {
        value: 'tick',
        label: '刻度线'
      }],
      controlFields: [
        {field: 'lineColor', notNull: true},
      ]
    }, {
      type: 'radio',
      key: 'y_line',
      label: 'y轴边线',
      initVal: card.y_line || 'hidden',
      tooltip: '图形左侧或右侧的边线。',
      type: 'checkbox',
      field: 'tickVals',
      label: '刻度值',
      initval: tickVals,
      required: false,
      options: [{
        value: 'show',
        text: '显示'
        value: 'x_label',
        label: 'X轴'
      }, {
        value: 'hidden',
        text: '隐藏'
      }]
        value: 'y_label',
        label: 'Y轴'
      }],
      controlFields: [
        {field: 'color', notNull: true},
      ]
    // }, {
    //   type: 'radio',
    //   field: 'grid',
    //   label: '网格线',
    //   initval: card.grid || 'show',
    //   required: false,
    //   options: [{
    //     value: 'show',
    //     label: '显示'
    //   }, {
    //     value: 'hidden',
    //     label: '隐藏'
    //   }]
    // }, {
    //   type: 'radio',
    //   field: 'y_line',
    //   label: 'y轴边线',
    //   initval: card.y_line || 'hidden',
    //   tooltip: '图形左侧或右侧的边线。',
    //   required: false,
    //   options: [{
    //     value: 'show',
    //     label: '显示'
    //   }, {
    //     value: 'hidden',
    //     label: '隐藏'
    //   }]
    }, {
      type: 'radio',
      key: 'download',
      field: 'download',
      label: '导出图片',
      initVal: card.download || 'forbid',
      initval: card.download || 'forbid',
      required: false,
      forbid: appType === 'mob',
      options: [{
        value: 'forbid',
        text: '禁用'
        label: '禁用'
      }, {
        value: 'enable',
        text: '启用'
        label: '启用'
      }]
    }, {
      type: 'radio',
      key: 'empty',
      field: 'empty',
      label: '空值隐藏',
      initVal: card.empty || 'show',
      initval: card.empty || 'show',
      tooltip: '当查询数据为空时,隐藏该组件。',
      required: false,
      options: [
        {value: 'show', text: '否'},
        {value: 'hidden', text: '是'},
        {value: 'show', label: '否'},
        {value: 'hidden', label: '是'},
      ],
    }, {
      type: 'number',
      key: 'barSize',
      field: 'barSize',
      label: '柱形宽度',
      tooltip: '空值时,宽度自适应。',
      min: 5,
      max: 100,
      decimal: 0,
      initVal: card.barSize,
      max: 200,
      precision: 0,
      initval: card.barSize,
      forbid: !['bar'].includes(card.chartType),
      required: false
    }, {
      type: 'number',
      key: 'barRadius',
      field: 'barRadius',
      label: '柱形圆角',
      tooltip: '柱形图上端圆角。',
      min: 0,
      max: 200,
      decimal: 0,
      initVal: card.barRadius || 0,
      precision: 0,
      initval: card.barRadius || 0,
      forbid: !['bar'].includes(card.chartType),
      required: false
    }, {
      type: 'number',
      key: 'min',
      field: 'min',
      label: '最小值',
      tooltip: 'y轴最小值,为空时自适应。',
      initVal: card.min,
      initval: card.min,
      required: false
    }, {
      type: 'number',
      key: 'max',
      field: 'max',
      label: '最大值',
      tooltip: 'y轴最大值,为空时自适应。',
      initVal: card.max,
      initval: card.max,
      required: false
    }, {
      type: 'number',
      key: 'XLimit',
      field: 'XLimit',
      min: 2,
      label: '字符限制',
      tooltip: 'X轴最大字符限制。',
      initVal: card.XLimit || 11,
      initval: card.XLimit || 11,
      forbid: appType === 'mob',
      required: false
    }, {
      type: 'color',
      key: 'color',
      label: '色系',
      initVal: card.color || 'rgba(0, 0, 0, 0.65)',
      tooltip: '坐标轴提示文字及示例的颜色。',
      required: false
    }, {
      type: 'color',
      key: 'lineColor',
      label: '轴线颜色',
      initVal: card.lineColor,
      tooltip: '坐标轴线的颜色,包括x轴、y轴及网格线。',
      field: 'lineColor',
      label: '坐标轴颜色',
      initval: card.lineColor || '',
      tooltip: '坐标轴线的颜色,包括x轴、y轴、网格线、刻度线。',
      allowClear: true,
      required: false
    }, {
      type: 'color',
      key: 'selectColor',
      label: '选中颜色',
      initVal: card.selectColor || '',
      tooltip: '选中柱形图的颜色,在交互效果《元素选中(多选)》和《元素选中(单选)》中有效,启用自定义设置时无效。',
      forbid: !['bar'].includes(card.chartType),
      field: 'color',
      label: '刻度值颜色',
      initval: card.color || '',
      allowClear: true,
      required: false
    }, {
      type: 'number',
      key: 'rotate',
      field: 'rotate',
      label: '旋转',
      tooltip: '坐标轴标注文本的旋转角度。',
      min: 0,
      max: 360,
      decimal: 0,
      initVal: card.rotate,
      precision: 0,
      initval: card.rotate,
      forbid: appType !== 'mob',
      required: false
    }, {
      type: 'select',
      key: 'interaction',
      type: 'multiselect',
      field: 'interaction',
      label: '交互效果',
      initVal: card.interaction || [],
      multi: true,
      initval: card.interaction || [],
      required: false,
      forbid: appType === 'mob',
      options: [
@@ -644,7 +706,19 @@
        { value: 'legend-active', label: '图例聚焦' },
        { value: 'legend-highlight', label: '图例高亮' },
        { value: 'brush', label: '选框过滤' },
      ],
      controlFields: [
        {field: 'selectColor', values: ['element-selected', 'element-single-selected']},
      ]
    }, {
      type: 'color',
      field: 'selectColor',
      label: '选中颜色',
      initval: card.selectColor || '',
      tooltip: '选中柱形图的颜色,启用自定义设置时无效。',
      forbid: !['bar'].includes(card.chartType),
      allowClear: true,
      required: false
    }
  ]
}
src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -1,19 +1,18 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Form, Row, Col, Select, Radio, notification, Tooltip, Input, InputNumber, Tabs, Button } from 'antd'
import { QuestionCircleOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons'
import { fromJS } from 'immutable'
import { Modal, Form, Col, Radio, notification, Tabs, Button } from 'antd'
import { EditOutlined, PlusOutlined } from '@ant-design/icons'
import Utils from '@/utils/utils.js'
import { chartColors } from '@/utils/option.js'
import { getBaseForm, getOptionForm } from './formconfig'
import asyncComponent from '@/utils/asyncComponent'
import ColorSketch from '@/mob/colorsketch'
import './index.scss'
const { TabPane } = Tabs
const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
const NormalForm = asyncComponent(() => import('@/menu/components/share/normalform'))
const ModalForm = asyncComponent(() => import('@/components/normalform/modalform'))
class LineChartDrawerForm extends Component {
  static propTpyes = {
@@ -24,7 +23,6 @@
  state = {
    view: 'base',
    ramp: 'false',
    visible: false,
    datatype: '',
    plot: null,
@@ -137,12 +135,89 @@
        }
      },
    ],
    cusColumns: [
    cusColumns: []
  }
  showDrawer = () => {
    const { config } = this.props
    let fieldName = {}
    config.columns.forEach(col => {
      if (col.field) {
        fieldName[col.field] = col.label
      }
    })
    let plot = fromJS(config.plot).toJS()
    if (plot.datatype !== 'statistics') {
      if (plot.colors) {
        plot.colors = plot.colors.map(item => {
          if (fieldName[item.type]) {
            item.label = fieldName[item.type]
          }
          return item
        })
      }
      if (plot.customs) {
        plot.customs = plot.customs.map(item => {
          if (fieldName[item.type]) {
            item.name = fieldName[item.type]
          }
          return item
        })
      }
    }
    if (!plot.zoomYaxis && plot.customs) {
      plot.customs.forEach(item => {
        if (item.min || item.min === 0) {
          plot.zoomYaxis = 'custom'
        } else if (item.max || item.max === 0) {
          plot.zoomYaxis = 'custom'
        }
      })
    }
    plot.zoomYaxis = plot.zoomYaxis || 'default'
    this.setState({
      visible: true,
      view: 'base',
      datatype: plot.datatype || 'query',
      fieldName: fieldName,
      plot: plot,
      baseFormlist: getBaseForm(plot, config.columns),
      formlist: getOptionForm(plot, config.columns),
      cusColumns: this.getCusColumns(plot.zoomYaxis)
    })
  }
  optionChange = (val, key) => {
    let _plot = {...this.state.plot, [key]: val}
    if (key === 'ramp' && val === 'true') {
      _plot.colors = _plot.colors || []
      _plot.colors = _plot.colors.map(item => {
        item.color1 = item.color1 || item.color
        return item
      })
    }
    this.setState({plot: _plot}, () => {
      if (key === 'zoomYaxis') {
        this.setState({cusColumns: this.getCusColumns(val)})
      }
    })
  }
  getCusColumns = (zoomYaxis) => {
    let cusColumns = [
      {
        title: '指标',
        dataIndex: 'name',
        editable: false,
        width: '14%'
        width: '12%'
      },
      {
        title: '形状',
@@ -158,26 +233,26 @@
            value: 'line',
            label: '折线',
            children: [
              { value: 'smooth', label: 'smooth' },
              { value: 'line', label: 'line' },
              { value: 'dot', label: 'dot' },
              { value: 'dash', label: 'dash' },
              { value: 'hv', label: 'hv' },
              { value: 'vh', label: 'vh' },
              { value: 'hvh', label: 'hvh' },
              { value: 'vhv', label: 'vhv' }
              { value: 'smooth', label: 'smooth(平滑线)' },
              { value: 'line', label: 'line(直线)' },
              { value: 'dot', label: 'dot(点状线)' },
              { value: 'dash', label: 'dash(虚线)' },
              { value: 'hv', label: 'hv(水平-垂直线)' },
              { value: 'vh', label: 'vh(垂直-水平线)' },
              { value: 'hvh', label: 'hvh(水平-垂直-水平线)' },
              { value: 'vhv', label: 'vhv(垂直-水平-垂直线)' }
            ]
          },
          {
            value: 'bar',
            label: '柱形',
            children: [
              { value: 'rect', label: 'rect' },
              { value: 'hollow-rect', label: 'hollow-rect' },
              { value: 'line', label: 'line' },
              { value: 'tick', label: 'tick' },
              { value: 'funnel', label: 'funnel' },
              { value: 'pyramid', label: 'pyramid' }
              { value: 'rect', label: 'rect(矩形)' },
              { value: 'hollow-rect', label: 'hollow-rect(空心矩形)' },
              // { value: 'line', label: 'line(线条)' },
              // { value: 'tick', label: 'tick(波动)' },
              // { value: 'funnel', label: 'funnel(漏斗图)' },
              { value: 'pyramid', label: 'pyramid(金字塔)' }
            ],
          }
        ]
@@ -209,7 +284,7 @@
        ],
        render: (text, record) => {
          let trans = {'true': '显示', 'false': '隐藏'}
          return trans[text] || '隐藏'
          return trans[text] || ''
        }
      },
      {
@@ -237,10 +312,11 @@
        width: '12%',
        options: [
          { value: 'value', text: '数值'},
          { value: 'percent', text: '百分比'}
          { value: 'percent', text: '百分比'},
          { value: 'thdSeparator', text: '千分位'}
        ],
        render: (text, record) => {
          let trans = {'value': '数值', 'percent': '百分比'}
          let trans = {value: '数值', percent: '百分比', thdSeparator: '千分位'}
          return trans[text] || ''
        }
      },
@@ -249,6 +325,7 @@
        dataIndex: 'min',
        inputType: 'number',
        editable: true,
        max: 9999999999,
        required: false,
        width: '12%'
      },
@@ -257,267 +334,21 @@
        dataIndex: 'max',
        inputType: 'number',
        editable: true,
        max: 9999999999,
        required: false,
        width: '12%'
      },
    ]
  }
  showDrawer = () => {
    const { config } = this.props
    let fieldName = {}
    config.columns.forEach(col => {
      if (col.field) {
        fieldName[col.field] = col.label
      }
    })
    let plot = fromJS(config.plot).toJS()
    if (plot.correction) {
      delete plot.correction // 数据修正(已弃用)
      plot.barSize = 35
    }
    if (plot.datatype !== 'statistics') {
      if (plot.colors) {
        plot.colors = plot.colors.map(item => {
          if (fieldName[item.type]) {
            item.label = fieldName[item.type]
          }
          return item
        })
      }
      if (plot.customs) {
        plot.customs = plot.customs.map(item => {
          if (fieldName[item.type]) {
            item.name = fieldName[item.type]
          }
          return item
        })
      }
    }
    this.setState({
      visible: true,
      view: 'base',
      ramp: plot.ramp || 'false',
      datatype: plot.datatype || 'query',
      fieldName: fieldName,
      plot: plot,
      baseFormlist: getBaseForm(plot, config.columns),
      formlist: getOptionForm(plot, config.columns)
    })
  }
  radioChange = (e, key) => {
    const { formlist } = this.state
    let val = e.target.value
    if (key === 'datatype') {
      this.setState({
        datatype: val,
        formlist: fromJS(formlist).toJS().map(item => {
          if (['Yaxis'].includes(item.key)) {
            item.hidden = val === 'statistics'
          } else if (['InfoType', 'InfoValue'].includes(item.key)) {
            item.hidden = val !== 'statistics'
          }
          return item
        })
      })
    } else if (key === 'label') {
      this.setState({formlist: fromJS(formlist).toJS().map(cell => {
        if (!['labelColor', 'labelValue'].includes(cell.key)) return cell
        if (cell.key === 'labelColor') {
          if (val !== 'true') {
            cell.hidden = true
          } else {
            cell.hidden = false
          }
        } else {
          if (val === 'false') {
            cell.hidden = true
          } else {
            cell.hidden = false
          }
        }
        return cell
      })})
    }
  }
  getFields() {
    const { formlist } = this.state
    const { getFieldDecorator } = this.props.form
    const fields = []
    if (!formlist) {
      return fields
    }
    formlist.forEach((item, index) => {
      if (item.hidden || item.forbid) return
      if (item.type === 'text') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.onSubmit}/>)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: '请输入' + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.onSubmit}/>)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
                <Select mode={item.multi ? 'multiple' : ''}>
                  {item.options.map((option, index) =>
                    <Select.Option key={index} value={option.field || option.value}>
                      {option.label || option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'radio') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: '请选择' + item.label + '!'
                  }
                ]
              })(
                <Radio.Group style={{whiteSpace: 'nowrap'}} disabled={item.readonly} onChange={(e) => this.radioChange(e, item.key)}>
                  {item.options.map(option => {
                    return (
                      <Radio key={option.value} value={option.value}>{option.text}</Radio>
                    )
                  })}
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'color') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <QuestionCircleOutlined className="mk-form-tip" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal
              })(
                <ColorSketch allowClear={item.allowClear} />
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  enabledChange = (e) => {
    const { plot } = this.state
    let val = e.target.value
    this.setState({plot: {...plot, enabled: val}})
  }
  mutilBarChange = (e) => {
    const { plot } = this.state
    let val = e.target.value
    this.setState({plot: {...plot, mutilBar: val}})
  }
  rampChange = (e) => {
    const { plot } = this.state
    let val = e.target.value
    let colors = plot.colors || []
    if (val === 'true') {
      colors = colors.map(item => {
        item.color1 = item.color1 || item.color
        return item
    if (zoomYaxis !== 'custom') {
      cusColumns.pop()
      cusColumns.pop()
      cusColumns.forEach(item => {
        item.width = '16%'
      })
    }
    this.setState({plot: {...plot, colors, ramp: val}, ramp: val})
  }
  rampDirectionChange = (e) => {
    const { plot } = this.state
    let val = e.target.value
    this.setState({plot: {...plot, rampDirection: val}})
    return cusColumns
  }
  onSubmit = () => {
@@ -525,90 +356,26 @@
    const { plot, view } = this.state
    if (view === 'normal') {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let _plot = {...plot, ...values}
      this.normalRef.handleConfirm().then(values => {
        let _plot = {...plot, ...values}
          if (values.datatype !== plot.datatype) {
            _plot.colors = null
          }
          if (values.datatype === 'statistics') {
            _plot.enabled = 'false'
            _plot.customs = []
            delete _plot.Yaxis
          } else if (!is(fromJS(values.Yaxis), fromJS(plot.Yaxis || []))) {
            _plot.enabled = 'false'
            _plot.colors = null
            let labels = {}
            config.columns.forEach(col => {
              labels[col.field] = col.label
            })
            let cus = {}
            _plot.customs && _plot.customs.forEach(m => {
              cus[m.type] = m
            })
            _plot.customs = _plot.Yaxis.map((item, i) => {
              if (cus[item]) return cus[item]
              return {
                uuid: Utils.getuuid(),
                type: item,
                name: labels[item] || item,
                axis: i === 0 ? 'true' : 'false',
                label: 'false',
                title: 'true',
                shape: _plot.chartType === 'bar' && i === 0 ? ['bar', 'rect'] : ['line', 'smooth']
              }
            })
          }
          this.setState({
            plot: _plot,
            visible: false
          })
          this.props.plotchange({...config, plot: _plot})
        if (_plot.datatype !== plot.datatype) {
          _plot.colors = null
        }
        this.resetPlot(_plot)
        this.setState({
          plot: _plot,
          visible: false
        })
        this.props.plotchange({...config, plot: _plot})
      })
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (res.click === 'menu') {
          delete _plot.menus
        } else if (res.click === 'menus') {
          delete _plot.menu
        } else {
          delete _plot.menus
          delete _plot.menu
        }
        delete _plot.MenuID
        delete _plot.MenuName
        delete _plot.MenuNo
        delete _plot.tabType
        if (_plot.click === 'menu' && sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.resetBase(_plot)
        this.setState({
          plot: _plot,
@@ -626,110 +393,28 @@
  }
  changeTab = (tab) => {
    const { config } = this.props
    const { plot, view } = this.state
    if (view === 'normal') {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let _plot = {...plot, ...values}
      this.normalRef.handleConfirm().then(values => {
        let _plot = {...plot, ...values}
          let labels = {}
          config.columns.forEach(col => {
            labels[col.field] = col.label
          })
          if (values.datatype !== plot.datatype) {
            _plot.colors = null
          }
          if (values.datatype === 'statistics') {
            _plot.enabled = 'false'
            _plot.customs = []
            delete _plot.Yaxis
          } else if (!is(fromJS(values.Yaxis), fromJS(plot.Yaxis || []))) {
            _plot.enabled = 'false'
            _plot.colors = null
            let cus = {}
            _plot.customs && _plot.customs.forEach(m => {
              cus[m.type] = m
            })
            _plot.customs = _plot.Yaxis.map((item, i) => {
              if (cus[item]) return cus[item]
              return {
                uuid: Utils.getuuid(),
                type: item,
                name: labels[item] || item,
                axis: i === 0 ? 'true' : 'false',
                label: 'false',
                title: 'true',
                shape: _plot.chartType === 'bar' && i === 0 ? ['bar', 'rect'] : ['line', 'smooth']
              }
            })
          }
          if (!_plot.colors) {
            _plot.colors = []
            if (_plot.datatype === 'query') {
              let limit = chartColors.length
              _plot.colors = _plot.Yaxis.map((item, i) => {
                return {
                  uuid: Utils.getuuid(),
                  type: item,
                  label: labels[item] || item,
                  color: chartColors[i % limit],
                  color1: chartColors[i % limit]
                }
              })
            }
          }
          this.setState({
            datatype: _plot.datatype,
            plot: _plot,
            view: tab
          })
        if (_plot.datatype !== plot.datatype) {
          _plot.colors = null
        }
        this.resetPlot(_plot)
        this.setState({
          plot: _plot,
          view: tab
        })
      })
    } else if (view === 'base') {
      this.baseRef.handleConfirm().then(res => {
        let _plot = {...plot, ...res}
        if (res.click === 'menu') {
          delete _plot.menus
        } else if (res.click === 'menus') {
          delete _plot.menu
        } else {
          delete _plot.menus
          delete _plot.menu
        }
        delete _plot.MenuID
        delete _plot.MenuName
        delete _plot.MenuNo
        delete _plot.tabType
        if (_plot.click === 'menu' && sessionStorage.getItem('appType') === '' && _plot.menu) {
          let list = null
          try {
            list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
          } catch (e) {
            list = []
          }
          let id = _plot.menu[_plot.menu.length - 1]
          list.forEach(item => {
            if (item.MenuID === id) {
              _plot.MenuID = id
              _plot.MenuName = item.MenuName
              _plot.MenuNo = item.MenuNo
              _plot.tabType = item.type
            }
          })
        }
        this.resetBase(_plot)
        if (!plot.Xaxis && (tab === 'color' || tab === 'custom')) {
          this.setState({
@@ -754,6 +439,130 @@
        view: tab
      })
    }
  }
  resetBase = (_plot) => {
    if (_plot.click === 'menu') {
      delete _plot.menus
      delete _plot.menuType
    } else if (_plot.click === 'menus') {
      delete _plot.menu
    } else {
      delete _plot.menus
      delete _plot.menu
      delete _plot.menuType
    }
    delete _plot.MenuID
    delete _plot.MenuName
    delete _plot.MenuNo
    delete _plot.tabType
    if (_plot.click === 'menu' && sessionStorage.getItem('appType') === '' && _plot.menu) {
      let list = null
      try {
        list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
      } catch (e) {
        list = []
      }
      let id = _plot.menu[_plot.menu.length - 1]
      list.forEach(item => {
        if (item.MenuID === id) {
          _plot.MenuID = id
          _plot.MenuName = item.MenuName
          _plot.MenuNo = item.MenuNo
          _plot.tabType = item.type
        }
      })
    }
  }
  resetPlot = (_plot) => {
    const { config } = this.props
    if (_plot.axis) {
      _plot.grid = _plot.axis.includes('grid') ? 'show' : 'hidden'
      _plot.x_line = _plot.axis.includes('x_line') ? 'show' : 'hidden'
      _plot.y_line = _plot.axis.includes('y_line') ? 'show' : 'hidden'
      _plot.tick = _plot.axis.includes('tick') ? 'show' : 'hidden'
      delete _plot.axis
    }
    if (_plot.tickVals) {
      _plot.x_label = _plot.tickVals.includes('x_label') ? 'show' : 'hidden'
      _plot.y_label = _plot.tickVals.includes('y_label') ? 'show' : 'hidden'
      delete _plot.tickVals
    }
    if (_plot.datatype === 'statistics') {
      _plot.enabled = 'false'
      _plot.customs = []
      _plot.colors = _plot.colors || []
      delete _plot.Yaxis
    } else if (_plot.Yaxis) {
      delete _plot.InfoType
      delete _plot.InfoValue
      let yaxis = JSON.parse(JSON.stringify(_plot.Yaxis))
      let caxis = _plot.customs ? _plot.customs.map(m => m.type) : []
      yaxis.sort()
      caxis.sort()
      if (JSON.stringify(yaxis) !== JSON.stringify(caxis)) {
        let labels = {}
        config.columns.forEach(col => {
          labels[col.field] = col.label
        })
        let cus = {}
        _plot.customs && _plot.customs.forEach(m => {
          cus[m.type] = m
        })
        _plot.customs = _plot.Yaxis.map((item, i) => {
          if (cus[item]) return cus[item]
          return {
            uuid: Utils.getuuid(),
            type: item,
            name: labels[item] || item,
            axis: i === 0 ? 'true' : 'false',
            label: _plot.label === 'false' ? 'false' : true,
            title: 'true',
            shape: _plot.chartType === 'bar' && i === 0 ? ['bar', 'rect'] : ['line', 'smooth']
          }
        })
        let cusColor = {}
        let limit = chartColors.length
        _plot.colors && _plot.colors.forEach(m => {
          cusColor[m.type] = m
        })
        _plot.colors = _plot.Yaxis.map((item, i) => {
          if (cusColor[item]) return cusColor[item]
          return {
            uuid: Utils.getuuid(),
            type: item,
            label: labels[item] || item,
            color: chartColors[i % limit],
            color1: chartColors[i % limit]
          }
        })
      }
    }
  }
  transVals = (values, key) => {
    if (key !== 'datatype') return
    this.setState({
      datatype: values.datatype
    })
  }
  addColor = () => {
@@ -802,7 +611,7 @@
  render() {
    const { config } = this.props
    const { view, visible, datatype, plot, ramp, colorColumns, barColorColumns, rampColorColumns, statColorColumns, rampStatColorColumns, cusColumns, baseFormlist } = this.state
    const { view, visible, datatype, plot, colorColumns, barColorColumns, rampColorColumns, statColorColumns, rampStatColorColumns, cusColumns, baseFormlist, formlist } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -820,28 +629,26 @@
        <Modal
          wrapClassName="mk-pop-modal"
          visible={visible}
          width={1000}
          width={1200}
          maskClosable={false}
          onOk={this.onSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          {config.name ? <div className="mk-com-name">{config.name} - 编辑</div> : null}
          <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
          <Tabs activeKey={view} className="menu-chart-line-edit-box" onChange={this.changeTab}>
            <TabPane tab="组件设置" key="base">
              <NormalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
              <ModalForm formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
            </TabPane>
            <TabPane tab="图表设置" key="normal">
              <Form {...formItemLayout}>
                <Row gutter={16}>{this.getFields()}</Row>
              </Form>
              <ModalForm formlist={formlist} inputSubmit={this.onSubmit} transVals={this.transVals} wrappedComponentRef={(inst) => this.normalRef = inst}/>
            </TabPane>
            {plot ? <TabPane tab="颜色设置" key="color">
              <div>
                <Col span={8} style={{height: '40px', top: '-5px', zIndex: 1}}>
                  <Form {...formItemLayout}>
                    <Form.Item label="渐变色" style={{marginBottom: 10}}>
                      <Radio.Group value={plot.ramp || 'false'} onChange={this.rampChange}>
                      <Radio.Group value={plot.ramp || 'false'} onChange={(e) => this.optionChange(e.target.value, 'ramp')}>
                        <Radio value="false">不使用</Radio>
                        <Radio value="true">使用</Radio>
                      </Radio.Group>
@@ -851,7 +658,7 @@
                {plot.chartType === 'line' ? <Col span={8} style={{height: '40px', top: '-5px', zIndex: 1}}>
                  <Form {...formItemLayout}>
                    <Form.Item label="渐变方向" style={{marginBottom: 10}}>
                      <Radio.Group value={plot.rampDirection || 'horizontal'} onChange={this.rampDirectionChange}>
                      <Radio.Group value={plot.rampDirection || 'horizontal'} onChange={(e) => this.optionChange(e.target.value, 'rampDirection')}>
                        <Radio value="horizontal">水平</Radio>
                        <Radio value="vertical">垂直</Radio>
                      </Radio.Group>
@@ -859,30 +666,30 @@
                  </Form>
                </Col> : null}
                {datatype === 'statistics' ? <Button className="color-add mk-green" onClick={this.addColor}>添加</Button> : null}
                {datatype === 'statistics' ? <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={ramp ==='true' ? rampStatColorColumns : statColorColumns} onChange={this.changeColor}/> : null}
                {datatype !== 'statistics' ? <EditTable actions={['edit']} data={plot.colors || []} columns={ramp ==='true' ? rampColorColumns : colorColumns} onChange={this.changeColor}/> : null}
                {datatype === 'statistics' ? <EditTable actions={['edit', 'move', 'del']} data={plot.colors || []} columns={plot.ramp ==='true' ? rampStatColorColumns : statColorColumns} onChange={this.changeColor}/> : null}
                {datatype !== 'statistics' ? <EditTable actions={['edit']} data={plot.colors || []} columns={plot.ramp ==='true' ? rampColorColumns : colorColumns} onChange={this.changeColor}/> : null}
                {plot.chartType === 'bar' && plot.datatype === 'query' ? <div className="mk-bar-colors">
                  <p>柱形颜色:可根据柱图序号设置颜色(请设置柱形宽度)。注:使用自定义图形设置或多根柱图时无效。</p>
                  <p>柱形颜色:可根据柱图序号设置颜色。注:使用自定义图形设置或多根柱图时无效。</p>
                  <div className="bar-color-add"><PlusOutlined onClick={this.addbarColor}/></div>
                  <EditTable actions={['edit', 'move', 'del']} data={plot.barcolors || []} columns={barColorColumns} onChange={this.changebarColor}/>
                </div> : null}
              </div>
            </TabPane> : null}
            {plot ? <TabPane tab="自定义图形设置" disabled={datatype === 'statistics'} key="custom">
              <Col span={12}>
              <Col span={8}>
                <Form {...formItemLayout}>
                  <Form.Item label="是否启用" style={{marginBottom: 10}}>
                    <Radio.Group value={plot.enabled || 'false'} onChange={this.enabledChange}>
                    <Radio.Group value={plot.enabled || 'false'} onChange={(e) => this.optionChange(e.target.value, 'enabled')}>
                      <Radio value="true">是</Radio>
                      <Radio value="false">否</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Form>
              </Col>
              <Col span={12}>
              <Col span={8}>
                <Form {...formItemLayout}>
                  <Form.Item label="多柱排列" style={{marginBottom: 10}}>
                    <Radio.Group value={plot.mutilBar || 'dodge'} onChange={this.mutilBarChange}>
                    <Radio.Group value={plot.mutilBar || 'dodge'} onChange={(e) => this.optionChange(e.target.value, 'mutilBar')}>
                      <Radio value="dodge">分组</Radio>
                      <Radio value="stack">堆叠</Radio>
                      <Radio value="overlap">重叠</Radio>
@@ -890,6 +697,17 @@
                  </Form.Item>
                </Form>
              </Col>
              <Col span={8}>
                <Form {...formItemLayout}>
                  <Form.Item label="Y轴区间" style={{marginBottom: 10}}>
                    <Radio.Group value={plot.zoomYaxis} onChange={(e) => this.optionChange(e.target.value, 'zoomYaxis')}>
                      <Radio value="default">默认</Radio>
                      <Radio value="custom">自定义</Radio>
                      <Radio value="adjust">自适应</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Form>
              </Col>
              <Col style={{fontSize: '12px', color: '#757575', paddingLeft: '10px'}} span={24}>注:使用自定义设置时,显示的坐标轴第一个在左侧,第二个在右侧,多余的不生效。</Col>
              <EditTable indexShow={false} actions={['edit', 'move']} data={plot.customs || []} columns={cusColumns} onChange={this.changeCustom}/>
            </TabPane> : null}
src/menu/components/chart/antv-bar/chartcompile/index.scss
@@ -4,14 +4,9 @@
    color: #1890ff;
  }
}
.menu-chart-edit-box {
.menu-chart-line-edit-box {
  .ant-radio-wrapper {
    margin-right: 5px;
  }
  .color-sketch-block {
    position: relative;
    top: 5px;
    width: 240px;
  }
  .color-add {
    float: right;
src/menu/components/chart/antv-bar/index.jsx
@@ -87,8 +87,14 @@
      this.updateComponent(_card, true)
    } else {
      let _card = fromJS(card).toJS()
      if (_card.plot.correction) {
        delete _card.plot.correction // 数据修正(已弃用)
        _card.plot.barSize = 35
      }
      this.setState({
        card: fromJS(card).toJS()
        card: _card
      })
    }
  }
@@ -581,6 +587,29 @@
        fill: '#fff'
      }
    }
    let label = plot.label
    if (Bar_axis.length) {
      if (label === 'false') {
        plot.customs.forEach(item => {
          if (!Bar_axis.includes(item.type)) return
          if (item.label === 'true') {
            label = 'true'
          }
        })
      } else {
        let reset = true
        plot.customs.forEach(item => {
          if (!Bar_axis.includes(item.type)) return
          if (item.label === 'true') {
            reset = false
          }
        })
        if (reset) {
          label = 'false'
        }
      }
    }
    if (plot.label === 'top') {
      lablecfg.offset = -5
@@ -605,6 +634,10 @@
      })
      const dst = new DataSet()
      const dvt = dst.createView().source(data)
      // if (plot.mutilBar === 'stack') {
      //   Bar_axis.reverse()
      // }
  
      dvt.transform({
        type: 'fold',
@@ -682,13 +715,13 @@
        } else {
          _chart.color('key')
        }
        if (plot.label !== 'false') {
        if (label !== 'false') {
          _chart.label('value*key', (value, key) => {
            if (plot.show === 'percent') {
              value = value + '%'
            }
            if (plot.label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
            if (label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
              lablecfg.style.fill = colors.get(key)
            }
            return {
@@ -698,7 +731,7 @@
          })
        }
        if (plot.barSize || plot.correction) {
        if (plot.barSize) {
          _chart.size(plot.barSize || 35)
        }
        if (plot.barRadius) {
@@ -733,13 +766,13 @@
        } else {
          _chart.color('key')
        }
        if (plot.label !== 'false') {
        if (label !== 'false') {
          _chart.label('value*key', (value, key) => {
            if (plot.show === 'percent') {
              value = value + '%'
            }
            if (plot.label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
            if (label === 'true' && plot.labelColor === 'custom' && colors.has(key)) {
              lablecfg.style.fill = colors.get(key)
            }
@@ -750,7 +783,7 @@
          })
        }
        if (plot.barSize || plot.correction) {
        if (plot.barSize) {
          _chart.size(plot.barSize || 35)
        }
        if (plot.barRadius) {
@@ -773,7 +806,7 @@
    view2.data(dv.rows)
    if (!noLegend) {
    if (!noLegend && Bar_axis.length) {
      view2.legend(false)
    }
@@ -1098,7 +1131,7 @@
          })
        }
        if (plot.barSize || plot.correction) {
        if (plot.barSize) {
          _chart.size(plot.barSize || 35)
        }
        if (plot.selectColor) {
@@ -1158,7 +1191,7 @@
          })
        }
        if (plot.barSize || plot.correction) {
        if (plot.barSize) {
          _chart.size(plot.barSize || 35)
        }
        if (plot.selectColor) {
@@ -1312,6 +1345,21 @@
    this.updateComponent(_card)
  }
  plotchange = (card) => {
    if (card.plot.enabled === 'true' && card.plot.zoomYaxis !== 'custom' && card.plot.customs) {
      card.plot.customs.forEach(item => {
        item.min = ''
        item.max = ''
      })
    }
    if (card.plot.barcolors && (card.plot.enabled === 'true' || card.plot.datatype === 'statistics')) {
      card.plot.barcolors = null
    }
    this.updateComponent(card)
  }
  clickComponent = (e) => {
    if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
      e.stopPropagation()
@@ -1336,7 +1384,7 @@
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            {appType !== 'mob' ? <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton}/> : null}
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <ChartCompileForm config={card} plotchange={this.plotchange}/>
            <CopyComponent type="line" card={card}/>
            <PasteComponent config={card} options={['action', 'search']} updateConfig={this.updateComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
src/menu/components/code/sandbox/editorcode/index.jsx
@@ -34,7 +34,7 @@
      visible: true,
      html: config.html || '',
      css: config.css || '',
      js: config.js || '',
      js: config.js || '// Function(data, result, Api, notification, systemType) data-数据列表,result-查询接口返回结果,Api-接口,notification-信息提示控件(移动端为Toast),systemType-系统类型(正式为 production,测试为空)',
    })
  }
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -669,7 +669,7 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      required: true,
      options: [{
        value: 'never',
@@ -697,7 +697,7 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      required: true,
      options: [{
        value: 'never',
@@ -1796,7 +1796,7 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用);@no_target_menu@ 不执行打开菜单。',
      required: true,
      options: [{
        value: 'never',
@@ -1821,7 +1821,7 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新哪一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新哪一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。' : '选择刷新行时,如果选择多条数据会刷新组件;选择刷新行 / 组件时,如果当前行数据不存在会刷新组件。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。返回信息(@retmsg)特殊标识:@close_tab@ 执行(关闭标签-管理系统);@close_popup@ 执行(关闭弹窗);@goback@ 执行(返回上一页-子应用)。',
      required: true,
      options: [{
        value: 'never',
src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
@@ -324,10 +324,10 @@
              取消
            </Button>
          </Col>
          {!type ? <Col span={3} style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}>
          <Col span={3} className="forced" style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}>
            强制保存:
            <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/>
          </Col> : null}
          </Col>
          <Col span={24} className="sql">
            <Form.Item label="sql">
              {getFieldDecorator('sql', {
src/menu/components/table/edit-table/options.jsx
@@ -54,17 +54,33 @@
      required: false
    },
    {
      type: 'radio',
      type: 'select',
      field: 'commit',
      label: '数据提交',
      initval: wrap.commit || 'all',
      tooltip: '设置为修改项时,在失去焦点且不存在必填项为空时触发提交。设置为修改项(全)时,在点击提交按钮时触发提交。',
      tooltip: '设置为修改项时,在失去焦点且不存在必填项为空时触发提交。设置为修改项(全)时,在点击提交按钮时触发提交。设置为勾选项时,只提交选中的数据,未选中数据时不可提交。',
      required: false,
      options: [
        {value: 'all', label: '全部'},
        {value: 'change', label: '修改项'},
        {value: 'amend', label: '修改项(全)'},
      ]
        {value: 'check', label: '勾选项'},
      ],
      reset_source: true,
      callback: (map, record, MKEmitter) => {
        let _tableType = map.get('tableType')
        _tableType.options[0].disabled = record.commit === 'check'
        _tableType.oriOptions[0].disabled = record.commit === 'check'
        map.set('tableType', _tableType)
        if (record.commit === 'check' && !record.tableType) {
          setTimeout(() => {
            MKEmitter.emit('mkFC', 'input', 'tableType', 'radio')
          }, 50)
        }
      }
    },
    {
      type: 'radio',
@@ -97,7 +113,7 @@
      initval: wrap.tableType || '',
      required: false,
      options: [
        {value: '', label: '不可选'},
        {value: '', label: '不可选', disabled: wrap.commit === 'check'},
        {value: 'radio', label: '单选'},
        {value: 'checkbox', label: '多选'},
      ]
src/menu/components/tabs/antv-tabs/index.jsx
@@ -265,6 +265,14 @@
      delete res.controlVals
    }
    res.tabStyle = res.tabStyle || 'line'
    res.cusClass = ''
    if (!['line', 'card'].includes(res.tabStyle)) {
      res.cusClass = res.tabStyle
      res.tabStyle = 'line'
    }
    tabs.setting = res
    this.updateComponent(tabs)
@@ -280,7 +288,7 @@
    let _style = resetStyle(tabs.style)
    return (
      <div className={'menu-tabs-edit-box ' + (tabs.setting.display || '')} style={_style} id={tabs.uuid}>
      <div className="menu-tabs-edit-box" style={_style} id={tabs.uuid}>
        <DraggableTabs defaultActiveKey={defaultActiveKey} tabBarStyle={{background: tabs.setting.backgroundColor || 'transparent'}} tabPosition={tabs.setting.position} type={tabs.setting.tabStyle} tabsMove={this.moveSwitch} onChange={this.onChange}>
          {tabs.subtabs.map(tab => (
            <TabPane tab={
src/menu/components/tabs/antv-tabs/options.jsx
@@ -107,6 +107,8 @@
  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal}))
  let tabStyle = setting.cusClass || setting.tabStyle
  const tabForm = [
    {
      type: 'text',
@@ -140,21 +142,36 @@
        {value: 'right', label: 'right'},
      ],
      controlFields: [
        {field: 'display', values: ['top', 'bottom']},
        // {field: 'cusClass', values: ['top']},
        {field: 'tabStyle', values: ['top']},
      ]
    },
    {
      type: 'radio',
      type: 'select',
      field: 'tabStyle',
      label: '页签样式',
      initval: setting.tabStyle || 'line',
      tooltip: '标签位置为top时有效,默认值为line。',
      initval: tabStyle || 'line',
      tooltip: '按钮样式在运行时可见',
      required: true,
      options: [
        {value: 'line', label: 'line'},
        {value: 'card', label: 'card'},
        {value: 'mk-tab-button', label: '按钮(左)'},
        {value: 'mk-tab-button tab-right', label: '按钮(右)'},
      ],
    },
    // {
    //   type: 'select',
    //   field: 'cusClass',
    //   label: '自定义样式',
    //   initval: setting.cusClass || '',
    //   required: false,
    //   options: [
    //     {value: '', label: '无'},
    //     {value: 'mk-tab-button', label: '按钮(左)'},
    //     {value: 'mk-tab-button tab-right', label: '按钮(右)'},
    //   ]
    // },
    {
      type: 'radio',
      field: 'autoSwitch',
src/menu/datasource/index.jsx
@@ -212,6 +212,9 @@
      if (config.subtype !== 'dualdatacard') {
        delete res.subColumns
        if (config.type === 'interface') {
          res.setting.laypage = 'false'
        }
      } else {
        res.subColumns = res.subColumns.map(item => {
          if (/int/ig.test(item.datatype)) {
src/menu/datasource/verifycard/index.jsx
@@ -59,6 +59,7 @@
        dataIndex: 'label',
        inputType: 'input',
        editable: true,
        searchable: true,
        width: '28%'
      },
      {
@@ -68,6 +69,7 @@
        editable: true,
        unique: true,
        strict: true,
        searchable: true,
        copy: true,
        rules: [{
          pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
@@ -659,16 +661,24 @@
      let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.type)
      let _debugId = md5(r.sql)
      if (r.custompage && setting.laypage === 'true' && _columns.findIndex(col => col.field === 'mk_total') === -1) {
        Modal.warning({
          title: `数据源或自定义脚本中使用自定义分页排序时,请在字段集中添加 mk_total。`,
          okText: '知道了',
          onOk: () => {
            reject()
          }
        })
        return
        if (config.subtype !== 'basetable') {
          Modal.warning({
            title: `数据源或自定义脚本中使用自定义分页排序时,请在字段集中添加 mk_total。`,
            okText: '知道了',
            onOk: () => {
              reject()
            }
          })
          return
        } else {
          notification.warning({
            top: 92,
            message: '数据源或自定义脚本中使用自定义分页排序时,请在显示列中添加 mk_total。',
            duration: 5
          })
        }
      }
      if (debugId === _debugId) {
src/menu/stylecontroller/index.jsx
@@ -29,7 +29,8 @@
  ArrowRightOutlined,
  SwapOutlined,
  EnterOutlined,
  DragOutlined
  DragOutlined,
  EyeOutlined
} from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
@@ -56,6 +57,7 @@
  }
  callback = null
  timer = null
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
@@ -96,6 +98,8 @@
    }
    this.callback = callback
    this.timer = null
    let card = fromJS(style).toJS()
    let borposition = 'outer'
@@ -163,7 +167,7 @@
    this.callback = null
  }
  updateStyle = (style) => {
  updateStyle = (style, delay) => {
    const { card } = this.state
    let _style = {
@@ -191,7 +195,15 @@
      card: _style,
    })
    this.callback && this.callback(_style)
    this.timer && clearTimeout(this.timer)
    if (delay) {
      this.timer = setTimeout(() => {
        this.callback && this.callback(_style)
      }, 300)
    } else {
      this.callback && this.callback(_style)
    }
  }
  /**
@@ -208,7 +220,7 @@
      value = 300
    }
    this.updateStyle({fontSize: `${value}px`})
    this.updateStyle({fontSize: `${value}px`}, true)
  }
  /**
@@ -219,7 +231,7 @@
    if (isNaN(value) || value < 1 || value > 10) return
    this.updateStyle({lineHeight: value})
    this.updateStyle({lineHeight: value}, true)
  }
  /**
@@ -230,7 +242,7 @@
    if (isNaN(value) || value < 0 || value > 100) return
    this.updateStyle({letterSpacing: `${value}px`})
    this.updateStyle({letterSpacing: `${value}px`}, true)
  }
  /**
@@ -241,7 +253,7 @@
    if (isNaN(value) || value < 0 || value > 100) return
    this.updateStyle({textIndent: `${value}px`})
    this.updateStyle({textIndent: `${value}px`}, true)
  }
  changeBackground = (val) => {
@@ -510,6 +522,8 @@
          delete style.right
        } else if (n === 'transform') {
          delete style.transform
        } else if (n === 'overflow') {
          delete style.overflow
        }
      })
    }
@@ -1064,6 +1078,20 @@
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('overflow') ? <Panel header="溢出" key="overflow">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<EyeOutlined title="溢出"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.overflow || 'hidden'} onChange={(e) => this.changeNormalStyle(e.target.value, 'overflow')}>
                      <Radio value="hidden">隐藏</Radio>
                      <Radio value="visible">显示</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('position') ? <Panel header="定位" key="position">
                <div style={{paddingLeft: '35px', fontSize: '12px'}}>注:定位效果请在运行环境中查看。</div>
                <Col span={24}>
src/tabviews/basetable/index.jsx
@@ -409,6 +409,11 @@
                  }
                }
              }
              if (cell.marks && cell.marks.length === 0) {
                cell.marks = null
              }
              return true
            })
@@ -422,6 +427,10 @@
            col.linkThdMenu = window.GLOB.mkThdMenus.get(menu_id) || ''
          } else {
            col.linkThdMenu = ''
          }
          if (col.marks && col.marks.length === 0) {
            col.marks = null
          }
          return true
@@ -496,6 +505,16 @@
      }
    }
    if (cell.verify && cell.verify.preHandle === 'true') {
      try {
        // eslint-disable-next-line
        let func = new Function('btn', 'systemType', cell.verify.pre_func)
        func(cell, window.GLOB.systemType)
      } catch (e) {
        console.warn(e)
      }
    }
    if (cell.syncComponentId) {
      if (cell.syncComponentId === item.setting.supModule) {
        cell.syncComponentId = ''
src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -197,26 +197,37 @@
    //   })
    //   return
    // }
    let Id = ''
    if (cards.subtype === 'propcard' && cardCell) {
      Id = cardCell.setting.primaryId || ''
    } else {
      Id = data[cards.setting.primaryKey] || ''
    }
    
    if (card.joint === 'true') {
      let con = '?'
      if (/\?/ig.test(url)) {
        con = '&'
    if (/^http.+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar|.ppt)$/i.test(url)) {
      let name = url.replace(/.+\//g, '').replace(/\.{1}[^.]*$/g, '')
      let d = document.createElement('a')
      d.href = url
      d.setAttribute('download', name)
      d.setAttribute('target', '_blank')
      document.body.appendChild(d)
      d.click()
      d.remove()
    } else {
      if (card.joint === 'true') {
        let Id = ''
        if (cards.subtype === 'propcard' && cardCell) {
          Id = cardCell.setting.primaryId || ''
        } else {
          Id = data[cards.setting.primaryKey] || ''
        }
        let con = '?'
        if (/\?/ig.test(url)) {
          con = '&'
        }
        url = url + `${con}id=${Id}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}`
      }
      url = url + `${con}id=${Id}&appkey=${window.GLOB.appkey}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID') || ''}`
      window.open(url)
    }
    window.open(url)
  }
  getColor = (marks) => {
@@ -294,39 +305,39 @@
  
        if (card.datatype === 'static') {
          val = card.value || ''
          if (/@username@|@fullName@|@mk_city@|@appname@|@bid@/ig.test(val)) {
            let userName = sessionStorage.getItem('User_Name') || ''
            let fullName = sessionStorage.getItem('Full_Name') || ''
            let city = sessionStorage.getItem('city') || ''
            let appname = sessionStorage.getItem('appname') || ''
            let bid = data.$$BID || ''
            val = val.replace(/@username@/ig, userName).replace(/@fullName@/ig, fullName).replace(/@mk_city@/ig, city).replace(/@appname@/ig, appname).replace(/@bid@/ig, bid)
          } else if (/@month@/ig.test(val)) {
            val = val.replace(/@month@/ig, new Date().toLocaleString('en-US', { month: 'long' }))
          } else if (/@week@/ig.test(val)) {
            val = val.replace(/@week@/ig, (() => {
              let day = new Date().getDay()
              let weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
              return weeks[day]
            })())
          } else if (/@day@/ig.test(val)) {
            val = val.replace(/@day@/ig, (() => {
              let day = new Date().getDate()
              return day < 10 ? '0' + day : day
            })())
          if (/@.+@/g.test(val)) {
            if (/@username@|@fullName@|@mk_city@|@appname@|@bid@/ig.test(val)) {
              let userName = sessionStorage.getItem('User_Name') || ''
              let fullName = sessionStorage.getItem('Full_Name') || ''
              let city = sessionStorage.getItem('city') || ''
              let appname = sessionStorage.getItem('appname') || ''
              let bid = data.$$BID || ''
              val = val.replace(/@username@/ig, userName).replace(/@fullName@/ig, fullName).replace(/@mk_city@/ig, city).replace(/@appname@/ig, appname).replace(/@bid@/ig, bid)
            } else if (/@month@/ig.test(val)) {
              val = val.replace(/@month@/ig, new Date().toLocaleString('en-US', { month: 'long' }))
            } else if (/@week@/ig.test(val)) {
              val = val.replace(/@week@/ig, (() => {
                let day = new Date().getDay()
                let weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
                return weeks[day]
              })())
            } else if (/@day@/ig.test(val)) {
              val = val.replace(/@day@/ig, (() => {
                let day = new Date().getDate()
                return day < 10 ? '0' + day : day
              })())
            }
          }
        } else if (data.hasOwnProperty(card.field)) {
          val = data[card.field]
          val = data[card.field] + ''
        }
  
        if (!val && card.noValue === 'hide') { // 空值隐藏
          return null
        }
        if (val !== '' && card.format) {
        if (val && card.format && card.format !== 'encryption') {
          let _val = null
  
          if (card.format === 'calendar1') {
          if (val < '1949-10-02') {
            val = ''
          } else if (card.format === 'calendar1') {
            _val = moment(val).calendar(null, {
              sameDay: '[今天] ahh:mm',
              nextDay: '[明天] ahh:mm',
@@ -373,17 +384,43 @@
          } else {
            _val = moment(val).format(card.format)
          }
          // if (card.format === 'YYYY-MM-DD' && /^[1-9]\d{3}(-|\/)(0[1-9]|1[0-2])(-|\/)(0[1-9]|[1-2][0-9]|3[0-1])/.test(val)) {
          //   val = `${val.substr(0, 4)}-${val.substr(5, 2)}-${val.substr(8, 2)}`
          // }
          if (_val && _val !== 'Invalid date') {
            val = _val
          }
        }
        if (!val && card.noValue === 'hide') { // 空值隐藏
          return null
        }
  
        if (val !== '') {
          let orival = val
          if (card.linkType === 'download') {
            let url = ''
            if (card.link === 'static') {
              url = card.linkurl
            } else {
              url = data[card.linkurl]
            }
            if (/^http.+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar)$/i.test(url)) {
              if (/pdf$/i.test(url)) {
                val = <><img src="./media/pdf.png" className="file-image" alt=""/> {val}</>
              } else if (/(.doc|.docx)$/i.test(url)) {
                val = <><img src="./media/word.png" className="file-image" alt=""/> {val}</>
              } else if (/(.xlsx|.xls)$/i.test(url)) {
                val = <><img src="./media/excel.png" className="file-image" alt=""/> {val}</>
              } else if (/(.zip|.rar)$/i.test(url)) {
                val = <><img src="./media/rar.png" className="file-image" alt=""/> {val}</>
              } else {
                val = <><img src="./media/txt.png" className="file-image" alt=""/> {val}</>
              }
            }
          }
          if (card.format === 'encryption') {
            val = <Encrypts value={val} />
          }
@@ -654,6 +691,10 @@
        if (card.link) {
          _style.cursor = 'pointer'
        }
        if (_style.position === 'absolute') {
          _style.width = '100%'
        }
  
        let scale = url && card.scale === 'true'
        let urls = url ? url.split(',').filter(Boolean) : ['']
src/tabviews/custom/components/card/cardcellList/index.scss
@@ -6,6 +6,11 @@
  .ant-btn {
    padding: 0;
  }
  .file-image {
    max-height: 100%;
    vertical-align: top;
    margin-right: 2px;
  }
  .ant-typography {
    margin: 0;
    padding: 0;
src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -100,6 +100,15 @@
    _config.style.height = 'auto'
    _config.style.minHeight = _config.plot.height + 30
    if (_config.plot.correction) {
      delete _config.plot.correction // 数据修正(已弃用)
      _config.plot.barSize = 35
    }
    if (!_config.plot.legend || _config.plot.legend === 'hidden') {
      _config.plot.legend = false
    }
    if (_config.plot.title) {
      _config.style.minHeight = _config.style.minHeight + 45
    }
@@ -133,6 +142,38 @@
      if (_config.plot.mutilBar !== 'overlap' && Bar_axis.length > 1) {
        _config.plot.Bar_axis = Bar_axis
      }
      if (_config.plot.Bar_axis && _config.plot.Bar_axis.length) {
        let label = _config.plot.label
        if (label === 'false') {
          _config.plot.customs.forEach(item => {
            if (!Bar_axis.includes(item.type)) return
            if (item.label === 'true') {
              label = 'true'
            }
          })
        } else {
          let reset = true
          _config.plot.customs.forEach(item => {
            if (!Bar_axis.includes(item.type)) return
            if (item.label === 'true') {
              reset = false
            }
          })
          if (reset) {
            label = 'false'
          }
        }
        _config.plot.$label = label
      }
      if (_config.plot.zoomYaxis === 'adjust' && _config.plot.mutilBar === 'stack') {
        if (_config.plot.Bar_axis) {
          _config.plot.zoomFields = _config.plot.Yaxis.filter(cell => !_config.plot.Bar_axis.includes(cell))
        }
      }
    } else {
      _config.plot.enabled = 'false'
@@ -1018,7 +1059,7 @@
    chart.axis(plot.Xaxis, plot.$xc)
    chart.axis(_valfield, plot.$yc)
    if (!plot.legend || plot.legend === 'hidden') {
    if (!plot.legend) {
      chart.legend(false)
    } else {
      chart.legend({
@@ -1051,9 +1092,17 @@
      .position(`${plot.Xaxis}*${_valfield}`)
      .shape(plot.shape || 'smooth')
      .tooltip(`${plot.Xaxis}*${_valfield}*${_typefield}`, (name, value, type) => {
        let val = value
        if (plot.show === 'percent') {
          val = value + '%'
        } else if (plot.show === 'thdSeparator') {
          val = val + ''
          val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
        }
        return {
          name: type,
          value: plot.show === 'percent' ? value + '%' : value
          value: val
        }
      })
@@ -1075,14 +1124,15 @@
    }
    if (plot.label !== 'false') {
      _chart.label(_valfield, (value) => {
        if (plot.labelValue === 'zero' && value === 0) {
          return null
        }
        let val = value
        if (plot.show === 'percent') {
          value = value + '%'
          val = value + '%'
        } else if (plot.show === 'thdSeparator') {
          val = val + ''
          val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
        }
        return {
          content: value,
          content: val,
          style: {
            fill: plot.color
          }
@@ -1153,6 +1203,41 @@
   */
  customrender = (data) => {
    const { plot, transfield } = this.state
    let max = 0
    if (plot.zoomYaxis === 'adjust') {
      data.forEach(item => {
        if (plot.zoomFields) {
          plot.zoomFields.forEach(f => {
            if (item[f] > max) {
              max = item[f]
            }
          })
          let sum = 0
          plot.Bar_axis.forEach(f => {
            sum += item[f]
          })
          if (sum > max) {
            max = sum
          }
        } else {
          plot.Yaxis.forEach(f => {
            if (item[f] > max) {
              max = item[f]
            }
          })
        }
      })
      if (!isNaN(max)) {
        max = Math.ceil(max)
        let s = max > 10 ? Math.pow(10, (max + '').length - 2) : 1
        max = Math.ceil(max / s) * s
      } else {
        max = 0
      }
    }
    const ds = new DataSet()
    const dv = ds.createView().source(data)
@@ -1187,8 +1272,7 @@
      })
    }
    let noLegend = !plot.legend || plot.legend === 'hidden'
    if (noLegend) {
    if (!plot.legend) {
      chart.legend(false)
    } else {
      chart.legend({
@@ -1265,22 +1349,30 @@
        range: [0, 0.9]
      }
  
      if (plot.min || plot.min === 0) {
        c.min = plot.min
      }
      if (plot.max || plot.max === 0) {
        c.max = plot.max
      if (plot.zoomYaxis === 'adjust') {
        if (max) {
          c.min = 0
          c.max = max
        }
      } else {
        if (plot.min || plot.min === 0) {
          c.min = plot.min
        }
        if (plot.max || plot.max === 0) {
          c.max = plot.max
          c.min = c.min || 0
        }
      }
      view1.scale('value', c)
      view1.axis('value', plot.$yc)
  
      if (!noLegend) {
      if (plot.legend) {
        view1.legend(false)
      }
      let colorIndex = 0
  
      if (plot.adjust !== 'stack') {
      if (plot.mutilBar !== 'stack') {
        let _chart = view1
          .interval()
          .position(`${plot.Xaxis}*value`)
@@ -1292,12 +1384,16 @@
          ])
          .shape(plot.shape || 'rect')
          .tooltip(`${plot.Xaxis}*value*key`, (name, value, key) => {
            let val = value
            if (plot.show === 'percent') {
              value = value + '%'
              val = value + '%'
            } else if (plot.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            return {
              name: key,
              value: value
              value: val
            }
          })
@@ -1314,45 +1410,53 @@
        } else {
          _chart.color('key')
        }
        if (plot.label !== 'false') {
        if (plot.$label !== 'false') {
          _chart.label('value*key', (value, key) => {
            if (plot.labelValue === 'zero' && value === 0) {
            if (plot.$label !== 'true' && value === 0) {
              return null
            }
            let val = value
            if (plot.show === 'percent') {
              value = value + '%'
              val = value + '%'
            } else if (plot.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            if (plot.label === 'true' && plot.labelColor === 'custom' && plot.$colors && plot.$colors.has(key)) {
            if (plot.$label === 'true' && plot.labelColor === 'custom' && plot.$colors && plot.$colors.has(key)) {
              lablecfg.style.fill = plot.$colors.get(key)
            }
            return {
              content: value,
              content: val,
              ...lablecfg
            }
          })
        }
        if (plot.barSize || plot.correction) {
        if (plot.barSize) {
          _chart.size(plot.barSize || 35)
        }
        if (plot.barRadius) {
          _chart.style({ radius: [plot.barRadius, plot.barRadius, 0, 0] })
        }
      } else if (plot.adjust === 'stack') {
      } else if (plot.mutilBar === 'stack') {
        let _chart = view1
          .interval()
          .position(`${plot.Xaxis}*value`)
          .adjust('stack')
          .shape(plot.shape || 'rect')
          .tooltip(`${plot.Xaxis}*value*key`, (name, value, type) => {
            let val = value
            if (plot.show === 'percent') {
              value = value + '%'
              val = value + '%'
            } else if (plot.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            return {
              name: type,
              value: value
              value: val
            }
          })
  
@@ -1369,26 +1473,30 @@
        } else {
          _chart.color('key')
        }
        if (plot.label !== 'false') {
        if (plot.$label !== 'false') {
          _chart.label('value*key', (value, key) => {
            if (plot.labelValue === 'zero' && value === 0) {
            if (plot.$label !== 'true' && value === 0) {
              return null
            }
            let val = value
            if (plot.show === 'percent') {
              value = value + '%'
              val = value + '%'
            } else if (plot.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            if (plot.label === 'true' && plot.labelColor === 'custom' && plot.$colors && plot.$colors.has(key)) {
            if (plot.$label === 'true' && plot.labelColor === 'custom' && plot.$colors && plot.$colors.has(key)) {
              lablecfg.style.fill = plot.$colors.get(key)
            }
            return {
              content: value,
              content: val,
              ...lablecfg
            }
          })
        }
        if (plot.barSize || plot.correction) {
        if (plot.barSize) {
          _chart.size(plot.barSize || 35)
        }
        if (plot.barRadius) {
@@ -1411,7 +1519,7 @@
    view2.data(dv.rows)
    if (!noLegend) {
    if (plot.legend && plot.Bar_axis) {
      view2.legend(false)
    }
@@ -1424,11 +1532,18 @@
          range: [0, 0.9]
        }
    
        if (item.min || item.min === 0) {
          c.min = item.min
        }
        if (item.max || item.max === 0) {
          c.max = item.max
        if (plot.zoomYaxis === 'adjust') {
          if (max) {
            c.min = 0
            c.max = max
          }
        } else {
          if (item.min || item.min === 0) {
            c.min = item.min
          }
          if (item.max || item.max === 0) {
            c.max = item.max
          }
        }
        view2.scale(item.name, c)
@@ -1438,9 +1553,16 @@
          .color(item.color)
          .shape(item.shape)
          .tooltip(`${item.name}`, (value) => {
            let val = value
            if (item.show === 'percent') {
              val = value + '%'
            } else if (item.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            return {
              name: item.name,
              value: item.show === 'percent' ? value + '%' : value
              value: val
            }
          })
@@ -1449,18 +1571,22 @@
        }
        if (item.label !== 'false') {
          _chart.label(item.name, (value) => {
            if (plot.labelValue === 'zero' && value === 0) {
            if (plot.label !== 'true' && value === 0) {
              return null
            }
            let val = value
            if (item.show === 'percent') {
              value = value + '%'
              val = value + '%'
            } else if (item.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            if (plot.label === 'true' && plot.labelColor === 'custom' && item.color) {
              lablecfg.style.fill = item.color
            }
            return {
              content: value,
              content: val,
              ...lablecfg
            }
          })
@@ -1479,11 +1605,18 @@
          range: [0, 0.9]
        }
    
        if (item.min || item.min === 0) {
          c.min = item.min
        }
        if (item.max || item.max === 0) {
          c.max = item.max
        if (plot.zoomYaxis === 'adjust') {
          if (max) {
            c.min = 0
            c.max = max
          }
        } else {
          if (item.min || item.min === 0) {
            c.min = item.min
          }
          if (item.max || item.max === 0) {
            c.max = item.max
          }
        }
        view2.scale(item.name, c)
@@ -1493,23 +1626,32 @@
          .color(item.color)
          .shape(item.shape)
          .tooltip(`${item.name}`, (value) => {
            let val = value
            if (item.show === 'percent') {
              val = value + '%'
            } else if (item.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            return {
              name: item.name,
              value: item.show === 'percent' ? value + '%' : value
              value: val
            }
          })
        if (item.label === 'true') {
          _chart.label(item.name, (value) => {
            if (plot.labelValue === 'zero' && value === 0) {
              return null
            let val = value
            if (item.show === 'percent') {
              val = value + '%'
            } else if (item.show === 'thdSeparator') {
              val = val + ''
              val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
            }
            if (item.show === 'percent') {
              value = value + '%'
            }
            return {
              content: value,
              content: val,
              style: {
                fill: plot.color
              }
@@ -1617,13 +1759,14 @@
    }
    if (plot.max || plot.max === 0) {
      c.max = plot.max
      c.min = c.min || 0
    }
    chart.scale(_valfield, c)
    chart.axis(plot.Xaxis, plot.$xc)
    chart.axis(_valfield, plot.$yc)
    if (!plot.legend || plot.legend === 'hidden') {
    if (!plot.legend) {
      chart.legend(false)
    } else {
      chart.legend({
@@ -1700,9 +1843,16 @@
        ])
        .shape(plot.shape || 'rect')
        .tooltip(`${plot.Xaxis}*${_valfield}*${_typefield}`, (name, value, type) => {
          let val = value
          if (plot.show === 'percent') {
            val = value + '%'
          } else if (plot.show === 'thdSeparator') {
            val = val + ''
            val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
          }
          return {
            name: type,
            value: plot.show === 'percent' ? value + '%' : value
            value: val
          }
        })
@@ -1735,12 +1885,16 @@
      }
      if (plot.label !== 'false') {
        _chart.label(`${_valfield}*${_typefield}`, (value, key) => {
          if (plot.labelValue === 'zero' && value === 0) {
          if (plot.label !== 'true' && value === 0) {
            return null
          }
          let val = value
          if (plot.show === 'percent') {
            value = value + '%'
            val = value + '%'
          } else if (plot.show === 'thdSeparator') {
            val = val + ''
            val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
          }
          if (plot.label === 'true' && plot.labelColor === 'custom' && plot.$colors && plot.$colors.has(key)) {
@@ -1748,13 +1902,13 @@
          }
          return {
            content: value,
            content: val,
            ...lablecfg
          }
        })
      }
      if (plot.barSize || plot.correction) {
      if (plot.barSize) {
        _chart.size(plot.barSize || 35)
      }
      if (plot.selectColor) {
@@ -1776,9 +1930,16 @@
        .adjust('stack')
        .shape(plot.shape || 'rect')
        .tooltip(`${plot.Xaxis}*${_valfield}*${_typefield}`, (name, value, type) => {
          let val = value
          if (plot.show === 'percent') {
            val = value + '%'
          } else if (plot.show === 'thdSeparator') {
            val = val + ''
            val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
          }
          return {
            name: type,
            value: plot.show === 'percent' ? value + '%' : value
            value: val
          }
        })
@@ -1810,12 +1971,16 @@
      }
      if (plot.label !== 'false') {
        _chart.label(`${_valfield}*${_typefield}`, (value, key) => {
          if (plot.labelValue === 'zero' && value === 0) {
          if (plot.label !== 'true' && value === 0) {
            return null
          }
          let val = value
          if (plot.show === 'percent') {
            value = value + '%'
            val = value + '%'
          } else if (plot.show === 'thdSeparator') {
            val = val + ''
            val = val.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
          }
          if (plot.label === 'true' && plot.labelColor === 'custom' && plot.$colors && plot.$colors.has(key)) {
@@ -1823,13 +1988,13 @@
          }
          return {
            content: value,
            content: val,
            ...lablecfg
          }
        })
      }
      if (plot.barSize || plot.correction) {
      if (plot.barSize) {
        _chart.size(plot.barSize || 35)
      }
      if (plot.selectColor) {
src/tabviews/custom/components/code/sand-box/index.jsx
@@ -318,8 +318,8 @@
      if (js) {
        try {
          // eslint-disable-next-line
          let evalfunc = eval('(true && function (data, result, Api, notification) {' + js + '})')
          evalfunc(data, result, Api, notification)
          let evalfunc = eval('(true && function (data, result, Api, notification, systemType) {' + js + '})')
          evalfunc(data, result, Api, notification, window.GLOB.systemType)
        } catch (e) {
          console.warn(e)
        }
src/tabviews/custom/components/form/simple-form/index.jsx
@@ -220,7 +220,7 @@
  refreshByButtonResult = (menuId, position, btn, id) => {
    const { config, group, BID } = this.state
    if (group.uuid !== menuId) return
    if (config.uuid !== menuId) return
    if (position === 'grid' && config.wrap.refocus) {
      let _group = fromJS(group).toJS()
src/tabviews/custom/components/form/step-form/index.jsx
@@ -239,9 +239,9 @@
   * @param {*} btn        // 执行的按钮
   */
  refreshByButtonResult = (menuId, position, btn, id) => {
    const { config, group, BID } = this.state
    const { config, BID } = this.state
    if (group.uuid !== menuId) return
    if (config.uuid !== menuId) return
    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) {
      MKEmitter.emit('reloadData', config.setting.supModule, BID)
src/tabviews/custom/components/form/tab-form/index.jsx
@@ -205,9 +205,9 @@
   * @param {*} btn        // 执行的按钮
   */
  refreshByButtonResult = (menuId, position, btn, id) => {
    const { config, group, BID } = this.state
    const { config, BID } = this.state
    if (group.uuid !== menuId) return
    if (config.uuid !== menuId) return
    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) {
      MKEmitter.emit('reloadData', config.setting.supModule, BID)
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -499,10 +499,6 @@
            } else if (_format && !Math.floor(Math.random() * radio)) {
              item.blur = true
            }
            if (item.marks && item.marks.length === 0) {
              item.marks = ''
            }
  
            if (item.field) {
              orderfields[item.uuid] = item.field
@@ -838,6 +834,8 @@
  onSelectChange = (selectedRowKeys, e) => {
    const { setting, MenuID, data } = this.props
    if (this.state.pickup) return
    let index = ''
    let _activeIndex = null
    if (selectedRowKeys.length > 0) {
src/tabviews/custom/components/share/normalTable/index.scss
@@ -103,6 +103,7 @@
        .card-cell-list {
          color: inherit;
          overflow: hidden;
        }
        .ant-mk-picture {
          position: relative;
src/tabviews/custom/components/table/edit-table/index.jsx
@@ -113,10 +113,6 @@
            item.type = 'text'
          }
          if (item.marks && item.marks.length === 0) {
            item.marks = ''
          }
          if (item.editable === 'true') {
            setting.hasSubmit = setting.commit !== 'change'
            item.$ctrl = setting.commit === 'change'
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -2017,7 +2017,7 @@
      setTimeout(() => {
        this.plusLine(colId)
      }, 10)
    } else if (edData[index] && setting.commit !== 'change') {
    } else if (edData[index] && (setting.commit === 'all' || setting.commit === 'amend')) {
      setTimeout(() => {
        this.submit()
      }, 10)
@@ -2158,7 +2158,7 @@
  checkData = () => {
    const { setting } = this.props
    const { edData, forms, checkForms } = this.state
    const { edData, forms, checkForms, selectedRowKeys } = this.state
    let data = fromJS(edData).toJS()
@@ -2166,6 +2166,17 @@
    if (setting.commit === 'amend') {
      data = data.filter(item => !item.$origin)
    } else if (setting.commit === 'check') {
      data = data.filter(item => selectedRowKeys.includes(item.$$uuid))
      if (data.length === 0) {
        notification.warning({
          top: 92,
          message: '请选择需要提交的数据!',
          duration: 5
        })
        return null
      }
    }
    if (data.length === 0) {
src/tabviews/custom/components/table/edit-table/normalTable/index.scss
@@ -65,6 +65,7 @@
        .card-cell-list {
          color: inherit;
          overflow: hidden;
        }
        .action-col {
          .ant-btn > .anticon + span {
src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -146,7 +146,7 @@
    if (!tabs.subtabs.length) return null
    return (
      <div className={'menu-antv-tabs-wrap ' + (tabs.setting.tabLabel || '')} id={'anchor' + tabs.uuid} style={tabs.style}>
      <div className={`menu-antv-tabs-wrap ${tabs.setting.tabLabel || ''} ${tabs.setting.cusClass || ''}`} id={'anchor' + tabs.uuid} style={tabs.style}>
        <Tabs defaultActiveKey="1" tabBarStyle={{background: tabs.setting.backgroundColor || 'transparent'}} tabPosition={tabs.setting.position} type={tabs.setting.tabStyle}>
          {tabs.subtabs.map(tab => (
            <TabPane tab={<span id={'tab' + tab.uuid}>{tab.icon ? <MkIcon type={tab.icon} /> : null}{tab.label}</span>} style={{backgroundColor: tab.backgroundColor || 'transparent'}} key={tab.uuid}>
src/tabviews/custom/components/tabs/antv-tabs/index.scss
@@ -28,3 +28,35 @@
.menu-antv-tabs-wrap.hide >.ant-tabs >.ant-tabs-bar{
  display: none;
}
.menu-antv-tabs-wrap.mk-tab-button >.ant-tabs >.ant-tabs-bar {
  border-bottom: 0px;
  .ant-tabs-nav-scroll {
    margin-bottom: 2px;
    .ant-tabs-ink-bar {
      display: none!important;
    }
    .ant-tabs-tab {
      margin-right: 10px;
      border: 1px solid var(--mk-sys-color3);
      padding: 8px 35px;
      border-radius: 40px;
      color: var(--mk-sys-color);
      background: #ffffff;
      transition: all 0.2s;
    }
    .ant-tabs-tab.ant-tabs-tab-active {
      border: 1px solid var(--mk-sys-color);
      background: var(--mk-sys-color);
      color: #ffffff;
    }
    .ant-tabs-tab:last-child {
      margin-right: 0px;
    }
  }
}
.menu-antv-tabs-wrap.mk-tab-button.tab-right >.ant-tabs >.ant-tabs-bar {
  .ant-tabs-nav-scroll {
    text-align: right;
  }
}
src/tabviews/custom/index.jsx
@@ -661,6 +661,10 @@
              col.linkThdMenu = ''
            }
            if (col.marks && col.marks.length === 0) {
              col.marks = null
            }
            return true
          })
        }
@@ -772,48 +776,17 @@
      } else if (item.type === 'form') {
        item.subcards = item.subcards.map(group => {
          group.subButton.uuid = group.uuid
          group.subButton.$menuId = group.uuid
          group.subButton.$MenuID = this.props.MenuID
          // group.subButton.$forbid = true // 不声明数据源变量
          group.subButton.OpenType = 'formSubmit'
          group.subButton.execError = 'never'
          group.subButton.logLabel = item.$menuname + '-' + group.subButton.label
          if (!group.subButton.Ot) {
            group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
          }
          if (item.$process) {
            group.subButton.$process = true
            group.subButton.$flowId = 'flow' + this.props.MenuID
          }
          group.subButton = this.resetButton(item, group.subButton)
          if (item.$cache && item.$time) {
          if (item.$cache && item.$time) { // 表单缓存
            group.$cache = item.$cache
            group.$time = item.$time
          }
          group.subButton.syncComponentId = group.subButton.syncComponent ? (group.subButton.syncComponent.pop() || '') : ''
          if (group.subButton.syncComponentId && group.subButton.syncComponentId === item.setting.supModule) {
            group.subButton.syncComponentId = ''
            if (group.subButton.execSuccess === 'grid') {
              group.subButton.execSuccess = 'mainline'
            }
          }
          if (group.subButton.verify && group.subButton.verify.invalid === 'true') {
            if (item.wrap.datatype === 'static' || item.wrap.datatype === 'public') {
              group.subButton.verify.invalid = 'false'
            } else if (item.setting && item.setting.maxScript && item.setting.maxScript >= 300) {
              group.subButton.verify.invalid = 'false'
            } else if (group.subButton.sqlType === 'insert') {
              group.subButton.verify.invalid = 'false'
            } else if (group.subButton.Ot === 'notRequired') {
              group.subButton.verify.invalid = 'false'
            } else if (group.subButton.intertype !== 'system' && group.subButton.procMode !== 'system') {
              group.subButton.verify.invalid = 'false'
            }
          }
          group.fields = group.fields.map(cell => {
@@ -945,6 +918,16 @@
      }
    }
    if (cell.verify && cell.verify.preHandle === 'true') {
      try {
        // eslint-disable-next-line
        let func = new Function('btn', 'systemType', cell.verify.pre_func)
        func(cell, window.GLOB.systemType)
      } catch (e) {
        console.warn(e)
      }
    }
    if (cell.syncComponentId) {
      if (cell.syncComponentId === item.setting.supModule) {
        cell.syncComponentId = ''
@@ -979,6 +962,10 @@
    if (cell.style.display === 'inline-block') {
      cell.style.verticalAlign = 'top'
    }
    if (cell.marks && cell.marks.length === 0) {
      cell.marks = null
    }
    if (['text', 'number', 'formula'].includes(cell.eleType)) {
@@ -1065,6 +1052,8 @@
      component.setting.arr_field = component.columns ? component.columns.map(col => col.field).join(',') : ''
      component.setting.useMSearch = component.setting.useMSearch === 'true'
      component.setting.laypage = component.setting.laypage === 'true'   // 是否分页,转为boolean 统一格式
      if (component.setting.useMSearch) {
        if (!window.GLOB.SearchBox.has(component.$searchId)) {
          component.setting.useMSearch = false
@@ -1077,10 +1066,14 @@
        component.setting.sync = 'false'
      }
      if (component.format === 'object') {
        component.setting.laypage = false
        component.setting.$top = true
      }
      if (component.setting.interType !== 'system') { // 不使用系统函数时
        component.setting.sync = 'false'
        component.setting.dataresource = ''
        component.setting.laypage = component.setting.laypage === 'true'
        return component
      }
@@ -1101,8 +1094,7 @@
      delete component.scripts
      component.setting.$name = component.$menuname || ''
      component.setting.execute = component.setting.execute !== 'false'  // 默认sql是否执行,转为boolean 统一格式
      component.setting.laypage = component.setting.laypage === 'true'   // 是否分页,转为boolean 统一格式
      if (!component.setting.execute) {
        component.setting.dataresource = ''
      }
@@ -1218,6 +1210,8 @@
        inter.setting.onload = 'false'
      }
      inter.setting.laypage = false
      inter.setting.$top = true
      inter.setting.useMSearch = inter.setting.useMSearch === 'true'
      inter.setting.arr_field = inter.columns.map(col => col.field).join(',')
@@ -1241,7 +1235,6 @@
      inter.setting.$name = '公共数据源-' + inter.setting.name
      inter.setting.execute = inter.setting.execute !== 'false'
      inter.setting.laypage = true
      if (!inter.setting.execute) {
        inter.setting.dataresource = ''
src/tabviews/custom/popview/index.jsx
@@ -405,6 +405,10 @@
              col.linkThdMenu = ''
            }
            if (col.marks && col.marks.length === 0) {
              col.marks = null
            }
            return true
          })
        }
@@ -504,39 +508,14 @@
      } else if (item.type === 'form') {
        item.subcards = item.subcards.map(group => {
          group.subButton.uuid = group.uuid
          group.subButton.$menuId = group.uuid
          group.subButton.$MenuID = Tab.$MenuID
          group.subButton.OpenType = 'formSubmit'
          group.subButton.execError = 'never'
          group.subButton.logLabel = item.$menuname + '-' + group.subButton.label
          group.subButton.$tabId = Tab.uuid
          if (!group.subButton.Ot) {
            group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
          }
          group.subButton.syncComponentId = group.subButton.syncComponent ? (group.subButton.syncComponent.pop() || '') : ''
          if (group.subButton.syncComponentId && group.subButton.syncComponentId === item.setting.supModule) {
            group.subButton.syncComponentId = ''
            if (group.subButton.execSuccess === 'grid') {
              group.subButton.execSuccess = 'mainline'
            }
          }
          if (group.subButton.verify && group.subButton.verify.invalid === 'true') {
            if (item.wrap.datatype === 'static') {
              group.subButton.verify.invalid = 'false'
            } else if (item.setting && item.setting.maxScript && item.setting.maxScript >= 300) {
              group.subButton.verify.invalid = 'false'
            } else if (group.subButton.intertype !== 'system' && group.subButton.procMode !== 'system') {
              group.subButton.verify.invalid = 'false'
            } else if (group.subButton.sqlType === 'insert') {
              group.subButton.verify.invalid = 'false'
            } else if (group.subButton.Ot === 'notRequired') {
              group.subButton.verify.invalid = 'false'
            }
          }
          group.subButton = this.resetButton(item, group.subButton, Tab)
          group.fields = group.fields.map(cell => {
            // 数据源sql语句,预处理,权限黑名单字段设置为隐藏表单
@@ -656,6 +635,16 @@
      }
    }
    if (cell.verify && cell.verify.preHandle === 'true') {
      try {
        // eslint-disable-next-line
        let func = new Function('btn', 'systemType', cell.verify.pre_func)
        func(cell, window.GLOB.systemType)
      } catch (e) {
        console.warn(e)
      }
    }
    if (cell.syncComponentId) {
      if (cell.syncComponentId === item.setting.supModule) {
        cell.syncComponentId = ''
@@ -690,6 +679,10 @@
    if (cell.style.display === 'inline-block') {
      cell.style.verticalAlign = 'top'
    }
    if (cell.marks && cell.marks.length === 0) {
      cell.marks = null
    }
    if (['text', 'number', 'formula'].includes(cell.eleType)) {
@@ -754,6 +747,8 @@
      component.setting.arr_field = component.columns ? component.columns.map(col => col.field).join(',') : ''
      component.setting.useMSearch = component.setting.useMSearch === 'true'
      component.setting.laypage = component.setting.laypage === 'true'   // 是否分页,转为boolean 统一格式
      if (component.setting.useMSearch) {
        if (!window.GLOB.SearchBox.has(component.$searchId)) {
          component.setting.useMSearch = false
@@ -762,10 +757,14 @@
        }
      }
      if (component.format === 'object') {
        component.setting.laypage = false
        component.setting.$top = true
      }
      if (component.setting.interType !== 'system') { // 不使用系统函数时
        component.setting.sync = 'false'
        component.setting.dataresource = ''
        component.setting.laypage = component.setting.laypage === 'true'
        return component
      }
@@ -786,7 +785,6 @@
      delete component.scripts
      component.setting.$name = component.$menuname || ''
      component.setting.execute = component.setting.execute !== 'false'  // 默认sql是否执行,转为boolean 统一格式
      component.setting.laypage = component.setting.laypage === 'true'   // 是否分页,转为boolean 统一格式
      if (!component.setting.execute) {
        component.setting.dataresource = ''
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -2356,7 +2356,7 @@
    const { btn } = this.props
    if (!btn.verify) return
    if (btn.verify.noteEnable !== 'true' && btn.verify.wxNote !== 'true' && btn.verify.printEnable !== 'true') return
    if (btn.verify.noteEnable !== 'true' && btn.verify.wxNote !== 'true' && btn.verify.printEnable !== 'true' && btn.verify.emailEnable !== 'true') return
    let id = ''
    if (btn.output) {
@@ -2371,6 +2371,9 @@
    if (btn.verify.noteEnable === 'true') {
      this.sendMessage(btn.verify, id)
    }
    if (btn.verify.emailEnable === 'true') {
      this.sendEmail(btn.verify, id)
    }
    if (btn.verify.wxNote === 'true') {
      if (btn.verify.wxTemplateId === 'mk_category_temp') {
@@ -2550,8 +2553,8 @@
  sendMessage = (verify, id) => {
    let param = {
      func: 's_get_sms_local',
      TypeCharOne: verify.noteTemp, // N不同内容,Y相同内容
      TypeCharTwo: verify.noteType, // N定时,Y实时
      TypeCharOne: verify.noteTemp || 'Y', // N不同内容,Y相同内容
      TypeCharTwo: verify.noteType || 'N', // N定时,Y实时
      upid: id
    }
@@ -2570,9 +2573,9 @@
      }
      let _param = {
        templatecode: verify.noteCode, // 模板编码
        TypeCharOne: verify.noteTemp,  // N不同内容,Y相同内容
        ID: verify.noteId || ''        // 模板Id,暂时未使用
        templatecode: verify.noteCode,        // 模板编码
        TypeCharOne: verify.noteTemp || 'Y',  // N不同内容,Y相同内容
        ID: verify.noteId || ''               // 模板Id,暂时未使用
      }
      _param.submitdate = res.submitdate
@@ -2580,17 +2583,17 @@
      let limit = 5 // 实时最大为5条,定时最大为100条
      let mobMap = new Map()
      if (verify.noteType === 'N') {
      if (verify.noteType === 'Y') {
        _param.func = 's_get_sms_sso_realtime'
      } else {
        _param.func = 's_get_sms_sso_timer'
        limit = 100
      } else if (verify.noteType === 'Y') {
        _param.func = 's_get_sms_sso_realtime'
      }
      let Ltext = []
      let error = false
      if (verify.noteTemp === 'Y') {
      if (verify.noteTemp !== 'N') {
        _param.p1 = res.p1 || ''
        _param.p2 = res.p2 || ''
        _param.p3 = res.p3 || ''
@@ -2599,25 +2602,156 @@
        let _p = _param.p1 + _param.p2 + _param.p3 + _param.p4 + _param.p5
        if (/\/|\.|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信|Q/.test(_p)) {
        if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
          error = true
        }
      }
      res.send_data && res.send_data.forEach(item => {
        if (item.mob && !mobMap.has(item.mob) && Ltext.length < limit) {
          if (verify.noteTemp === 'Y') {
          if (verify.noteTemp !== 'N') {
            Ltext.push(`'${item.mob}'`)
          } else {
            let _p = `'${item.p1 || ''}','${item.p2 || ''}','${item.p3 || ''}','${item.p4 || ''}','${item.p5 || ''}','${item.mob}'`
            if (/\/|\.|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信|Q/.test(_p)) {
            if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
              error = true
            }
            Ltext.push(_p)
          }
          mobMap.set(item.mob, true)
        }
      })
      if (error) {
        notification.warning({
          top: 92,
          message: '消息中含有非法字符',
          duration: 5
        })
        return
      }
      if (Ltext.length === 0) return
      Ltext = Ltext.join(';')
      _param.LText = window.btoa(window.encodeURIComponent(Ltext))
      _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
      _param.rduri = 'https://sso.mk9h.cn/webapi/dostars'
      _param.userid = 'bh0bapabtd45epsgra79segbch6c1ibk'
      _param.LoginUID = 'bh0bapabtd45epsgra79segbch6c1ibk'
      Api.genericInterface(_param).then(result => {
        if (!result.status) {
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
        }
      }, (error) => {
        if (error && error.ErrCode === 'LoginError') {
          let param = {
            func: 's_visitor_login',
            timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
            SessionUid: 'bh0bapabtd45epsgra79segbch6c1ibk',
            TypeCharOne: 'pc',
            appkey: '202004041613277377A6A2456D34A4948AE84'
          }
          param.LText = md5(window.btoa('bh0bapabtd45epsgra79segbch6c1ibk' + param.timestamp))
          param.secretkey = md5(param.LText + 'mingke' + param.timestamp)
          let params = {
            url: 'https://sso.mk9h.cn/webapi/dologon',
            method: 'post',
            data: JSON.stringify(param)
          }
          Api.directRequest(params)
          return
        }
      })
    })
  }
  sendEmail = (verify, id) => {
    let param = {
      func: 's_get_email_local',
      TypeCharOne: verify.emailTemp || 'Y', // N不同内容,Y相同内容
      TypeCharTwo: verify.emailType || 'N', // N定时,Y实时
      upid: id
    }
    param.LText = Utils.formatOptions(Utils.getuuid())
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    Api.genericInterface(param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      let _param = {
        msn_email_temp_no: verify.emailCode,   // 模板编码
        TypeCharOne: verify.emailTemp || 'Y',  // N不同内容,Y相同内容
        ID: verify.emailId || ''               // 模板Id,暂时未使用
      }
      _param.submitdate = res.submitdate
      let limit = 5 // 实时最大为5条,定时最大为100条
      let mobMap = new Map()
      if (verify.emailType === 'Y') {
        _param.func = 's_get_email_sso_realtime'
      } else {
        _param.func = 's_get_email_sso_timer'
        limit = 100
      }
      let Ltext = []
      let error = false
      if (verify.emailTemp !== 'N') {
        _param.p1 = res.p1 || ''
        _param.p2 = res.p2 || ''
        _param.p3 = res.p3 || ''
        _param.p4 = res.p4 || ''
        _param.p5 = res.p5 || ''
        let _p = _param.p1 + _param.p2 + _param.p3 + _param.p4 + _param.p5
        if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
          error = true
        }
      }
      res.send_data && res.send_data.forEach(item => {
        if (item.email && !mobMap.has(item.email) && Ltext.length < limit) {
          if (verify.emailTemp !== 'N') {
            Ltext.push(`'${item.email}'`)
          } else {
            let _p = `'${item.p1 || ''}','${item.p2 || ''}','${item.p3 || ''}','${item.p4 || ''}','${item.p5 || ''}','${item.email}'`
            if (/\/|.*共.*产|.*习.*近|面试|邀请|下载|红包|招聘|好评|评价|政务通知|缴费|保险|股票|金融|房地产|教育|游戏|微信/.test(_p)) {
              error = true
            }
            Ltext.push(_p)
          }
          mobMap.set(item.email, true)
        }
      })
@@ -2765,6 +2899,13 @@
      })
    } else if (res.ErrCode === 'NM') {
      message.error(res.message || '执行失败!')
    } else if (res.ErrCode === '-2') {
      this.setState({
        loadingNumber: '',
        loadingTotal: '',
        loading: false
      })
      return
    }
    this.errorContinue(sign)
src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -1968,6 +1968,8 @@
      return
    }
    if (res.ErrCode === '-2') return
    if (btnconfig && btnconfig.setting && btnconfig.setting.errFocus) {
      MKEmitter.emit('mkFC', 'focus', btnconfig.setting.errFocus)
    }
src/tabviews/zshare/fileupload/index.jsx
@@ -12,8 +12,9 @@
class FileUpload extends Component {
  static propTpyes = {
    config: PropTypes.object,  // 表单信息
    onChange: PropTypes.func,  // 表单变化
    data: PropTypes.any,
    config: PropTypes.object,
    onChange: PropTypes.func,
  }
  state = {
@@ -31,7 +32,7 @@
  }
  UNSAFE_componentWillMount () {
    const { config } = this.props
    const { config, data } = this.props
    let filelist = []
    if (config.initval) {
@@ -56,6 +57,12 @@
          })
        } catch (e) {
          filelist = []
        }
        if (data && config.subFields && config.subFields.length === 1 && filelist.length === 1) {
          if (data[config.subFields[0].field]) {
            filelist[0].name = data[config.subFields[0].field]
          }
        }
      }
    }
@@ -270,7 +277,7 @@
      percent: 0
    })
    let file_name = file.name.replace(/\.{1}[^.]*$/ig, '')
    let file_name = file.name
    if (compress === 'true' || compress === 'base64') {
      let reader = new FileReader()
src/tabviews/zshare/fileupload/index.scss
@@ -34,6 +34,9 @@
      display: none;
    }
  }
  .ant-upload-list-item-card-actions {
    opacity: 1;
  }
}
.fileupload-form-container.limit-fileupload {
  > .ant-upload {
src/tabviews/zshare/mutilform/index.jsx
@@ -1244,7 +1244,7 @@
        } else if (item.type === 'fileupload') {
          className = item.readonly ? 'readonly' : ''
          className += item.fileType === 'picture-card' ? ' file-upload' : ''
          content = (<MKFileUpload config={item} onChange={(val, other = {}) => this.recordChange({[item.field]: val, ...other})} />)
          content = (<MKFileUpload config={item} data={this.record} onChange={(val, other = {}) => this.recordChange({[item.field]: val, ...other})} />)
        } else if (item.type === 'textarea') {
          content = (<MKTextArea config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val})}/>)
        } else if (item.type === 'rate') {
src/tabviews/zshare/topSearch/index.jsx
@@ -426,6 +426,7 @@
  }
  resetSearch = (result) => {
    let trigger = false
    let _searchlist = fromJS(this.state.searchlist).toJS().map(item => {
      if (['select', 'link', 'multiselect', 'checkcard', 'radio'].includes(item.type) && result[item.field] && result[item.field].length > 0) {
        let options = []
@@ -491,12 +492,23 @@
        item.options = item.oriOptions
      }
      if (item.$first && item.options.length > 0) {
        item.initval = item.options[0].Value
        trigger = true
      }
      return item
    })
    this.setState({
      searchlist: _searchlist
    })
    if (trigger) {
      setTimeout(() => {
        this.handleSubmit()
      }, 10)
    }
  }
  recordChange = (val, defer, item) => {
src/tabviews/zshare/topSearch/mkSelect/index.jsx
@@ -46,6 +46,12 @@
        config: fromJS(nextProps.config).toJS(),
        options: fromJS(nextProps.config.options).toJS()
      })
      if (config.$first && nextProps.config.initval) {
        this.setState({
          value: nextProps.config.initval
        })
      }
    }
  }
src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
@@ -341,10 +341,10 @@
              取消
            </Button>
          </Col>
          {!type ? <Col span={3} style={{paddingTop: '15px', fontSize: '12px', whiteSpace: 'nowrap'}}>
          <Col span={3} className="forced" style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}>
            强制保存:
            <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/>
          </Col> : null}
          </Col>
          <Col span={24} className="sql">
            <Form.Item label="sql">
              {getFieldDecorator('sql', {
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -17,6 +17,7 @@
const { TabPane } = Tabs
const { confirm } = Modal
const { Search } = Input
const { Paragraph } = Typography
const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
const FullScripts = asyncComponent(() => import('@/templates/zshare/verifycard/fullScripts'))
@@ -31,6 +32,7 @@
    verify: {},
    systemScripts: [],
    activeKey: 'basemsg',
    searchKey: '',
    excelColumns: [
      {
        title: '字段',
@@ -39,6 +41,8 @@
        inputType: 'input',
        unique: true,
        strict: true,
        searchable: true,
        copy: true,
        editable: true
      },
      {
@@ -46,6 +50,7 @@
        dataIndex: 'Text',
        width: '14%',
        inputType: 'input',
        searchable: true,
        editable: true
      },
      {
@@ -297,6 +302,7 @@
    }
    this.setState({
      searchKey: '',
      verify: {
        ..._verify,
        default: _verify.default || 'true',
@@ -833,7 +839,7 @@
  render() {
    const { card } = this.props
    const { getFieldDecorator } = this.props.form
    const { verify, excelColumns, scriptsColumns, uniqueColumns, activeKey } = this.state
    const { verify, excelColumns, scriptsColumns, uniqueColumns, activeKey, searchKey } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -901,13 +907,13 @@
          } key="excelcolumn">
            <ColumnForm columnChange={this.columnChange}/>
            <Button className="excel-col-add mk-green" title="添加显示列字段" onClick={this.columnFieldInput}>
              同步显示列
              同步字段集
            </Button>
            <Button className="excel-col-add mk-red" title="清空Excel列" onClick={this.clearField}>
              清空Excel列
            </Button>
            <Col style={{fontSize: '12px', color: '#757575', paddingLeft: '10px'}} span={24}>注:数值类型(int 或 decimal),内容为必填;最大值和最小值在类型为数值时有效。导入-初始化:用于excel中不存在,导入时需要初始化的字段</Col>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'extra:required:是否必填']} type="excelcolumn" data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'extra:required:是否必填']} searchKey={searchKey} type="excelcolumn" data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
          </TabPane>
          {card.intertype === 'system' ? <TabPane tab={
            <span>
@@ -951,7 +957,12 @@
            />
            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
          </TabPane> : null}
          <TabPane tab="信息提示" key="tip">
          <TabPane tab={
            <span>
              信息提示
              {activeKey === 'excelcolumn' ? <span onClick={(e) => {e.stopPropagation()}}><Search className="mk-search-fields" defaultValue={searchKey} allowClear onSearch={(val, e) => {e.stopPropagation();this.setState({searchKey: val})}} /></span> : null}
            </span>
          } key="tip">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col offset={6} span={6}>
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss
@@ -15,6 +15,34 @@
    color: #1890ff;
    font-size: 12px;
  }
  .mk-search-fields {
    position: absolute;
    cursor: pointer;
    width: 150px;
    z-index: 1;
    top: 10px;
    right: -170px;
    display: inline-block;
    .ant-input {
      border-radius: 40px;
      height: 30px;
      transition: opacity 0.2s;
    }
    .ant-input:not(:hover):not(:active):not(:focus) {
      opacity: 0.6;
    }
    .ant-input:not(:hover):not(:active):not(:focus) + .ant-input-suffix {
      opacity: 0.6;
    }
  }
  .mk-search-fields:hover {
    .ant-input {
      opacity: 1;
    }
    .ant-input-suffix {
      opacity: 1;
    }
  }
  .verify-form {
    .sql {
      .ant-col-sm-8 {
src/templates/sharecomponent/actioncomponent/verifyexcelin/uniqueform/index.jsx
@@ -98,7 +98,7 @@
          <Col span={7}>
            <Form.Item label="验证类型">
              {getFieldDecorator('verifyType', {
                initialValue: 'physical',
                initialValue: 'logic',
                rules: [
                  {
                    required: true,
@@ -107,15 +107,15 @@
                ]
              })(
                <Select>
                  <Select.Option value="physical"> 物理验证(全量验证) </Select.Option>
                  <Select.Option value="logic"> 逻辑验证(全量验证) </Select.Option>
                  <Select.Option value="physical"> 物理验证(全量验证) </Select.Option>
                  <Select.Option value="physical_temp"> 物理验证(仅临时表) </Select.Option>
                  <Select.Option value="logic_temp"> 逻辑验证(仅临时表)  </Select.Option>
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={3} className="add">
          <Col span={3} className="add" style={{paddingTop: '4px'}}>
            <Button onClick={this.handleConfirm} className="mk-green">
              添加
            </Button>
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Spin, Typography, Popconfirm } from 'antd'
import { Form, Tabs, Row, Col, Button, Input, notification, Modal, message, InputNumber, Spin, Typography, Popconfirm } from 'antd'
import { EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
import md5 from 'md5'
@@ -16,6 +16,7 @@
const { TabPane } = Tabs
const { confirm } = Modal
const { Search } = Input
const { Paragraph } = Typography
const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
@@ -29,6 +30,7 @@
    verify: {},
    debugId: '',
    activeKey: 'setting',
    searchKey: '',
    excelColumns: [
      {
        title: '字段',
@@ -36,6 +38,8 @@
        inputType: 'input',
        editable: true,
        unique: true,
        searchable: true,
        copy: true,
        width: '16%'
      },
      {
@@ -43,6 +47,7 @@
        dataIndex: 'Text',
        inputType: 'input',
        editable: true,
        searchable: true,
        unique: true,
        width: '16%'
      },
@@ -354,6 +359,7 @@
    }
    this.setState({
      searchKey: '',
      verify: _verify,
      searches: searches,
      activeKey: card.intertype === 'system' && _verify.dataType === 'custom' ? 'setting' : 'columns'
@@ -501,6 +507,7 @@
  }
  handleConfirm = () => {
    const { card, config } = this.props
    const { activeKey, verify } = this.state
    
    // 表单提交时检查输入值是否正确
@@ -516,6 +523,24 @@
        })
        
        return
      }
      if (card.intertype === 'system' && verify.dataType !== 'custom' && verify.columns.length > 0 && config.$c_ds && config.setting.interType === 'system' && config.columns && config.columns.length > 0) {
        let cols = []
        let columns = config.columns.map(c => c.field)
        verify.columns.forEach(col => {
          if (col.output === 'false' || col.Column === '$Index') return
          if (!columns.includes(col.Column)) {
            cols.push(col.Column)
          }
        })
        if (cols.length) {
          notification.warning({
            top: 92,
            message: `导出列(${cols.join('、')})在字段集中不存在!`,
            duration: 5
          })
        }
      }
      if (activeKey === 'setting') {
@@ -937,7 +962,7 @@
  render() {
    const { card } = this.props
    const { verify, excelColumns, scriptsColumns, activeKey, loading, searches } = this.state
    const { verify, excelColumns, scriptsColumns, activeKey, loading, searches, searchKey } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -965,13 +990,13 @@
          } key="columns">
            <ColumnForm columnChange={this.columnChange}/>
            <Button className="excel-col-add mk-green" title="添加显示列字段" onClick={this.columnFieldInput}>
              同步显示列
              同步字段集
            </Button>
            <Button className="excel-col-add mk-red" title="清空Excel列" onClick={this.clearField}>
              清空Excel列
            </Button>
            <div style={{color: '#959595', fontSize: '13px', paddingLeft: '10px'}}>如需导出序号,请使用字段 $Index;数值类型导出时可取绝对值以及设置小数位;导出为否时,不使用行信息;红色标题导出时列头文字为红色。</div>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" wrappedComponentRef={(inst) => this.columnRef = inst} data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" searchKey={searchKey} wrappedComponentRef={(inst) => this.columnRef = inst} data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
          </TabPane>
          {card.intertype === 'system' ? <TabPane tab={
            <span>
@@ -988,7 +1013,12 @@
            />
            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
          </TabPane> : null}
          <TabPane tab="信息提示" key="message">
          <TabPane tab={
            <span>
              信息提示
              {activeKey === 'columns' ? <span onClick={(e) => {e.stopPropagation()}}><Search className="mk-search-fields" defaultValue={searchKey} allowClear onSearch={(val, e) => {e.stopPropagation();this.setState({searchKey: val})}} /></span> : null}
            </span>
          } key="message">
            <Form {...formItemLayout}>
              <Row gutter={24}>
                <Col offset={6} span={6}>
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss
@@ -15,6 +15,34 @@
    color: #1890ff;
    font-size: 12px;
  }
  .mk-search-fields {
    position: absolute;
    cursor: pointer;
    width: 150px;
    z-index: 1;
    top: 10px;
    right: -170px;
    display: inline-block;
    .ant-input {
      border-radius: 40px;
      height: 30px;
      transition: opacity 0.2s;
    }
    .ant-input:not(:hover):not(:active):not(:focus) {
      opacity: 0.6;
    }
    .ant-input:not(:hover):not(:active):not(:focus) + .ant-input-suffix {
      opacity: 0.6;
    }
  }
  .mk-search-fields:hover {
    .ant-input {
      opacity: 1;
    }
    .ant-input-suffix {
      opacity: 1;
    }
  }
  .verify-form {
    .sql {
      .ant-col-sm-8 {
src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -270,7 +270,7 @@
      dataType: _verify.dataType || 'line',
      linkType: _verify.linkType,
      printMode: _verify.printMode,
      printFunc: _verify.printFunc || '// Function(data, form, printer, notification) data-打印数据列表,form-表单信息(不存在时为{}),printer-打印设置,notification-信息提示控件,callback-释放按钮的回调'
      printFunc: _verify.printFunc || '// Function(data, form, printer, notification, Api, systemType, callback) data-打印数据列表,form-表单信息(不存在时为{}),printer-打印设置,notification-信息提示控件(移动端为Toast),Api-接口,systemType-系统类型(正式为 production,测试为空),callback-释放按钮的回调'
    })
  }
src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -288,6 +288,25 @@
      reLabel.field = '类型字段'
    }
    reTooltip.initval = ''
    if (type === 'select') {
      if (this.record.resourceType === '0') {
        reTooltip.initval = '初始值应为数据的Value值,可使用@username@、@fullName@'
      } else if (this.record.resourceType === '1') {
        reTooltip.initval = '初始值应为《值·字段》的值,可使用@username@、@fullName@、$first。注:使用$first时,搜索条件应为必填。'
      }
    } else if (type === 'link') {
      if (this.record.resourceType === '0') {
        reTooltip.initval = '初始值应为数据的Value值。'
      } else if (this.record.resourceType === '1') {
        reTooltip.initval = '初始值应为《值·字段》的值,可使用$first。注:使用$first时,搜索条件应为必填。'
      }
    } else if (type === 'text') {
      reTooltip.initval = '可使用@username@、@fullName@。'
    } else if (type === 'range') {
      reTooltip.initval = '使用逗号拼接,例如 3,10'
    }
    return {
      shows,
      reOptions,
@@ -690,6 +709,23 @@
            values.field = values.field.join(',')
          }
          if (['select', 'link'].includes(values.type)) {
            if (values.resourceType === '1') {
              if (/\$first/.test(values.initval) && values.initval.replace(/\s/g, '') === '$first') {
                values.initval = '$first'
              }
              if (values.initval === '$first' && values.required !== 'true') {
                notification.warning({
                  top: 92,
                  message: '使用$first时,搜索条件应为必填!',
                  duration: 5
                })
                return
              }
            }
          }
          // 下拉菜单或联动菜单
          if (['multiselect', 'select', 'link', 'radio'].includes(values.type)) {
            if (values.resourceType === '0') {
src/templates/zshare/codemirror/index.jsx
@@ -240,7 +240,7 @@
          {fullScreen || func ? <Dropdown overlayClassName="mk-mirror-font" overlay={menu} placement="bottomRight">
            <FontSizeOutlined />
          </Dropdown> : null}
          <SwapOutlined title="字符替换" onClick={() => this.setState({visible: true})}/>
          {!mode ? <SwapOutlined title="字符替换" onClick={() => this.setState({visible: true})}/> : null}
          {display ? <CodeMirror
            className="code-mirror-area"
            value={defaultVal}
src/templates/zshare/editTable/index.jsx
@@ -826,7 +826,17 @@
      return item
    })
    let reg = searchKey ? new RegExp(searchKey, 'i') : null
    let reg = null
    let regs = []
    if (searchKey) {
      reg = new RegExp(searchKey, 'i')
      this.state.columns.forEach(col => {
        if (col.searchable) {
          regs.push(col.dataIndex)
        }
      })
    }
    return (
      <EditableContext.Provider value={this.props.form}>
@@ -845,7 +855,7 @@
                  className += ' active'
                }
                if (searchKey) {
                  if (!reg.test(record.field) && !reg.test(record.label)) {
                  if (regs.findIndex(f => reg.test(record[f])) === -1) {
                    className += ' hidden'
                  }
                }
src/templates/zshare/formconfig.jsx
@@ -166,7 +166,6 @@
      type: 'text',
      key: 'initval',
      label: '初始值',
      tooltip: '类型为下拉菜单时,初始值应为数据的Value值(使用数据源时,应为《值·字段》的值);类型为数值(区间)时,初始值使用逗号拼接,例如 3,10;文本与下拉菜单中可使用@username@、@fullName@',
      initVal: card.initval,
      required: false
    },
src/templates/zshare/verifycard/baseform/index.jsx
@@ -6,6 +6,7 @@
import Api from '@/api'
import MkPrintTemps from '@/menu/components/share/actioncomponent/actionform/mkPrintTemps'
import CodeMirror from '@/templates/zshare/codemirror'
import './index.scss'
const sysTempsIds = ['8IFltwzyKcu15iA8fqSyb6m-pMa88a3ZTu0No3vDHgo', 'LOB-bbt9jVncGh7IOAUdESh1Sgzcbt62UwOqSqcK9ok']
@@ -16,6 +17,7 @@
    verify: PropTypes.object,
    unionFields: PropTypes.array,
    notes: PropTypes.array,
    emailCodes: PropTypes.array,
    appType: PropTypes.any,
    onChange: PropTypes.func
  }
@@ -128,10 +130,14 @@
    let error = ''
    if (verify.noteEnable === 'true' && !verify.noteCode) { // 开启短信时,需要模板编码
      error = '开启短信时,需要选择短信模板!'
    } else if (verify.emailEnable === 'true' && !verify.emailCode) {
      error = '开启邮件发送时,需要选择邮件模板!'
    } else if (verify.printEnable === 'true' && !verify.printTempId) {
      error = '使用单据打印时,需要选择打印模板!'
    } else if (verify.accountdate === 'true' && !verify.accountfield) {
      error = '开启账期时,需要选择验证公司!'
    } else if (verify.preHandle === 'true' && !verify.pre_func) {
      error = '开启按钮预处理时,需要填写处理函数!'
    } else if (verify.wxNote === 'true') {
      if (!verify.wxTemplateId) {
        error = '开启公众号消息推送时,需要选择消息模板!'
@@ -152,6 +158,11 @@
    if (_verify.noteEnable !== 'true') {
      _verify.noteCode = ''
      _verify.noteId = ''
    }
    if (_verify.emailEnable !== 'true') {
      _verify.emailCode = ''
      _verify.emailId = ''
    }
    if (_verify.printEnable !== 'true') {
      _verify.printTempId = ''
@@ -159,6 +170,9 @@
    if (_verify.accountdate !== 'true') {
      _verify.accountfield = ''
      _verify.voucherdate = ''
    }
    if (_verify.preHandle !== 'true') {
      _verify.pre_func = ''
    }
    if (_verify.wxNote !== 'true') {
      _verify.wxTemplateId = ''
@@ -182,6 +196,14 @@
    const { verify } = this.props
    let _verify = {...verify, noteCode: val, noteId: option.props.id}
    this.props.onChange(_verify)
  }
  onEmailCodeChange = (val, option) => {
    const { verify } = this.props
    let _verify = {...verify, emailCode: val, emailId: option.props.id}
    this.props.onChange(_verify)
  }
@@ -270,7 +292,7 @@
  }
  render() {
    const { unionFields, verify, notes, card, appType, columns } = this.props
    const { unionFields, verify, notes, emailCodes, card, appType, columns } = this.props
    const { wxTemps, selectTemp } = this.state
    const formItemLayout = {
      labelCol: {
@@ -379,7 +401,7 @@
                短信模板
              </Tooltip>
            } required>
              <Select value={verify.noteCode} onSelect={this.onNoteCodeChange}>
              <Select value={verify.noteCode || ''} onSelect={this.onNoteCodeChange}>
                {notes.map(option =>
                  <Select.Option key={option.value} id={option.id} value={option.value}>
                    {option.name}
@@ -395,7 +417,7 @@
                发送方式
              </Tooltip>
            }>
              <Radio.Group value={verify.noteType} onChange={(e) => {this.onOptionChange(e.target.value, 'noteType')}}>
              <Radio.Group value={verify.noteType || 'N'} onChange={(e) => {this.onOptionChange(e.target.value, 'noteType')}}>
                <Radio value="Y">实时</Radio>
                <Radio value="N">定时</Radio>
              </Radio.Group>
@@ -408,7 +430,63 @@
                短信内容
              </Tooltip>
            }>
              <Radio.Group value={verify.noteTemp} onChange={(e) => {this.onOptionChange(e.target.value, 'noteTemp')}}>
              <Radio.Group value={verify.noteTemp || 'Y'} onChange={(e) => {this.onOptionChange(e.target.value, 'noteTemp')}}>
                <Radio value="Y">相同</Radio>
                <Radio value="N">不同</Radio>
              </Radio.Group>
            </Form.Item>
          </Col> : null}
          <Col span={24}></Col>
          <Col span={8}>
            <Form.Item label={
              <Tooltip placement="bottomLeft" title={'选择发送邮件时,需完善邮件设置。'}>
                <QuestionCircleOutlined className="mk-form-tip" />
                发送邮件
              </Tooltip>
            }>
              <Radio.Group value={verify.emailEnable} onChange={(e) => {this.onOptionChange(e.target.value, 'emailEnable')}}>
                <Radio value="true">开启</Radio>
                <Radio value="false">不开启</Radio>
              </Radio.Group>
            </Form.Item>
          </Col>
          {verify.emailEnable === 'true' ? <Col span={8}>
            <Form.Item label={
              <Tooltip placement="bottomLeft" title={<span>邮件模板添加地址:<a target="_blank" rel="noopener noreferrer" href="https://cloud.mk9h.cn/admin/index.html">云中心</a>-&gt;应用服务-&gt;开发者中心-&gt;邮件模板。</span>}>
                <QuestionCircleOutlined className="mk-form-tip" />
                邮件模板
              </Tooltip>
            } required>
              <Select value={verify.emailCode || ''} onSelect={this.onEmailCodeChange}>
                {emailCodes.map(option =>
                  <Select.Option key={option.value} id={option.id} value={option.value}>
                    {option.name}
                  </Select.Option>
                )}
              </Select>
            </Form.Item>
          </Col> : null}
          {verify.emailEnable === 'true' ? <Col span={8}>
            <Form.Item label={
              <Tooltip placement="bottomLeft" title={'实时发送最多同时发送5个用户,定时发送最多同时发送100个用户。'}>
                <QuestionCircleOutlined className="mk-form-tip" />
                发送方式
              </Tooltip>
            }>
              <Radio.Group value={verify.emailType || 'N'} onChange={(e) => {this.onOptionChange(e.target.value, 'emailType')}}>
                <Radio value="Y">实时</Radio>
                <Radio value="N">定时</Radio>
              </Radio.Group>
            </Form.Item>
          </Col> : null}
          {verify.emailEnable === 'true' ? <Col span={8}>
            <Form.Item label={
              <Tooltip placement="bottomLeft" title={'当向多个用户发送短信时,短信内容是否相同。'}>
                <QuestionCircleOutlined className="mk-form-tip" />
                邮件内容
              </Tooltip>
            }>
              <Radio.Group value={verify.emailTemp || 'Y'} onChange={(e) => {this.onOptionChange(e.target.value, 'emailTemp')}}>
                <Radio value="Y">相同</Radio>
                <Radio value="N">不同</Radio>
              </Radio.Group>
@@ -616,6 +694,23 @@
              </div>
            </div>
          </Col> : null}
          <Col span={24}></Col>
          <Col span={8}>
            <Form.Item label={
              <Tooltip placement="topRight" title="运行时修改按钮参数,入参为(btn, systemType)。注:systemType为系统类型,正式系统为production">
                <QuestionCircleOutlined className="mk-form-tip" />
                按钮预处理
              </Tooltip>
            }>
              <Radio.Group value={verify.preHandle || 'false'} onChange={(e) => {this.onOptionChange(e.target.value, 'preHandle')}}>
                <Radio value="true">开启</Radio>
                <Radio value="false">不开启</Radio>
              </Radio.Group>
            </Form.Item>
          </Col>
          {verify.preHandle === 'true' ? <Col span={24} style={{paddingLeft: '50px'}}>
            <CodeMirror mode="text/javascript" theme="cobalt" value={verify.pre_func || ''} onChange={(val) => {this.onOptionChange(val, 'pre_func')}} />
          </Col> : null}
        </Row>
      </Form>
    )
src/templates/zshare/verifycard/billcodeform/index.jsx
@@ -311,7 +311,7 @@
            </Button>
          </Col>
          {type === '1' ? <Col span={7}>
            <Form.Item label={'位数'}>
            <Form.Item label="位数">
              {getFieldDecorator('Type', {
                initialValue: 4,
                rules: [
@@ -320,11 +320,11 @@
                    message: '请输入位数!'
                  }
                ]
              })(<InputNumber min={1} max={10} precision={0} />)}
              })(<InputNumber min={1} max={10} precision={0} onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col> : null}
          {type === '2' ? <Col span={7}>
            <Form.Item label={'凭证标识'}>
            <Form.Item label="凭证标识">
              {getFieldDecorator('ModularDetailCode', {
                initialValue: this.state.modularDetail[0] ? this.state.modularDetail[0].ModularDetailCode : '',
                rules: [
@@ -366,7 +366,7 @@
                    message: '请输入数字、字母以及_'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col> : null}
        </Row>
src/templates/zshare/verifycard/callbackcustomscript/index.jsx
@@ -265,10 +265,10 @@
              取消
            </Button>
          </Col>
          {!type ? <Col span={3} style={{paddingTop: '15px', fontSize: '12px', whiteSpace: 'nowrap'}}>
          <Col span={3} className="forced" style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}>
            强制保存:
            <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/>
          </Col> : null}
          </Col>
          <Col span={24} className="sql">
            <Form.Item label="sql">
              {getFieldDecorator('sql', {
src/templates/zshare/verifycard/contrastform/index.jsx
@@ -48,7 +48,7 @@
                    message: '请输入内容1!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col>
          <Col span={7}>
@@ -85,7 +85,7 @@
                    message: '请输入内容2!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col>
          <Col span={3} className="add">
@@ -107,11 +107,11 @@
                    message: '提示信息不允许包含\''
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col>
          <Col span={7}>
            <Form.Item label={'报错编码'}>
            <Form.Item label="报错编码">
              {getFieldDecorator('errorCode', {
                initialValue: 'E',
                rules: [
src/templates/zshare/verifycard/customform/index.jsx
@@ -195,7 +195,7 @@
                    message: '提示信息不允许包含\''
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col>
          <Col span={7}>
src/templates/zshare/verifycard/customscript/index.jsx
@@ -351,10 +351,10 @@
              取消
            </Button>
          </Col>
          {!_type ? <Col span={3} style={{paddingTop: '15px', fontSize: '12px', whiteSpace: 'nowrap'}}>
          <Col span={3} className="forced" style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}>
            强制保存:
            <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/>
          </Col> : null}
          </Col>
          <Col span={24} className="sql">
            <Form.Item label={
              <Tooltip placement="topLeft" overlayStyle={{width: '320px', maxWidth: '320px'}} title={<><div>{'调试替换符 /*$breakpoint_begin_xxxx@ 、@breakpoint_end_xxxx$*/,在控制台中输入 window.debug = \'xxxx\' 会启用对应的调试语句,快捷键 ctrl+c 或在控制台中输入 window.debug = false 关闭调试。注:调试时字符 $breakpoint_proc@ 将被替换。'}</div><div style={{height: '5px'}}></div><div>{'数据检查替换符 $check@ -> \'\'、 @check$ -> \'\',ErrorCode等于C时会询问是否继续执行,确定时 $check@ -> /*、 @check$ -> */。注:1、需使用系统接口 2、行设置为“选择多行”时无效。'}</div></>}>
src/templates/zshare/verifycard/fullScripts/index.scss
@@ -112,7 +112,7 @@
            width: 89.5%;
          }
        }
        .add {
        .add {
          position: absolute;
          top: 10px;
          z-index: 1;
@@ -125,6 +125,13 @@
            margin-right: 10px;
          }
        }
        .forced {
          position: absolute;
          top: 10px;
          z-index: 1;
          text-align: right;
          right: 80px;
        }
      }
    }
  }
src/templates/zshare/verifycard/index.jsx
@@ -42,6 +42,7 @@
    activeKey: 'base',
    appType: sessionStorage.getItem('appType'),
    notes: [],              // 短信模板
    emailCodes: [],         // 邮箱模板
    verify: {},
    fields: [],
    usefulfields: '',
@@ -571,9 +572,9 @@
    _verify.default = _verify.default || 'true'
    _verify.wxNote = _verify.wxNote || 'false'           // 公众号消息推送是否开启
    _verify.noteEnable = _verify.noteEnable || 'false'   // 短信发送是否开启
    _verify.emailEnable = _verify.emailEnable || 'false' // 邮件发送是否开启
    _verify.printEnable = _verify.printEnable || 'false' // 单据打印是否开启
    _verify.noteType = _verify.noteType || 'N'           // 短信发送模式:Y(实时)、N(定时)
    _verify.noteTemp = _verify.noteTemp || 'Y'           // 短信发送模板:Y(相同)、N(不同)
    _verify.preHandle = _verify.preHandle || 'false'     // 按钮预处理是否开启
    _verify.invalid = _invalid
    _verify.uniques = _verify.uniques || []
    _verify.contrasts = _verify.contrasts || []
@@ -1063,6 +1064,11 @@
        LText: window.btoa(window.encodeURIComponent(`select t.id,templatecode,'['+SignName+']'+describe as describe from (select * from bd_msn_sms_temp where  deleted=0 and TypeDesc='QX' and status=20 ) t inner join (select openid from susers where uid=@userid@) u on t.openid =t.openid`))
      },
      {
        obj_name: 'emailCodes',
        arr_field: 'msn_email_temp_no,remark,id',
        LText: window.btoa(window.encodeURIComponent(`select t.id,t.msn_email_temp_no,t.remark from (select * from bd_msn_email_temp where deleted=0) t inner join (select openid from susers where uid=@userid@) u on t.openid=t.openid`))
      },
      {
        obj_name: 'scripts',
        arr_field: 'funcname,longparam',
        LText: window.btoa(window.encodeURIComponent(`Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort`))
@@ -1101,6 +1107,13 @@
            return {
              name: item.describe,
              value: item.templatecode,
              id: item.id
            }
          }),
          emailCodes: res.emailCodes.map(item => {
            return {
              name: item.remark,
              value: item.msn_email_temp_no,
              id: item.id
            }
          }),
@@ -1559,7 +1572,7 @@
  render() {
    const { card, columns } = this.props
    const { activeKey, verifyInter, verify, fields, uniqueFields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, cbScriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes, appType } = this.state
    const { activeKey, verifyInter, verify, fields, uniqueFields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, cbScriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes, emailCodes, appType } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -1581,7 +1594,7 @@
              {verify.default === 'false' ? <span className="count-tip"><ExclamationOutlined style={{color: 'orange'}}/></span> : null}
            </span>
          } key="base">
            <BaseForm card={card} appType={appType} columns={columns} unionFields={unionFields} verify={verify} notes={notes} onChange={(verify) => this.setState({verify})} wrappedComponentRef={(inst) => this.baseForm = inst}/>
            <BaseForm card={card} appType={appType} columns={columns} unionFields={unionFields} verify={verify} notes={notes} emailCodes={emailCodes} onChange={(verify) => this.setState({verify})} wrappedComponentRef={(inst) => this.baseForm = inst}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
            <span>
src/templates/zshare/verifycard/uniqueform/index.jsx
@@ -106,8 +106,8 @@
                ]
              })(
                <Select>
                  <Select.Option value="physical"> 物理验证 </Select.Option>
                  <Select.Option value="logic"> 逻辑验证 </Select.Option>
                  <Select.Option value="physical"> 物理验证 </Select.Option>
                </Select>
              )}
            </Form.Item>
src/utils/utils-datamanage.js
@@ -204,8 +204,14 @@
        } else {
          DateCount = `/*system_query*/select count(1) as total from ${_dataresource} ${_search}`
        }
      } else if (setting.$top) {
        if (orderBy) {
          LText = `/*system_query*/select top 1 ${arr_field} from ${_dataresource} ${_search} order by ${orderBy} `
        } else {
          LText = `/*system_query*/select top 1 ${arr_field} from ${_dataresource} ${_search}  `
        }
      } else if (orderBy) {
        LText = `/*system_query*/select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows `
        LText = `/*system_query*/select ${arr_field} from ${_dataresource} ${_search} order by ${orderBy} `
      } else {
        LText = `/*system_query*/select ${arr_field} from ${_dataresource} ${_search}  `
      }
@@ -458,8 +464,14 @@
    _search = _search ? 'where ' + _search : ''
  }
  if (setting.order && _dataresource) {
    _dataresource = `select top 1000 ${setting.arr_field} from (select ${setting.arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows `
  if (setting.$top) {
    if (setting.order && _dataresource) {
      _dataresource = `select top 1 ${setting.arr_field} from ${_dataresource} ${_search} order by ${setting.order} `
    } else if (_dataresource) {
      _dataresource = `select top 1 ${setting.arr_field} from ${_dataresource} ${_search} `
    }
  } else if (setting.order && _dataresource) {
    _dataresource = `select top 1000 ${setting.arr_field} from ${_dataresource} ${_search} order by ${setting.order} `
  } else if (_dataresource) {
    _dataresource = `select top 1000 ${setting.arr_field} from ${_dataresource} ${_search} `
  }
src/utils/utils.js
@@ -348,6 +348,9 @@
          item.initval = ''
          item.initType = ''
        }
      } else if ((item.type === 'select' || item.type === 'link') && item.initval === '$first' && item.resourceType === '1') {
        item.initval = ''
        item.$first = true
      }
      
      item.oriInitval = item.initval
@@ -1115,10 +1118,19 @@
    let _insert = ''
    if (btn.default !== 'false') {
      let _fields = []
      btn.columns.forEach(col => {
        if (col.import === 'false' || col.import === 'init') return
        _fields.push(col.Column)
      })
      _fields = _fields.join(',')
      _insert = `
      /* 默认sql */
      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
      Select ${fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
      Insert into ${database}${sheet} (${_fields},createuserid,createuser,createstaff,bid)
      Select ${_fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
      `
    }
src/views/billprint/index.jsx
@@ -395,6 +395,10 @@
                } else {
                  item.IsSort = 'false'
                }
                if (item.marks && item.marks.length === 0) {
                  item.marks = null
                }
          
                return true
              })
@@ -461,6 +465,11 @@
          if (!component.format) return component  // 没有动态数据  数据格式 array 或 object
          component.setting.arr_field = component.columns ? component.columns.map(col => col.field).join(',') : ''
          component.setting.laypage = false   // 是否分页,转为boolean 统一格式
          if (component.format === 'object') {
            component.setting.$top = true
          }
          if (component.setting.interType !== 'system') { // 不使用系统函数时
            component.setting.sync = 'false'
@@ -484,7 +493,6 @@
          delete component.scripts
    
          component.setting.execute = component.setting.execute !== 'false'  // 默认sql是否执行,转为boolean 统一格式
          component.setting.laypage = false   // 是否分页,转为boolean 统一格式
          component.setting.onload = 'true'   // 默认加载
    
          if (!component.setting.execute) {
@@ -610,6 +618,10 @@
    if (cell.style.display === 'inline-block') {
      cell.style.verticalAlign = 'top'
    }
    if (cell.marks && cell.marks.length === 0) {
      cell.marks = null
    }
    
    if (['text', 'number', 'formula'].includes(cell.eleType)) {
      cell.innerHeight = cell.innerHeight || 'auto'
@@ -673,7 +685,8 @@
      inter.setting.$name = '公共数据源-' + inter.setting.name
      inter.setting.execute = inter.setting.execute !== 'false'
      inter.setting.laypage = true
      inter.setting.laypage = false
      inter.setting.$top = true
      if (!inter.setting.execute) {
        inter.setting.dataresource = ''
src/views/design/header/index.jsx
@@ -141,6 +141,7 @@
                EasyCode: trd.EasyCode,
                type: 'CommonTable',            // 默认值为常用表
                OpenType: 'newtab',             // 打开方式
                up_action: window.GLOB.upStatus && trd.up_action === 'Y',
                level: 'third'
              }
  
src/views/design/sidemenu/index.jsx
@@ -326,7 +326,7 @@
                {item.children.map(cell => {
                  return (
                    <Menu.Item key={cell.MenuID}>
                      <span className="editable-menu-item" onDoubleClick={() => this.editmenu(cell)}>{cell.PageParam && cell.PageParam.interfaces === 'true' ? <ApiOutlined title="菜单中使用了外部接口" /> : null}{cell.MenuName}</span>
                      <span className={'editable-menu-item ' + (cell.up_action ? 'unupdate' : '')} onDoubleClick={() => this.editmenu(cell)}>{cell.PageParam && cell.PageParam.interfaces === 'true' ? <ApiOutlined title="菜单中使用了外部接口" /> : null}{cell.MenuName}</span>
                    </Menu.Item>
                  )
                })}
src/views/design/sidemenu/index.scss
@@ -24,6 +24,10 @@
        color: orange;
      }
    }
    .editable-menu-item.unupdate {
      color: orange;
    }
  }
  .ant-menu-sub.ant-menu-inline {
    position: relative;
src/views/interface/history/index.jsx
@@ -260,18 +260,18 @@
          ))}
          <div className="list-line" key="example">
            <div className="line-title">示例</div>
              <div className="line-item" key="dologon">
              <div className="line-item" style={{cursor: 'pointer'}} key="dologon" onClick={this.uselogon}>
                <div className="method">POST</div>
                <div className="inter" style={{lineHeight: '40px'}}>dologon</div>
                <div className="action" style={{paddingLeft: '40px'}}>
                  <RightOutlined onClick={this.uselogon} />
                  <RightOutlined/>
                </div>
              </div>
              <div className="line-item" key="dostars">
              <div className="line-item" style={{cursor: 'pointer'}} key="dostars" onClick={this.usedostars}>
                <div className="method">POST</div>
                <div className="inter" style={{lineHeight: '40px'}}>dostars</div>
                <div className="action" style={{paddingLeft: '40px'}}>
                  <RightOutlined onClick={this.usedostars} />
                  <RightOutlined/>
                </div>
              </div>
          </div>
src/views/login/index.jsx
@@ -891,7 +891,7 @@
            <a target="_blank" rel="noopener noreferrer" href={webSite} dangerouslySetInnerHTML={{ __html: copyRight.replace(/\s/ig, '&nbsp;') }}></a> :
            <p dangerouslySetInnerHTML={{ __html: copyRight ? copyRight.replace(/\s/ig, '&nbsp;') : '' }}></p>
          }
          {ICP ? <p dangerouslySetInnerHTML={{ __html: ICP.replace(/\s/ig, '&nbsp;') }}></p> : null}
          {ICP ? <a target="_blank" rel="noopener noreferrer" href="https://beian.miit.gov.cn/#/Integrated/index" dangerouslySetInnerHTML={{ __html: ICP.replace(/\s/ig, '&nbsp;') }}></a> : null}
        </div>
        {/* 编辑状态登录 */}
        <Modal
src/views/login/index.scss
@@ -240,7 +240,7 @@
      margin-right: 15px;
    }
    a {
      display: inline-block;
      display: block;
      margin-bottom: 5px;
      color: var(--mk-sys-font-color);
    }
src/views/menudesign/index.jsx
@@ -749,6 +749,10 @@
        config.components = this.resetSyncQuery(config.components)
      }
      if (config.MenuID === 'home_page_id') {
        config.permission = 'false'
      }
      let tbs = []
      let btns = this.getMenuMessage(config, tbs)
      let arr = []
@@ -908,10 +912,10 @@
            duration: 2
          })
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          Modal.warning({
            width: 400,
            title: res.message,
            okText: '知道了'
          })
        }
        MKEmitter.emit('completeSave')
src/views/menudesign/menuform/index.jsx
@@ -50,6 +50,7 @@
    thdMenuList = JSON.parse(thdMenuList)
    let thdMenu = null
    let firstId = ''
    thdMenuList.forEach(trd => {
      if (MenuId === trd.MenuID) {
@@ -65,17 +66,21 @@
          smenulist = item.children
        }
      })
      firstId = thdMenu.FstId || ''
    }
    this.props.updateConfig({...config, fstMenuId: thdMenu ? thdMenu.FstId : ''})
    if (firstId !== config.fstMenuId) {
      this.props.updateConfig({...config, fstMenuId: firstId})
    }
    this.setState({
      fstMenuId: thdMenu ? thdMenu.FstId : '',
      fstMenuId: firstId,
      menulist,
      smenulist
    }, () => {
      this.props.form.setFieldsValue({
        fstMenuId: thdMenu ? thdMenu.FstId : '',
        fstMenuId: firstId,
        parentId: thdMenu ? thdMenu.ParentId : ''
      })
    })
@@ -149,24 +154,29 @@
        })
        let smenulist = []
        let firstId = ''
        if (thdMenu) {
          menulist.forEach(item => {
            if (item.MenuID === thdMenu.FstId) {
              smenulist = item.children
            }
          })
          firstId = thdMenu.FstId || ''
        }
        sessionStorage.setItem('fstMenuList', JSON.stringify(menulist))
        sessionStorage.setItem('thdMenuList', JSON.stringify(thdMenuList))
        this.props.updateConfig({...config, fstMenuId: thdMenu ? thdMenu.FstId : ''})
        if (firstId !== config.fstMenuId) {
          this.props.updateConfig({...config, fstMenuId: firstId})
        }
        this.setState({
          fstMenuId: thdMenu ? thdMenu.FstId : '',
          fstMenuId: firstId,
          menulist,
          smenulist
        }, () => {
          this.props.form.setFieldsValue({
            fstMenuId: thdMenu ? thdMenu.FstId : '',
            fstMenuId: firstId,
            parentId: thdMenu ? thdMenu.ParentId : ''
          })
        })
src/views/mobdesign/index.jsx
@@ -1688,10 +1688,10 @@
            duration: 2
          })
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          Modal.warning({
            width: 400,
            title: res.message,
            okText: '知道了'
          })
        }
        MKEmitter.emit('completeSave')
src/views/pcdesign/index.jsx
@@ -1405,10 +1405,10 @@
            duration: 2
          })
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          Modal.warning({
            width: 400,
            title: res.message,
            okText: '知道了'
          })
        }
        MKEmitter.emit('completeSave')
src/views/rolemanage/index.jsx
@@ -23,6 +23,7 @@
    app: null,
    loading: false,
    menulist: [],
    sortType: '',
    columns: [
      {
        title: '菜单名称', dataIndex: 'MenuName', key: 'MenuName', align: 'center', render: (text, record) => {
@@ -38,11 +39,19 @@
        title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo', align: 'center'
      },
      {
        title: '修改时间', dataIndex: 'modifydate', key: 'modifydate', align: 'center', sorter: true, render: (text, record) => {
          if (window.GLOB.upStatus && record.up_action === 'Y') {
            return <span style={{color: 'orange'}}>{text}</span>
          }
          return text
        }
      },
      {
        title: '操作',
        key: 'action',
        align: 'center',
        render: (text, record) => (
          <div>
          <div style={{minWidth: '125px'}}>
            {record.type !== 'none' ?
              <Button type="link" onClick={() => this.deleteMenu(record)} style={{color: '#ff4d4f'}}>删除</Button> :
              <Button type="link" onClick={() => {
@@ -878,12 +887,30 @@
    window.open(window.location.href.replace(/#.+/ig, `#/${route}/${window.btoa(window.encodeURIComponent(JSON.stringify({...app, MenuID: item.MenuID, type: 'app'})))}`))
  }
  changeTable = (pagination, filters, sorter) => {
    this.setState({sortType: sorter.order || ''})
  }
  render () {
    const { app, loading, columns, menulist, trees, searchkey } = this.state
    let _menulist = menulist
    const { app, loading, columns, menulist, trees, searchkey, sortType } = this.state
    let _menulist = fromJS(menulist).toJS()
    if (searchkey) {
      _menulist = _menulist.filter(item => item.MenuName.toLowerCase().indexOf(searchkey.toLowerCase()) > -1)
    }
    if (sortType === 'ascend') {
      _menulist.sort((a, b) => {
        if (a.modifydate > b.modifydate) return 1
        if (a.modifydate < b.modifydate) return -1
        return 0
      })
    } else if (sortType === 'descend') {
      _menulist.sort((a, b) => {
        if (a.modifydate < b.modifydate) return 1
        if (a.modifydate > b.modifydate) return -1
        return 0
      })
    }
    return (
@@ -907,6 +934,7 @@
                  columns={columns}
                  dataSource={_menulist}
                  pagination={false}
                  onChange={this.changeTable}
                />
              </div>
            </div>
src/views/rolemanage/index.scss
@@ -68,8 +68,8 @@
      border-radius: 4px;
    }
    .ant-table-tbody {
      > tr.ant-table-row-selected td {
        background: #bae7ff;
      td:nth-child(1), td:nth-child(2) {
        word-break: break-all;
      }
    }
  }
src/views/tabledesign/index.jsx
@@ -651,10 +651,10 @@
            duration: 2
          })
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          Modal.warning({
            width: 400,
            title: res.message,
            okText: '知道了'
          })
        }
        MKEmitter.emit('completeSave')