king
2023-04-07 20185ab64a165df51515d9fa1c9b12a7a8c55f59
2023-04-07
26个文件已修改
2个文件已添加
741 ■■■■ 已修改文件
src/components/normalform/modalform/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/paste/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/card.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/elementform/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/formconfig.jsx 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/options.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.jsx 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/double-data-card/index.jsx 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/tableHeader/index.jsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/tableHeader/index.scss 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.scss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/exceloutbutton/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/editcard/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/menuform/index.jsx 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.jsx
@@ -45,6 +45,8 @@
      
      item.hidden = false
      if (item.forbid && item.del) return false
      if (item.forbid) {
        item.hidden = true
      }
src/components/paste/index.jsx
@@ -33,10 +33,10 @@
          })
          this.setState({visible: false})
        } else {
          notification.success({
          notification.warning({
            top: 92,
            message: result.message,
            duration: 2
            duration: 5
          })
        }
      })
src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -1,7 +1,7 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Popover } from 'antd'
import { EditOutlined, CopyOutlined, CloseOutlined, FontColorsOutlined } from '@ant-design/icons'
import { EditOutlined, CopyOutlined, CloseOutlined, FontColorsOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons'
import MkIcon from '@/components/mk-icon'
import moment from 'moment'
@@ -84,6 +84,9 @@
      if (card.fixStyle === 'alone') {
        let _s = {fontSize: card.fixSize, color: card.fixColor, marginLeft: card.fixLeft, marginRight: card.fixRight}
        val = <><span style={_s}>{card.prefix || ''}</span>{`${card.datatype === 'static' ? (card.value || '') : (card.field || '')}`}<span style={_s}>{card.postfix || ''}</span></>
      }
      if (card.sortField) {
        val = <><span>{val}</span><span className="sort-wrap"><CaretUpOutlined /><CaretDownOutlined /></span></>
      }
      return (
        <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
@@ -211,6 +214,11 @@
    _style_ = {clear: 'left'}
  }
  let tableHCell = false
  if (parent.setting && parent.setting.cardRole === 'header') {
    tableHCell = true
  }
  return (
    <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
      <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
@@ -218,7 +226,7 @@
        <CopyOutlined className="copy" title="复制" onClick={() => copyCard(id)} />
        <CloseOutlined className="close" title="删除" onClick={() => delCard(id)} />
        <FontColorsOutlined className="style" title="调整样式" onClick={() => changeStyle(id)}/>
        {['text', 'number', 'slider', 'sequence', 'formula'].includes(card.eleType) ? <MarkColumn field={card.field || ''} columns={fields} type={card.eleType} marks={card.marks} onSubmit={(vals) => updateMarks({...card, marks: vals})} /> : null }
        {['text', 'number', 'slider', 'sequence', 'formula'].includes(card.eleType) && !tableHCell ? <MarkColumn field={card.field || ''} columns={fields} type={card.eleType} marks={card.marks} onSubmit={(vals) => updateMarks({...card, marks: vals})} /> : null }
      </div>
    } trigger="hover">
      <div ref={node => drag(drop(node))} style={_style_} className={'ant-col card-cell ant-col-' + card.width}>
src/menu/components/card/cardcellcomponent/dragaction/index.scss
@@ -214,4 +214,21 @@
    background-repeat: no-repeat;
    background-size: cover;
  }
  .sort-wrap {
    position: relative;
    margin-left: 5px;
    font-size: 12px;
    color: #bfbfbf;
    display: none;
    .anticon-caret-up {
      position: relative;
      top: -4px;
    }
    .anticon-caret-down {
      position: absolute;
      top: 5px;
      left: 0px;
    }
  }
}
src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -15,7 +15,7 @@
const cardTypeOptions = {
  sequence: ['eleType', 'width'],
  text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'anchors', 'noValue', 'bgImage', 'fixStyle', 'copyable', 'alignItems'],
  text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'anchors', 'noValue', 'bgImage', 'fixStyle', 'copyable', 'alignItems', 'sortField'],
  number: ['eleType', 'datatype', 'width', 'height', 'prefix', 'postfix', 'noValue', 'fixStyle', 'alignItems'],
  picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'maxWidth', 'link', 'noValue'],
  video: ['eleType', 'datatype', 'width', 'aspectRatio', 'autoPlay', 'loop', 'startTime', 'noValue', 'posterType'],
@@ -96,6 +96,26 @@
              }
            })
          }
        } else if (item.key === 'sortField' && !item.forbid) {
          item.options = []
          config.columns.forEach(col => {
            let label = `${col.field}(${col.label})`
            item.options.push({
              value: col.field,
              text: label
            })
          })
          if (config.subColumns) {
            config.subColumns.forEach(col => {
              let label = `${col.field}(${col.label})`
              item.options.push({
                value: col.field,
                text: label
              })
            })
          }
        } else if (item.key === 'value' && card.eleType === 'slider') {
          item.type = 'number'
          item.label = '值'
src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -43,6 +43,14 @@
    tooltip = '在扩展卡片中,动态数据显示值为获取到的第一行数据。'
  }
  let isHeader = false
  if (cardCell.$cardType === 'extendCard' && cardCell.setting.cardRole === 'header') {
    isHeader = true
    anchors = null
    card.link = ''
    _options = [{ value: 'text', text: '文本'}]
  }
  let width = card.width || 12
  if (/x/.test(card.width)) {
    width = +width.replace(/x/, '.5')
@@ -193,7 +201,8 @@
        { value: 'MM月DD日 ahh:mm', text: '自定义2(例:12月17日 上午10:57)' },
        { value: 'calendar1', text: '自定义3(例:今天 上午10:57)' },
        { value: 'calendar2', text: '自定义4(例:刚刚、昨天、5天前)' },
      ]
      ],
      forbid: isHeader
    },
    {
      type: 'select',
@@ -359,7 +368,8 @@
      tooltip: '绑定数据源字段,可根据返回值改变背景图。',
      required: false,
      allowClear: true,
      options: []
      options: [],
      forbid: isHeader
    },
    {
      type: 'cascader',
@@ -490,7 +500,8 @@
        { value: '', text: '无' },
        { value: 'dynamic', text: '动态' },
        { value: 'static', text: '静态' }
      ]
      ],
      forbid: isHeader
    },
    {
      type: 'radio',
@@ -584,7 +595,8 @@
        { value: '', text: '居上' },
        { value: 'center', text: '居中' },
        { value: 'end', text: '居下' }
      ]
      ],
      forbid: isHeader
    },
    {
      type: 'radio',
@@ -596,7 +608,8 @@
      options: [
        { value: '', text: '统一样式' },
        { value: 'alone', text: '独立样式' }
      ]
      ],
      forbid: isHeader
    },
    {
      type: 'radio',
@@ -608,7 +621,8 @@
      options: [
        { value: 'true', text: '是' },
        { value: 'false', text: '否' }
      ]
      ],
      forbid: isHeader
    },
    {
      type: 'number',
@@ -648,6 +662,16 @@
      tooltip: '前缀、后缀的右边距。',
      required: false
    },
    {
      type: 'select',
      key: 'sortField',
      label: '排序字段',
      initVal: card.sortField || '',
      required: false,
      allowClear: true,
      options: [],
      forbid: !isHeader
    },
  ]
  return forms
src/menu/components/card/cardcellcomponent/index.jsx
@@ -75,7 +75,7 @@
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (this.props.side !== nextProps.side) {
    if (this.props.side !== nextProps.side && nextProps.side) {
      this.setState({
        elements: fromJS(nextProps.elements).toJS()
      })
src/menu/components/card/cardcomponent/index.jsx
@@ -12,6 +12,8 @@
import MKEmitter from '@/utils/events.js'
import './index.scss'
const { confirm } = Modal
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
@@ -129,6 +131,10 @@
    newcard.datatype = 'dynamic'
    newcard.height = 1
    if (card.$cardType === 'extendCard' && card.setting.cardRole === 'header') {
      newcard.datatype = 'static'
    }
    // 注册事件-添加元素
    MKEmitter.emit('cardAddElement', card.uuid, newcard)
  }
@@ -188,6 +194,39 @@
  updateSetting = (res) => {
    const { card, side, appType } = this.state
    if (card.$cardType === 'extendCard' && res.cardRole === 'header') {
      let _card = {...card, setting: res}
      let originLength = _card.elements.length
      _card.elements = _card.elements.filter(item => item.eleType === 'text')
      _card.backElements = []
      delete _card.menus
      if (_card.elements.length < originLength) {
        const that = this
        confirm({
          title: '表格头仅支持文本,确定要切换卡片角色吗?',
          content: '',
          okText: '确定',
          cancelText: '取消',
          onOk() {
            that.setState({ card: _card, side: '', elements: fromJS(_card.elements).toJS() }, () => {
              that.setState({ side: 'front' })
            })
            that.props.updateElement(_card)
          },
          onCancel() {}
        })
      } else {
        this.setState({ card: _card, side: 'front' })
        this.props.updateElement(_card)
      }
      return
    }
    if (appType === '' && res.menu) {
      let list = null
      try {
@@ -237,6 +276,11 @@
    let _uuid = Utils.getuuid()
    
    if (card.$cardType === 'extendCard' && card.setting.cardRole === 'header' && element.eleType !== 'text') {
      resolve({status: false, message: '表格头仅支持文本元素!'})
      return
    }
    if (element.copyType === 'action') {
      element.eleType = 'button'
    }
@@ -325,16 +369,21 @@
      }
    }
    let tablerole = ''
    if (card.$cardType === 'extendCard' && card.setting.cardRole === 'header') {
      tablerole = ' mk-table-header'
    }
    return (
      <Col span={card.setting.width || 6}>
        <div className={'card-item ' + (card.setting.btnControl || '') + checkAll} style={_style} onDoubleClick={(e) => {e.stopPropagation(); this.doubleClickCard()}} id={card.uuid}>
        <div className={'card-item ' + (card.setting.btnControl || '') + checkAll + tablerole} style={_style} onDoubleClick={(e) => {e.stopPropagation(); this.doubleClickCard()}} id={card.uuid}>
          <span className="circle-select"></span>
          <CardCellComponent cards={cards} cardCell={card} side={side} elements={elements} updateElement={this.updateCard}/>
          <div className="card-control" onDoubleClick={(e) => e.stopPropagation()}>
            <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
              <div className="mk-popover-control">
                <PlusOutlined className="plus" title="添加元素" onClick={this.addElement} />
                <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton} />
                {!tablerole ? <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton} /> : null}
                <NormalForm title={cards.subtype === 'datacard' && card.$cardType !== 'extendCard' ? '循环卡片设置' : '属性卡片设置'} width={950} update={this.updateSetting} getForms={this.getSettingForms}>
                  <EditOutlined className="edit" title="编辑"/>
                </NormalForm>
src/menu/components/card/cardcomponent/index.scss
@@ -93,3 +93,8 @@
    border-radius: 0;
  }
}
.card-item.mk-table-header {
  .sort-wrap {
    display: inline;
  }
}
src/menu/components/card/cardcomponent/options.jsx
@@ -61,6 +61,24 @@
    },
    {
      type: 'radio',
      field: 'cardRole',
      label: '卡片角色',
      initval: setting.cardRole || 'card',
      required: false,
      options: [
        {value: 'card', label: '属性卡'},
        {value: 'header', label: '表格头'},
      ],
      controlFields: [
        {field: 'type', values: ['card']},
        {field: 'click', values: ['card']},
        {field: 'btnControl', values: ['card']},
      ],
      del: true,
      forbid: cardType !== 'extendCard'
    },
    {
      type: 'radio',
      field: 'type',
      label: '卡片类型',
      initval: setting.type || 'simple',
src/menu/components/table/base-table/columns/editColumn/index.jsx
@@ -17,7 +17,7 @@
  picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'fieldlength', 'blacklist', 'scale', 'lenWidRadio', 'backgroundSize', 'span'],
  video: ['label', 'field', 'type', 'Align', 'Hide', 'startTime', 'Width', 'fieldlength', 'blacklist', 'aspectRatio'],
  colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'],
  custom: ['label', 'type', 'Align', 'Hide', 'Width', 'blacklist'],
  custom: ['label', 'type', 'Align', 'Width', 'blacklist'],
  action: ['label', 'type', 'Align', 'Width'],
  formula: ['label', 'type', 'Align', 'Hide', 'Width', 'prefix', 'postfix', 'eval', 'formula', 'blacklist'],
  index: ['label', 'type', 'Align', 'Width']
src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -16,7 +16,7 @@
  text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'textFormat', 'editable', 'initval', 'blacklist'],
  number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'editable', 'initval', 'sum', 'blacklist'],
  textarea: ['label', 'field', 'type', 'Align', 'Hide', 'Width', 'prefix', 'initval', 'postfix', 'blacklist'],
  custom: ['label', 'type', 'Align', 'Hide', 'Width', 'blacklist'],
  custom: ['label', 'type', 'Align', 'Width', 'blacklist'],
  colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'],
  action: ['label', 'type', 'Align', 'Width'],
  formula: ['label', 'type', 'Align', 'Hide', 'Width', 'prefix', 'postfix', 'eval', 'formula', 'blacklist'],
src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -17,7 +17,7 @@
  picture: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'blacklist', 'scale', 'lenWidRadio', 'backgroundSize', 'span'],
  video: ['label', 'field', 'type', 'Align', 'Hide', 'startTime', 'Width', 'blacklist', 'aspectRatio'],
  colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'],
  custom: ['label', 'type', 'Align', 'Hide', 'Width', 'blacklist'],
  custom: ['label', 'type', 'Align', 'Width', 'blacklist'],
  action: ['label', 'type', 'Align', 'Width'],
  formula: ['label', 'type', 'Align', 'Hide', 'Width', 'prefix', 'postfix', 'eval', 'formula', 'blacklist'],
  index: ['label', 'type', 'Align', 'Width']
src/menu/datasource/verifycard/index.jsx
@@ -4,6 +4,7 @@
import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button, Input } from 'antd'
import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined, SnippetsOutlined } from '@ant-design/icons'
import moment from 'moment'
import md5 from 'md5'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -33,6 +34,7 @@
  state = {
    columns: [],
    debugId: '',
    subColumns: [],
    activeKey: 'setting',
    loading: false,
@@ -653,7 +655,7 @@
  }
  sqlverify = (resolve, reject, change = false, testScripts) => {
    const { columns, setting, scripts, searches, defaultSearch } = this.state
    const { columns, setting, scripts, searches, defaultSearch, debugId } = this.state
    let _scripts = scripts.filter(item => item.status !== 'false')
@@ -678,6 +680,13 @@
    if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) {
      let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch, timestamp)
      let _debugId = md5(r.sql)
      if (debugId === _debugId) {
        resolve()
        return
      }
      if (r.errors) {
        notification.warning({
@@ -713,6 +722,7 @@
          if (sumParam) {
            Api.genericInterface(sumParam).then(res => {
              if (res.status) {
                this.setState({debugId: _debugId})
                resolve()
              } else {
                reject()
@@ -722,6 +732,7 @@
              }
            })
          } else {
            this.setState({debugId: _debugId})
            resolve()
          }
        } else {
src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -249,11 +249,11 @@
          className = mark.signType
        }
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={card.style}>
              <div className={'ant-mk-text line1' + className} style={{height: card.innerHeight || 'auto'}}><span className="sequence-wrap" style={_style}>{data.$Index || ''}</span></div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'text') {
        let val = ''
@@ -409,11 +409,11 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={_style} onClick={(e) => {this.openNewView(e, card)}}>
              <div className={'ant-mk-text line' + (card.height || '') + className} style={lineStyle}>{val}</div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'number') {
        let val = ''
@@ -486,11 +486,11 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={_style}>
              <div className={'ant-mk-text line' + (card.height || '') + className} style={lineStyle}>{val}</div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'icon') {
        let val = ''
@@ -528,13 +528,13 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={card.style}>
              {val ? <Tooltip title={val}>
                <MkIcon className="ant-mk-icon" style={{height: height}} type={icon}/>
              </Tooltip> : <MkIcon className="ant-mk-icon" style={{height: height}} type={icon}/>}
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'slider') {
        let val = 0
@@ -558,11 +558,11 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={card.style}>
              <MkProgress value={val} config={card} color={color}/>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'picture') {
        let _imagestyle = {}
@@ -610,22 +610,22 @@
        let urls = url ? url.split(',').filter(Boolean) : ['']
        urls.forEach((u, i) => {
          contents.push(<Col key={card.uuid + i} style={_style_} span={card.width}>
          contents.push(<div className={'ant-col ant-col-' + card.width} key={card.uuid + i} style={_style_} span={card.width}>
            <div style={_style} onClick={(e) => {this.openNewView(e, card)}}>
              <MkPicture style={_imagestyle} scale={scale} url={u} urls={urls}/>
            </div>
          </Col>)
          </div>)
        })
      } else if (card.eleType === 'splitline') {
        let _borderWidth = card.borderWidth === undefined ? 1 : card.borderWidth
        _style_ = _style_ || {}
        _style_.minHeight = _borderWidth
        contents.push(
          <Col key={card.uuid} span={card.width} style={_style_}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} span={card.width} style={_style_}>
            <div style={card.style}>
              <div className="ant-mk-splitline" style={{borderColor: card.color, borderWidth: _borderWidth}}></div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'barcode') {
        let val = ''
@@ -641,13 +641,13 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={card.style}>
              <div style={{height: card.innerHeight || 25}}>
                {val ? <BarCode card={card} value={val}/> : null}
              </div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'video') {
        let url = ''
@@ -674,11 +674,11 @@
  
        urls.forEach((u, i) => {
          contents.push(
            <Col key={card.uuid + i} style={_style_} span={card.width}>
            <div className={'ant-col ant-col-' + card.width} key={card.uuid + i} style={_style_} span={card.width}>
              <div className="video-wrap" style={card.style}>
                <Video card={card} poster={poster} value={u}/>
              </div>
            </Col>
            </div>
          )
        })
      } else if (card.eleType === 'qrcode') {
@@ -695,13 +695,13 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={card.style}>
              <div style={{minHeight: card.qrWidth || 50}}>
                {val ? <QrCode card={card} value={val}/> : null}
              </div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'currentDate') {
        let val = moment().format(card.dateFormat || 'YYYY-MM-DD')
@@ -714,11 +714,11 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={card.style}>
              <div className="ant-mk-text line1" style={{height: card.innerHeight || 'auto'}}>{val}</div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'formula') {
        let val = 0
@@ -812,11 +812,11 @@
        }
  
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div style={_style}>
              <div className={'ant-mk-text line' + (card.height || '') + className} style={lineStyle}>{val}</div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'color') {
        let color = ''
@@ -844,7 +844,7 @@
        }
        contents.push(
          <Col key={card.uuid} style={_style_} span={card.width}>
          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
            <div className="ant-mk-color" style={card.style}>
              <div style={_bgstyle} onClick={(e) => {
                if (card.copyable === 'true') {
@@ -861,7 +861,7 @@
                }
              }}></div>
            </div>
          </Col>
          </div>
        )
      } else if (card.eleType === 'button') {
        let _disabled = data.$disabled
@@ -882,7 +882,7 @@
  
        if (['exec', 'prompt', 'pop', 'form'].includes(card.OpenType)) {
          contents.push(
            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <NormalButton
                btn={card}
                BID={data.$$BID}
@@ -892,11 +892,11 @@
                columns={cards.columns}
                selectedData={_data}
              />
            </Col>
            </div>
          )
        } else if (card.OpenType === 'excelIn') {
          contents.push(
            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <ExcelInButton
                btn={card}
                BID={data.$$BID}
@@ -905,11 +905,11 @@
                setting={cards.setting}
                selectedData={_data}
              />
            </Col>
            </div>
          )
        } else if (card.OpenType === 'excelOut') {
          contents.push(
            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <ExcelOutButton
                btn={card}
                BID={data.$$BID}
@@ -918,11 +918,11 @@
                setting={cards.setting}
                selectedData={_data}
              />
            </Col>
            </div>
          )
        } else if (card.OpenType === 'popview') {
          contents.push(
            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <PopupButton
                btn={card}
                BID={data.$$BID}
@@ -931,11 +931,11 @@
                setting={cards.setting}
                selectedData={_data}
              />
            </Col>
            </div>
          )
        } else if (card.OpenType === 'tab') {
          contents.push(
            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <TabButton
                btn={card}
                BID={data.$$BID}
@@ -943,23 +943,23 @@
                disabled={_disabled}
                selectedData={_data}
              />
            </Col>
            </div>
          )
        } else if (card.OpenType === 'innerpage') {
          contents.push(
            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <NewPageButton
                btn={card}
                BData={data.$$BData || ''}
                disabled={_disabled}
                selectedData={_data}
              />
            </Col>
            </div>
          )
        } else if (card.OpenType === 'funcbutton') {
          if (card.funcType === 'changeuser' || card.funcType === 'closetab') {
            contents.push(
              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <ChangeUserButton
                  btn={card}
                  BID={data.$$BID}
@@ -968,11 +968,11 @@
                  setting={cards.setting}
                  selectedData={_data}
                />
              </Col>
              </div>
            )
          } else if (card.funcType === 'print') {
            contents.push(
              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <PrintButton
                  btn={card}
                  BID={data.$$BID}
@@ -982,11 +982,11 @@
                  columns={cards.columns}
                  selectedData={_data}
                />
              </Col>
              </div>
            )
          } else if (card.funcType === 'megvii') {
            contents.push(
              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <FuncMegvii
                  btn={card}
                  BID={data.$$BID}
@@ -994,11 +994,11 @@
                  setting={cards.setting}
                  selectedData={_data}
                />
              </Col>
              </div>
            )
          } else if (card.funcType === 'filezip') {
            contents.push(
              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <FuncZip
                  btn={card}
                  BID={data.$$BID}
@@ -1006,7 +1006,7 @@
                  setting={cards.setting}
                  selectedData={_data}
                />
              </Col>
              </div>
            )
          }
        }
@@ -1022,6 +1022,7 @@
    return (
      <div className={'card-cell-list ' + (cardCell && cardCell.setting && cardCell.setting.layout === 'flex' ? 'mk-flex' : '')}>
        {this.getContent()}
        <Col style={{display: 'none'}} span={24}></Col>
      </div>
    )
  }
src/tabviews/custom/components/card/data-card/index.jsx
@@ -15,6 +15,7 @@
import './index.scss'
const CardItem = asyncComponent(() => import('../cardItem'))
const TableHeader = asyncComponent(() => import('../tableHeader'))
const MainAction = asyncComponent(() => import('@/tabviews/zshare/actionList'))
const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader'))
@@ -32,6 +33,7 @@
    search: null,              // 搜索条件
    pageIndex: 1,              // 页码
    pageSize: 10,
    orderBy: '',
    pageOptions: [],
    activeKey: '',             // 选中卡
    selectKeys: [],            // 多选时选中卡片
@@ -578,7 +580,7 @@
   */
  queryModuleParam = (menuId, callback) => {
    const { mainSearch } = this.props
    const { arr_field, config, search } = this.state
    const { arr_field, config, search, orderBy } = this.state
    if (config.uuid !== menuId) return
@@ -594,7 +596,7 @@
    callback({
      arr_field: arr_field,
      orderBy: config.setting.order || '',
      orderBy: orderBy ||config.setting.order || '',
      search: searches,
      menuName: config.name
    })
@@ -602,7 +604,7 @@
  async loadData (id, type) {
    const { mainSearch } = this.props
    const { config, arr_field, pageIndex, pageSize, search, BID, BData, selected } = this.state
    const { config, arr_field, pageIndex, pageSize, search, BID, BData, selected, orderBy } = this.state
    if (config.setting.supModule && !BID && config.wrap.supKey !== 'false') { // BID 不存在时,不做查询
      this.loaded = true
@@ -654,7 +656,7 @@
      })
    }
    let _orderBy = config.setting.order || ''
    let _orderBy = orderBy || config.setting.order || ''
    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID)
    let result = await Api.genericInterface(param)
@@ -757,7 +759,7 @@
   */ 
  async loadLinedata (id) {
    const { mainSearch } = this.props
    const { config, arr_field, pageIndex, pageSize, search, BID, BData } = this.state
    const { config, arr_field, pageIndex, pageSize, search, BID, BData, orderBy } = this.state
    let searches = fromJS(search).toJS()
    if (config.setting.useMSearch && mainSearch && mainSearch.length > 0) { // 主表搜索条件
@@ -773,7 +775,7 @@
      loading: true
    })
    let _orderBy = config.setting.order || ''
    let _orderBy = orderBy || config.setting.order || ''
    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, id)
    let result = await Api.genericInterface(param)
@@ -928,6 +930,14 @@
    }
  }
  refreshByHeader = (sorter) => {
    this.setState({
      orderBy: sorter || ''
    }, () => {
      this.loadData()
    })
  }
  render() {
    const { config, precards, nextcards, loading, data, pageIndex, pageSize, total, card, activeKey, BID, BData, selectedData, selectKeys } = this.state
@@ -977,9 +987,11 @@
          <Row className={'card-row-list ' + config.wrap.layout}>
            {precards.map((item, index) => (
              <Col key={'pre' + index} className="extend-card" span={item.setting.width || 6}>
                <CardItem card={item} cards={config} data={extendData}>
                {item.setting.cardRole === 'header' ? <TableHeader card={item} data={extendData} refresh={this.refreshByHeader}>
                  {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                </CardItem>
                </TableHeader> : <CardItem card={item} cards={config} data={extendData}>
                  {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                </CardItem>}
              </Col>
            ))}
            {data && data.map((item, index) => {
@@ -1007,9 +1019,11 @@
            })}
            {nextcards.map((item, index) => (
              <Col key={'next' + index} className="extend-card" span={item.setting.width || 6}>
                <CardItem card={item} cards={config} data={extendData}>
                {item.setting.cardRole === 'header' ? <TableHeader card={item} data={extendData} refresh={this.refreshByHeader}>
                  {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                </CardItem>
                </TableHeader> : <CardItem card={item} cards={config} data={extendData}>
                  {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                </CardItem>}
              </Col>
            ))}
          </Row>
src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -13,6 +13,7 @@
import './index.scss'
const CardItem = asyncComponent(() => import('../cardItem'))
const TableHeader = asyncComponent(() => import('../tableHeader'))
const MainAction = asyncComponent(() => import('@/tabviews/zshare/actionList'))
const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader'))
@@ -29,6 +30,7 @@
    search: null,              // 搜索条件
    pageIndex: 1,              // 页码
    pageSize: 10,
    orderBy: '',
    pageOptions: [],
    activeKey: '',             // 选中卡
    selectKeys: [],            // 多选时选中卡片
@@ -445,7 +447,7 @@
   */
  queryModuleParam = (menuId, callback) => {
    const { mainSearch } = this.props
    const { arr_field, config, search } = this.state
    const { arr_field, config, search, orderBy } = this.state
    if (config.uuid !== menuId) return
@@ -461,7 +463,7 @@
    callback({
      arr_field: arr_field,
      orderBy: config.setting.order || '',
      orderBy: orderBy || config.setting.order || '',
      search: searches,
      menuName: config.name
    })
@@ -469,7 +471,7 @@
  async loadData (id, type) {
    const { mainSearch } = this.props
    const { config, arr_field, pageIndex, pageSize, search, BID, BData, selected, card } = this.state
    const { config, arr_field, pageIndex, pageSize, search, BID, BData, selected, card, orderBy } = this.state
    if (config.setting.supModule && !BID && config.wrap.supKey !== 'false') { // BID 不存在时,不做查询
      this.loaded = true
@@ -519,7 +521,7 @@
      })
    }
    let _orderBy = config.setting.order || ''
    let _orderBy = orderBy || config.setting.order || ''
    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID)
    let result = await Api.genericInterface(param)
@@ -674,7 +676,7 @@
   */ 
  async loadLinedata (id) {
    const { mainSearch } = this.props
    const { config, arr_field, pageIndex, pageSize, search, BID, BData } = this.state
    const { config, arr_field, pageIndex, pageSize, search, BID, BData, orderBy } = this.state
    let searches = fromJS(search).toJS()
    if (config.setting.useMSearch && mainSearch && mainSearch.length > 0) { // 主表搜索条件
@@ -690,7 +692,7 @@
      loading: true
    })
    let _orderBy = config.setting.order || ''
    let _orderBy = orderBy || config.setting.order || ''
    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, id)
    let result = await Api.genericInterface(param)
@@ -874,6 +876,14 @@
    }
  }
  refreshByHeader = (sorter) => {
    this.setState({
      orderBy: sorter || ''
    }, () => {
      this.loadData()
    })
  }
  render() {
    const { config, precards, nextcards, loading, data, pageIndex, pageSize, total, card, activeKey, BID, BData, selectedData, selectKeys, subcard, subconfig, wrapStyle, opens } = this.state
@@ -922,9 +932,11 @@
            <Row className={'card-row-list '}>
              {precards.map((item, index) => (
                <Col key={'pre' + index} className="extend-card" span={item.setting.width || 6}>
                  <CardItem card={item} cards={config} data={extendData}>
                  {item.setting.cardRole === 'header' ? <TableHeader card={item} data={extendData} refresh={this.refreshByHeader}>
                    {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                  </CardItem>
                  </TableHeader> : <CardItem card={item} cards={config} data={extendData}>
                    {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                  </CardItem>}
                </Col>
              ))}
              {data && data.map((item, index) => {
@@ -969,9 +981,11 @@
              })}
              {nextcards.map((item, index) => (
                <Col key={'next' + index} className="extend-card" span={item.setting.width || 6}>
                  <CardItem card={item} cards={config} data={extendData}>
                  {item.setting.cardRole === 'header' ? <TableHeader card={item} data={extendData} refresh={this.refreshByHeader}>
                    {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                  </CardItem>
                  </TableHeader> : <CardItem card={item} cards={config} data={extendData}>
                    {item.setting.checkAll === 'show' ? <span onClick={this.checkAll} className={'circle-select' + checkAll}></span> : null}
                  </CardItem>}
                </Col>
              ))}
            </Row>
src/tabviews/custom/components/card/tableHeader/index.jsx
New file
@@ -0,0 +1,160 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons'
import './index.scss'
class TableHeader extends Component {
  static propTpyes = {
    card: PropTypes.object,     // 卡片配置信息
    data: PropTypes.object,
    refresh: PropTypes.func
  }
  state = {
    sortField: '',
    order: ''
  }
  /**
   * @description 搜索条件初始化
   */
  UNSAFE_componentWillMount () {
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState)) || !is(fromJS(this.props), fromJS(nextProps))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  triggerHeader = (item) => {
    const { sortField, order } = this.state
    if (!item.sortField) return
    if (item.sortField !== sortField) {
      this.setState({sortField: item.sortField, order: 'asc'})
      this.props.refresh(item.sortField + ' asc')
    } else {
      if (order === 'asc') {
        this.setState({order: 'desc'})
        this.props.refresh(item.sortField + ' desc')
      } else if (order === 'desc') {
        this.setState({sortField: '', order: ''})
        this.props.refresh('')
      }
    }
  }
  getContent = () => {
    const { data, card } = this.props
    const { sortField, order } = this.state
    let contents = []
    card.elements.forEach(item => {
      if (item.eleType !== 'text') return
      let _style_ = null
      if (item.style && item.style.clear === 'left') {
        _style_ = {clear: 'left'}
      }
      let val = ''
      let _style = item.style ? {...item.style} : {}
      if (item.datatype === 'static') {
        val = item.value || ''
        if (/@username@|@fullName@|@mk_city@|@bid@/ig.test(val)) {
          let userName = sessionStorage.getItem('User_Name') || ''
          let fullName = sessionStorage.getItem('Full_Name') || ''
          let city = sessionStorage.getItem('city') || ''
          let bid = data.$$BID || ''
          val = val.replace(/@username@/ig, userName).replace(/@fullName@/ig, fullName).replace(/@mk_city@/ig, city).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(item.field)) {
        val = data[item.field]
      }
      if (val === '' && item.noValue === 'hide') { // 空值隐藏
        return null
      }
      if (val !== '') {
        if (item.sortField) {
          val = <>
            <span className="mk-content">{item.prefix || ''}{val}{item.postfix || ''}</span>
            <span className="sort-wrap"><CaretUpOutlined /><CaretDownOutlined /></span>
          </>
        } else {
          val = <span>{item.prefix || ''}{val}{item.postfix || ''}</span>
        }
      }
      let lineStyle = {height: item.innerHeight || 'auto', display: 'flex', alignItems: 'center', justifyContent: _style.textAlign || 'left'}
      let extra = ''
      if (item.sortField) {
        extra = ' sortable'
        if (item.sortField === sortField) {
          if (order === 'asc') {
            extra += ' up-sort'
          } else {
            extra += ' down-sort'
          }
        }
      }
      contents.push(
        <div className={'ant-col ant-col-' + item.width + extra} onClick={() => this.triggerHeader(item)} key={item.uuid} style={_style_} span={item.width}>
          <div style={_style}>
            <div className={'ant-mk-text mk-header-cell line' + (item.height || '')} style={lineStyle}>{val}</div>
          </div>
        </div>
      )
    })
    return contents
  }
  render() {
    const { card, children } = this.props
    return (
      <div className={'card-item-box mk-table-header'} style={card.style}>
        {children}
        <div className={'card-cell-list ' + (card.setting.layout === 'flex' ? 'mk-flex' : '')}>
          {this.getContent()}
        </div>
      </div>
    )
  }
}
export default TableHeader
src/tabviews/custom/components/card/tableHeader/index.scss
New file
@@ -0,0 +1,45 @@
.card-item-box.mk-table-header {
  position: relative;
  overflow: hidden;
  .mk-content {
    display: inline-block;
    white-space: normal;
    max-width: calc(100% - 20px);
  }
  .sort-wrap {
    position: relative;
    margin-left: 10px;
    font-size: 12px;
    color: #bfbfbf;
    display: inline-block;
    .anticon-caret-up {
      position: relative;
      top: -3px;
    }
    .anticon-caret-down {
      position: absolute;
      top: 7px;
      left: 0px;
    }
  }
  .sortable {
    cursor: pointer;
  }
  .sortable.up-sort {
    .anticon-caret-up {
      color: var(--mk-sys-color);
    }
  }
  .sortable.down-sort {
    .anticon-caret-down {
      color: var(--mk-sys-color);
    }
  }
  .sortable:hover {
    .mk-content {
      color: var(--mk-sys-color);
    }
  }
}
src/tabviews/custom/index.jsx
@@ -1384,9 +1384,9 @@
    const { loadingview, viewlost, config, loading, shortcuts, BID } = this.state
    return (
      <div className={'custom-page-wrap ' + (loadingview || loading ? 'loading' : '')} id={this.state.ContainerId} style={config ? config.style : null}>
      <div className={`custom-page-wrap ${config && config.minWidth ? 'mk-scroll' : ''} ${loadingview || loading ? 'loading' : ''}`} id={this.state.ContainerId} style={config ? config.style : null}>
        {(loadingview || (loading && !config.$cache)) ? <Spin className="view-spin" size="large" /> : null}
        <Row id={config ? 'menu' + config.uuid : ''} className="component-wrap">{this.getComponents()}</Row>
        <Row id={config ? 'menu' + config.uuid : ''} style={config && config.minWidth ? {minWidth: config.minWidth} : null} className="component-wrap">{this.getComponents()}</Row>
        {config && config.interfaces.length > 0 ? <MkInterfaces BID={BID} interfaces={config.interfaces}/> : null}
        {config && window.GLOB.breakpoint ? <DebugTable /> : null}
        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <TableNodes config={config} /> : null}
src/tabviews/custom/index.scss
@@ -49,3 +49,8 @@
    display: none;
  }
}
.custom-page-wrap.mk-scroll {
  height: calc(100vh - 93px);
  overflow: auto;
  margin: 0!important;
}
src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -713,6 +713,21 @@
          })
        }
        if (btn.verify.wrapText === 'true' && data) {
          let lines = data.length + 1
          let start = 2
          if (btn.verify.merge === 'true') {
            lines = data.length + 2
          }
          for (let n = 0; n < cols.length; n++) {
            for (let m = start; m <= lines; m++) {
              if (ws[cols[n] + m] && !ws[cols[n] + m].s) {
                ws[cols[n] + m].s = {alignment: { wrapText: true }}
              }
            }
          }
        }
        // ws["A1"].s = {fill: { bgColor: { rgb: "FFFFAA"  }}, font: { color: { rgb: "1890FF" } }}
        const wb = XLSX.utils.book_new()
src/templates/sharecomponent/actioncomponent/verifyexcelout/datasource/index.jsx
@@ -282,6 +282,22 @@
                </Radio.Group>)}
              </Form.Item>
            </Col> : null}
            {btnType !== 'print' ? <Col span={8}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="Excel内容区是否自动换行。">
                  <QuestionCircleOutlined className="mk-form-tip" />
                  自动换行
                </Tooltip>
              }>
                {getFieldDecorator('wrapText', {
                  initialValue: setting.wrapText || 'false'
                })(
                <Radio.Group>
                  <Radio value="false">否</Radio>
                  <Radio value="true">是</Radio>
                </Radio.Group>)}
              </Form.Item>
            </Col> : null}
          </Row>
        </Form>
      </div>
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -4,6 +4,7 @@
import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Radio, Spin, Typography, Popconfirm } from 'antd'
import { EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
import moment from 'moment'
import md5 from 'md5'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -28,6 +29,7 @@
  state = {
    verify: {},
    debugId: '',
    activeKey: 'setting',
    defaultscript: '', // 自定义脚本
    excelColumns: [
@@ -995,7 +997,7 @@
  }
  sqlverify = (_resolve, _reject, scripts) => {
    const { searches, verify } = this.state
    const { searches, verify, debugId } = this.state
    if (verify.dataType !== 'custom') {
      _resolve()
@@ -1004,6 +1006,14 @@
    let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    let sql = SettingUtils.getDebugSql(verify, scripts, (verify.useSearch === 'true' ? searches : []), Utils, timestamp)
    let _debugId = md5(sql)
    if (debugId === _debugId) {
      _resolve()
      return
    }
    let param = {
      func: 's_debug_sql',
      exec_type: 'y',
@@ -1015,6 +1025,7 @@
    Api.genericInterface(param).then(result => {
      if (result.status) {
        this.setState({debugId: _debugId})
        _resolve()
      } else {
        _reject()
src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -4,6 +4,7 @@
import { Form, Tabs, Row, Col, Button, notification, Modal, message, InputNumber, Input, Select, Radio, Tooltip, Typography, Popconfirm, Spin } from 'antd'
import { QuestionCircleOutlined, EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
import moment from 'moment'
import md5 from 'md5'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -33,6 +34,7 @@
  state = {
    verify: {},
    debugId: '',
    templates: [],
    loading: false,
    activeKey: 'base',
@@ -611,10 +613,18 @@
  }
  sqlverify = (_resolve, _reject, scripts) => {
    const { verify, declareSql } = this.state
    const { verify, declareSql, debugId } = this.state
    let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    let sql = SettingUtils.getDebugSql(verify.setting || {}, verify.columns, scripts, declareSql, timestamp)
    let _debugId = md5(sql)
    if (debugId === _debugId) {
      _resolve()
      return
    }
    let param = {
      func: 's_debug_sql',
      exec_type: 'y',
@@ -626,6 +636,7 @@
    Api.genericInterface(param).then(result => {
      if (result.status) {
        this.setState({debugId: _debugId})
        _resolve()
      } else {
        _reject()
src/templates/sharecomponent/fieldscomponent/editcard/index.jsx
@@ -18,7 +18,9 @@
          _type = 'text'
        }
      } else if (props.type === 'search') {
        if (_type !== 'select') {
        if (_type === 'date' || _type === 'datetime') {
          _type = 'date'
        } else if (_type !== 'select') {
          _type = 'text'
        }
      } else if (props.type === 'form') {
@@ -83,6 +85,7 @@
          <Radio.Group onChange={this.changeType} value={card.type} disabled={!card.selected || card.origin}>
            <Radio value="text">text</Radio>
            <Radio value="select">select</Radio>
            <Radio value="date">date</Radio>
          </Radio.Group> : null
        }
        {type === 'columns' ?
src/templates/sharecomponent/fieldscomponent/index.jsx
@@ -106,10 +106,13 @@
      selectCards.forEach(item => {
        let _match = ''
        let initval = ''
        if (item.type === 'select') {
        let _type = item.type
        if (item.type === 'date') {
          _type = 'daterange'
        } else if (item.type === 'select') {
          _match = '='
        } else {
          item.type = 'text'
          _type = 'text'
          _match = 'like'
        }
@@ -118,7 +121,7 @@
          label: item.label,
          field: item.field,
          initval: initval,
          type: item.type,
          type: _type,
          resourceType: '0',
          options: [],
          orderType: 'asc',
src/views/menudesign/menuform/index.jsx
@@ -193,47 +193,14 @@
        this.props.form.setFieldsValue({parentId: _id})
        this.props.updateConfig({...config, fstMenuId: value, parentId: _id})
      })
    } else if (key === 'parentId') {
      this.props.updateConfig({...config, parentId: value})
    } else if (key === 'cacheUseful') {
      this.props.updateConfig({...config, cacheUseful: value})
    } else if (key === 'timeUnit') {
      this.props.updateConfig({...config, timeUnit: value})
    } else if (key === 'OpenType') {
      this.props.updateConfig({...config, OpenType: value})
    } else if (key === 'hidden') {
      this.props.updateConfig({...config, hidden: value})
    } else if (key === 'permission') {
      this.props.updateConfig({...config, permission: value})
    } else if (key === 'cacheLocal') {
      this.props.updateConfig({...config, cacheLocal: value})
    } else {
      if (key === 'cacheTime' || key === 'minWidth') {
        if (typeof(value) !== 'number') {
          value = ''
        }
      }
      this.props.updateConfig({...config, [key]: value})
    }
  }
  // 菜单名称
  changeName = (e) => {
    this.props.updateConfig({...this.props.config, MenuName: e.target.value})
  }
  // 菜单参数
  changeNo = (e) => {
    this.props.updateConfig({...this.props.config, MenuNo: e.target.value})
  }
  // 助记码
  changeEasyCode = (e) => {
    this.props.updateConfig({...this.props.config, easyCode: e.target.value})
  }
  changeRemark = (e) => {
    this.props.updateConfig({...this.props.config, Remark: e.target.value})
  }
  changeCacheDay = (val) => {
    if (typeof(val) !== 'number') {
      val = ''
    }
    this.props.updateConfig({...this.props.config, cacheTime: val})
  }
  render() {
@@ -306,7 +273,7 @@
                    message: '请输入菜单名称!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onChange={this.changeName}/>)}
              })(<Input placeholder="" autoComplete="off" onChange={(e) => {this.selectChange('MenuName', e.target.value)}}/>)}
            </Form.Item>
          </Col>
          <Col span={24}>
@@ -319,7 +286,7 @@
                    message: '请输入菜单参数!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onChange={this.changeNo}/>)}
              })(<Input placeholder="" autoComplete="off" onChange={(e) => {this.selectChange('MenuNo', e.target.value)}}/>)}
            </Form.Item>
          </Col>
          <Col span={24}>
@@ -336,6 +303,23 @@
                <Radio.Group onChange={(e) => {this.selectChange('OpenType', e.target.value)}}>
                  <Radio value="newtab">标签页</Radio>
                  <Radio value="newpage">新页面</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          <Col span={24}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="跳过权限验证时,页面中组件及按钮不在进行权限控制。">
                <QuestionCircleOutlined className="mk-form-tip" />
                权限验证
              </Tooltip>
            }>
              {getFieldDecorator('permission', {
                initialValue: config.permission || 'true'
              })(
                <Radio.Group onChange={(e) => {this.selectChange('permission', e.target.value)}}>
                  <Radio value="true">使用</Radio>
                  <Radio value="false">不使用</Radio>
                </Radio.Group>
              )}
            </Form.Item>
@@ -374,23 +358,6 @@
              )}
            </Form.Item>
          </Col>
          <Col span={24}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="跳过权限验证时,页面中组件及按钮不在进行权限控制。">
                <QuestionCircleOutlined className="mk-form-tip" />
                权限验证
              </Tooltip>
            }>
              {getFieldDecorator('permission', {
                initialValue: config.permission || 'true'
              })(
                <Radio.Group onChange={(e) => {this.selectChange('permission', e.target.value)}}>
                  <Radio value="true">使用</Radio>
                  <Radio value="false">不使用</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          {config.cacheUseful === 'true' ? <Col span={24}>
            <Form.Item label="单位">
              {getFieldDecorator('timeUnit', {
@@ -414,15 +381,29 @@
                  }
                ]
              })(
                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/>
                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={(val) => {this.selectChange('cacheTime', val)}}/>
              )}
            </Form.Item>
          </Col> : null}
          <Col span={24}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="如果页面内容在窗口中无法完全展示,可设置最小宽度,实现页面的横向滚动。">
                <QuestionCircleOutlined className="mk-form-tip" />
                最小宽度
              </Tooltip>
            }>
              {getFieldDecorator('minWidth', {
                initialValue: config.minWidth
              })(
                <InputNumber min={0} precision={0} onChange={(val) => {this.selectChange('minWidth', val)}}/>
              )}
            </Form.Item>
          </Col>
          <Col span={24}>
            <Form.Item label="助记码">
              {getFieldDecorator('easyCode', {
                initialValue: config.easyCode
              })(<Input placeholder="" autoComplete="off" onChange={this.changeEasyCode}/>)}
              })(<Input placeholder="" autoComplete="off" onChange={(e) => {this.selectChange('easyCode', e.target.value)}}/>)}
            </Form.Item>
          </Col>
          <Col span={24}>
@@ -442,7 +423,7 @@
                    message: '备注最多512个字符!'
                  }
                ]
              })(<TextArea rows={2} placeholder={''} onChange={this.changeRemark} />)}
              })(<TextArea rows={2} placeholder={''} onChange={(e) => {this.selectChange('Remark', e.target.value)}}/>)}
            </Form.Item>
          </Col>
        </Row>