king
2023-12-12 49f09cc6f8ff8c30a75ed1a9d6f510b69b73962a
2023-12-12
13个文件已修改
953 ■■■■■ 已修改文件
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/versions/index.jsx 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/versions/index.scss 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.jsx 284 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-pie/index.jsx 232 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartcomponent/chartcompile/formconfig.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -497,22 +497,6 @@
      }]
    }, {
      type: 'radio',
      field: 'repeat',
      label: '重复数据',
      initval: card.repeat || 'unrepeat',
      required: false,
      options: [{
        value: 'unrepeat',
        label: '去重'
      }, {
        value: 'average',
        label: '平均'
      }, {
        value: 'cumsum',
        label: '累加'
      }]
    }, {
      type: 'radio',
      field: 'coordinate',
      label: '坐标',
      initval: card.coordinate || 'angle',
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -292,22 +292,6 @@
      }],
    }, {
      type: 'radio',
      key: 'repeat',
      label: '重复数据',
      initVal: card.repeat || 'unrepeat',
      required: false,
      options: [{
        value: 'unrepeat',
        text: '去重'
      }, {
        value: 'average',
        text: '平均'
      }, {
        value: 'cumsum',
        text: '累加'
      }]
    }, {
      type: 'radio',
      key: 'download',
      label: '导出图片',
      initVal: card.download || 'forbid',
src/menu/versions/index.jsx
@@ -1,8 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Button, notification } from 'antd'
import { QuestionCircleOutlined, CalendarOutlined } from '@ant-design/icons'
import { Modal, Button, notification, Table, Spin } from 'antd'
import { CalendarOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
@@ -12,16 +12,30 @@
class Versions extends Component {
  static propTpyes = {
    MenuId: PropTypes.string,
    open_edition: PropTypes.string,
    Template: PropTypes.string,
    checklog: PropTypes.func,
    updateConfig: PropTypes.func
  }
  state = {
    visible: false,
    loadingTable: false,
    preconfirming: false,
    nextconfirming: false,
    tables: [],
    loading: false,
    logs: [],
    columns: [
      { title: '修改时间', dataIndex: 'createdate', key: 'createdate', align: 'center' },
      { title: '修改人', dataIndex: 'fullname', key: 'fullname', align: 'center' },
      {
        title: '操作',
        key: 'action',
        align: 'center',
        width: '230px',
        render: (text, record) => (
          <div>
            <Button type="link" onClick={() => this.change(record)} style={{color: '#1890ff'}}>切换</Button>
          </div>
        ),
      },
    ]
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -29,124 +43,162 @@
  }
  trigger = () => {
    this.setState({visible: true})
  }
  preVersion = () => {
    const { MenuId, open_edition, updateConfig } = this.props
    let param = {
      func: 's_spages_Param_ctrlzy',
      ctrlzy: 'z',
      MenuID: MenuId,
      func: 's_get_spages_param_log',
      MenuID: this.props.MenuId,
      TypeCharOne: sessionStorage.getItem('kei_no') || '',
      TypeName: sessionStorage.getItem('typename') || '',
      lang: sessionStorage.getItem('lang'),
      timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
      open_edition: open_edition,
      LText: MenuId + window.GLOB.appkey
      LText: this.props.MenuId + window.GLOB.appkey
    }
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    this.setState({preconfirming: true})
    this.setState({loading: true, visible: true, logs: []})
    Api.getCloudConfig(param).then(res => {
      this.setState({preconfirming: false})
      this.setState({loading: false})
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else {
        this.setState({visible: false})
        notification.success({
          top: 92,
          message: '执行成功。',
          duration: 1
        return
      } else if (!res.data || res.data.length === 0) {
        Modal.warning({
          title: '当前菜单无历史版本。',
          okText: '知道了'
        })
        if (updateConfig) {
          updateConfig()
        } else {
          setTimeout(() => {
            window.location.reload()
          }, 1000)
        }
        return
      }
      this.setState({logs: res.data})
    })
  }
  nextVersion = () => {
    const { MenuId, open_edition, updateConfig } = this.props
  change = (record) => {
    const { checklog } = this.props
    if (checklog()) {
      this.getpage(record)
    } else {
      const that = this
      Modal.confirm({
        title: '当前配置未保存,确定切换吗?',
        onOk: () => {
          that.getpage(record)
        },
        onCancel() {}
      })
    }
  }
  getpage = (record) => {
    const { Template } = this.props
    let param = {
      func: 's_spages_Param_ctrlzy',
      ctrlzy: 'y',
      MenuID: MenuId,
      func: 'sPC_Get_LongParam_page_id',
      id: record.id,
      TypeCharOne: sessionStorage.getItem('kei_no') || '',
      TypeName: sessionStorage.getItem('typename') || '',
      lang: sessionStorage.getItem('lang'),
      timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
      open_edition: open_edition,
      LText: MenuId + window.GLOB.appkey
    }
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    this.setState({nextconfirming: true})
    this.setState({loading: true})
    Api.getCloudConfig(param).then(res => {
      this.setState({nextconfirming: false})
      this.setState({loading: false})
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      } else {
        this.setState({visible: false})
        notification.success({
      } else if (!res.LongParam) {
        notification.warning({
          top: 92,
          message: '执行成功。',
          duration: 1
          message: '未获取到配置信息!',
          duration: 5
        })
        if (updateConfig) {
          updateConfig()
      } else {
        let config = null
        try {
          config = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
        } catch (e) {
          console.warn('Parse Failure')
          config = null
        }
        if (!config) {
          notification.warning({
            top: 92,
            message: '配置信息解析失败!',
            duration: 5
          })
        } else {
          setTimeout(() => {
            window.location.reload()
          }, 1000)
          if (Template !== config.Template) {
            notification.warning({
              top: 92,
              message: '菜单模板不一致,不可切换!',
              duration: 5
            })
          } else if (config.Template === 'CustomPage' && config.version !== 2.0) {
            notification.warning({
              top: 92,
              message: '历史配置版本过低,不可切换!',
              duration: 5
            })
          } else {
            this.setState({visible: false}, () => {
              this.props.updateConfig(config)
            })
            notification.success({
              top: 92,
              message: '版本切换成功,保存后生效!',
              duration: 5
            })
          }
        }
      }
    })
  }
  render() {
    const { visible, preconfirming, nextconfirming } = this.state
    const { visible, loading, logs, columns } = this.state
    return (
      <>
        <Button style={{borderColor: '#40a9ff', color: '#40a9ff'}} onClick={this.trigger}><CalendarOutlined /> 版本管理</Button>
        <Modal
          title=""
          title="版本管理"
          wrapClassName="version-modal"
          visible={visible}
          width={500}
          closable={false}
          width={800}
          maskClosable={false}
          footer={[]}
          onCancel={() => { this.setState({ visible: false, logs: [] }) }}
          footer={[
            <Button key="cancel" onClick={() => this.setState({ visible: false, logs: [] })}>关闭</Button>
          ]}
          destroyOnClose
        >
          <div className="header"><QuestionCircleOutlined/>版本切换</div>
          <div className="detail">请选择需要切换的版本,或点击取消关闭弹窗。</div>
          <div className="footer">
            <Button key="pre" type="primary" loading={preconfirming} onClick={this.preVersion}>上一版本</Button>
            <Button key="next" type="primary" loading={nextconfirming} onClick={this.nextVersion}>下一版本</Button>
            <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>取消</Button>
          </div>
          {loading ? <Spin size="large" /> : null}
          <Table
            rowKey="id"
            columns={columns}
            dataSource={logs}
            pagination={{
              pageSize: 10,
              total: logs.length,
              showTotal: (total, range) => `${range[0]}-${range[1]} 共 ${total} 条`
            }}
          />
        </Modal>
      </>
    )
src/menu/versions/index.scss
@@ -1,30 +1,20 @@
.version-modal {
  .ant-modal-body {
    padding: 32px 32px 24px;
  }
  .ant-modal-footer {
    display: none;
  }
  .header {
    color: rgba(0, 0, 0, 0.85);
    font-weight: 500;
    font-size: 16px;
    .anticon {
      color: #faad14;
      margin-right: 16px;
      font-size: 22px;
  .ant-modal {
    top: 50px;
    .ant-modal-body {
      position: relative;
    }
  }
  .detail {
    margin-top: 8px;
    margin-bottom: 24px;
    color: rgba(0, 0, 0, 0.5);
    font-size: 14px;
  .ant-table-tbody > tr > td {
    padding: 5px 16px;
  }
  .footer {
    text-align: right;
    .ant-btn + .ant-btn {
      margin-left: 15px;
    }
  }
  .ant-spin {
    position: absolute;
    z-index: 2;
    top: 120px;
    left: calc(50% - 16px);
  }
}
src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -689,149 +689,43 @@
    }, 100)
  }
  /**
   * @description 图表数据预处理
   * 1、通过显示列进行数据类型转换
   * 2、重复数据:取平均值、累计、去重
   * 3、柱状图数据补齐
   */
  getdata = () => {
    const { plot, vFields, config } = this.state
    if (this.data.length === 0) {
      this.setState({empty: true})
      return []
    } else {
      this.setState({empty: false})
    }
    let _data = []
    let _cdata = fromJS(this.data).toJS()
    return fromJS(this.data).toJS().map(item => {
      // dodge is not support linear attribute, please use category attribute! 时间格式
      if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
        item[plot.Xaxis] = ' ' + item[plot.Xaxis]
      } else {
        item[plot.Xaxis] = '' + item[plot.Xaxis]
      }
    if (plot.repeat === 'average') {
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (!item[plot.Xaxis] && item[plot.Xaxis] !== 0) return
        vFields.forEach(col => {
          if (typeof(item[col.field]) !== 'number') {
            item[col.field] = parseFloat(item[col.field])
            if (isNaN(item[col.field])) {
              item[col.field] = 0
            }
      vFields.forEach(col => {
        if (typeof(item[col.field]) !== 'number') {
          item[col.field] = parseFloat(item[col.field])
          if (isNaN(item[col.field])) {
            item[col.field] = 0
          }
          if (col.show === 'percent') {
            item[col.field] = item[col.field] * 100
          }
        })
        // dodge is not support linear attribute, please use category attribute! 时间格式
        if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
          item[plot.Xaxis] = ' ' + item[plot.Xaxis]
        } else {
          item[plot.Xaxis] = '' + item[plot.Xaxis]
        }
        if (col.show === 'percent') {
          item[col.field] = item[col.field] * 100
        }
        if (!_mdata.has(item[plot.Xaxis])) {
          item.$count = 1
          _mdata.set(item[plot.Xaxis], item)
        } else {
          let _item = _mdata.get(item[plot.Xaxis])
          _item.$count++
          vFields.forEach(col => {
            _item[col.field] += item[col.field]
          })
          _mdata.set(item[plot.Xaxis], _item)
        }
        item[col.field] = item[col.field].toFixed(col.decimal)
        item[col.field] = +item[col.field]
      })
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        vFields.forEach(col => {
          item[col.field] = item[col.field] / item.$count
          item[col.field] = item[col.field].toFixed(col.decimal)
          item[col.field] = +item[col.field]
        })
        item.$$uuid = item[config.setting.primaryKey] || ''
        return item
      })
    } else if (plot.repeat === 'cumsum') {
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (!item[plot.Xaxis] && item[plot.Xaxis] !== 0) return
      item.$$uuid = item[config.setting.primaryKey] || ''
        vFields.forEach(col => {
          if (typeof(item[col.field]) !== 'number') {
            item[col.field] = parseFloat(item[col.field])
            if (isNaN(item[col.field])) {
              item[col.field] = 0
            }
          }
          if (col.show === 'percent') {
            item[col.field] = item[col.field] * 100
          }
        })
        if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
          item[plot.Xaxis] = ' ' + item[plot.Xaxis]
        } else {
          item[plot.Xaxis] = '' + item[plot.Xaxis]
        }
        if (!_mdata.has(item[plot.Xaxis])) {
          _mdata.set(item[plot.Xaxis], item)
        } else {
          let _item = _mdata.get(item[plot.Xaxis])
          vFields.forEach(col => {
            _item[col.field] += item[col.field]
          })
          _mdata.set(item[plot.Xaxis], _item)
        }
      })
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        vFields.forEach(col => {
          item[col.field] = item[col.field].toFixed(col.decimal)
          item[col.field] = +item[col.field]
        })
        item.$$uuid = item[config.setting.primaryKey] || ''
        return item
      })
    } else { // plot.repeat === 'unrepeat'
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (!item[plot.Xaxis] && item[plot.Xaxis] !== 0) return
        if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
          item[plot.Xaxis] = ' ' + item[plot.Xaxis]
        } else {
          item[plot.Xaxis] = '' + item[plot.Xaxis]
        }
        if (!_mdata.has(item[plot.Xaxis])) {
          vFields.forEach(col => {
            if (typeof(item[col.field]) !== 'number') {
              item[col.field] = parseFloat(item[col.field])
              if (isNaN(item[col.field])) {
                item[col.field] = 0
              }
            }
            if (col.show === 'percent') {
              item[col.field] = item[col.field] * 100
            }
            item[col.field] = item[col.field].toFixed(col.decimal)
            item[col.field] = +item[col.field]
          })
          item.$$uuid = item[config.setting.primaryKey] || ''
          _mdata.set(item[plot.Xaxis], item)
        }
      })
      _data = [..._mdata.values()]
    }
    this.setState({empty: _data.length === 0})
    return _data
      return item
    })
  }
  /**
@@ -840,132 +734,36 @@
  getStaticMsg = () => {
    const { plot, vstFields } = this.state
    let percent = false
    let decimal = vstFields ? vstFields.decimal : 0
    if (plot.show === 'percent') {
      percent = true
    }
    if (this.data.length === 0) {
      this.setState({empty: true})
      return []
    } else {
      this.setState({empty: false})
    }
    let _data = []
    let _cdata = fromJS(this.data).toJS()
    let decimal = vstFields ? vstFields.decimal : 0
    if (plot.repeat === 'average') {
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (!item[plot.InfoType] || !item[plot.Xaxis]) return
    return fromJS(this.data).toJS().map(item => {
      if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
        item[plot.Xaxis] = ' ' + item[plot.Xaxis]
      }
        if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
          item[plot.Xaxis] = ' ' + item[plot.Xaxis]
      if (typeof(item[plot.InfoValue]) !== 'number') {
        item[plot.InfoValue] = parseFloat(item[plot.InfoValue])
        if (isNaN(item[plot.InfoValue])) {
          item[plot.InfoValue] = 0
        }
      }
        item.$uuid = item[plot.InfoType] + item[plot.Xaxis]
        if (typeof(item[plot.InfoValue]) !== 'number') {
          item[plot.InfoValue] = parseFloat(item[plot.InfoValue])
          if (isNaN(item[plot.InfoValue])) {
            item[plot.InfoValue] = 0
          }
        }
        if (percent) {
          item[plot.InfoValue] = item[plot.InfoValue] * 100
        }
      if (plot.show === 'percent') {
        item[plot.InfoValue] = item[plot.InfoValue] * 100
      }
        if (!_mdata.has(item.$uuid)) {
          item.$count = 1
          _mdata.set(item.$uuid, item)
        } else {
          let _item = _mdata.get(item.$uuid)
          _item.$count++
          _item[plot.InfoValue] += item[plot.InfoValue]
          _mdata.set(item.$uuid, _item)
        }
      })
      item[plot.InfoValue] = item[plot.InfoValue].toFixed(decimal)
      item[plot.InfoValue] = +item[plot.InfoValue]
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        item[plot.InfoValue] = item[plot.InfoValue] / item.$count
        item[plot.InfoValue] = item[plot.InfoValue].toFixed(decimal)
        item[plot.InfoValue] = +item[plot.InfoValue]
        return item
      })
    } else if (plot.repeat === 'cumsum') {
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (!item[plot.InfoType] || !item[plot.Xaxis]) return
        if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
          item[plot.Xaxis] = ' ' + item[plot.Xaxis]
        }
        item.$uuid = item[plot.InfoType] + item[plot.Xaxis]
        if (typeof(item[plot.InfoValue]) !== 'number') {
          item[plot.InfoValue] = parseFloat(item[plot.InfoValue])
          if (isNaN(item[plot.InfoValue])) {
            item[plot.InfoValue] = 0
          }
        }
        if (percent) {
          item[plot.InfoValue] = item[plot.InfoValue] * 100
        }
        if (!_mdata.has(item.$uuid)) {
          _mdata.set(item.$uuid, item)
        } else {
          let _item = _mdata.get(item.$uuid)
          _item[plot.InfoValue] += item[plot.InfoValue]
          _mdata.set(item.$uuid, _item)
        }
      })
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        item[plot.InfoValue] = item[plot.InfoValue].toFixed(decimal)
        item[plot.InfoValue] = +item[plot.InfoValue]
        return item
      })
    } else { // plot.repeat === 'unrepeat'
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (!item[plot.InfoType] || !item[plot.Xaxis]) return
        if (/^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2})?/.test(item[plot.Xaxis])) {
          item[plot.Xaxis] = ' ' + item[plot.Xaxis]
        }
        item.$uuid = item[plot.InfoType] + item[plot.Xaxis]
        if (!_mdata.has(item.$uuid)) {
          if (typeof(item[plot.InfoValue]) !== 'number') {
            item[plot.InfoValue] = parseFloat(item[plot.InfoValue])
            if (isNaN(item[plot.InfoValue])) {
              item[plot.InfoValue] = 0
            }
          }
          if (percent) {
            item[plot.InfoValue] = item[plot.InfoValue] * 100
          }
          item[plot.InfoValue] = item[plot.InfoValue].toFixed(decimal)
          item[plot.InfoValue] = +item[plot.InfoValue]
          _mdata.set(item.$uuid, item)
        }
      })
      _data = [..._mdata.values()]
    }
    this.setState({empty: _data.length === 0})
    return _data
      return item
    })
  }
  /**
src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -353,8 +353,6 @@
  /**
   * @description 图表数据预处理
   * 1、通过显示列进行数据类型转换
   * 2、重复数据:取平均值、累计、去重
   * 3、柱状图数据补齐
   */
  getdata = () => {
    const { plot } = this.state
@@ -362,91 +360,22 @@
    if (this.data.length === 0) {
      this.setState({empty: true})
      return []
    } else {
      this.setState({empty: false})
    }
    let _data = []
    let _cdata = fromJS(this.data).toJS()
    if (plot.repeat === 'average') {
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (typeof(item[plot.Yaxis]) !== 'number') {
          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
          if (isNaN(item[plot.Yaxis])) {
            return
          }
        } else if (!item[plot.Xaxis]) {
          return
    return fromJS(this.data).toJS().map(item => {
      if (typeof(item[plot.Yaxis]) !== 'number') {
        item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
        if (isNaN(item[plot.Yaxis])) {
          item[plot.Yaxis] = 0
        }
      }
        if (!_mdata.has(item[plot.Xaxis])) {
          item.$count = 1
          _mdata.set(item[plot.Xaxis], item)
        } else {
          let _item = _mdata.get(item[plot.Xaxis])
          _item.$count++
          _item[plot.Yaxis] += item[plot.Yaxis]
          _mdata.set(item[plot.Xaxis], _item)
        }
      })
      item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        item[plot.Yaxis] = item[plot.Yaxis] / item.$count
        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
        return item
      })
    } else if (plot.repeat === 'cumsum') {
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (typeof(item[plot.Yaxis]) !== 'number') {
          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
          if (isNaN(item[plot.Yaxis])) {
            return
          }
        } else if (!item[plot.Xaxis]) {
          return
        }
        if (!_mdata.has(item[plot.Xaxis])) {
          _mdata.set(item[plot.Xaxis], item)
        } else {
          let _item = _mdata.get(item[plot.Xaxis])
          _item[plot.Yaxis] += item[plot.Yaxis]
          _mdata.set(item[plot.Xaxis], _item)
        }
      })
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
        return item
      })
    } else { // plot.repeat === 'unrepeat'
      let _mdata = new Map()
      _cdata.forEach(item => {
        if (!item[plot.Xaxis] || _mdata.has(item[plot.Xaxis])) {
          return
        }
        if (typeof(item[plot.Yaxis]) !== 'number') {
          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
          if (isNaN(item[plot.Yaxis])) {
            return
          }
        }
        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
        _mdata.set(item[plot.Xaxis], item)
      })
      _data = [..._mdata.values()]
    }
    this.setState({empty: _data.length === 0})
    return _data
      return item
    })
  }
  getnestdata = () => {
@@ -458,127 +387,40 @@
    }
    let _data = []
    let _cdata = fromJS(this.data).toJS()
    if (plot.repeat === 'average') {
      let _mdata = new Map()
      let map = new Map()
      let sort = 1
      _cdata.forEach(item => {
        if (typeof(item[plot.Yaxis]) !== 'number') {
          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
          if (isNaN(item[plot.Yaxis])) {
            return
          }
        } else if (!item[plot.Xaxis] || !item[plot.type]) {
    let _mdata = new Map()
    let map = new Map()
    let sort = 1
    fromJS(this.data).toJS().forEach(item => {
      let sign = item[plot.type] + item[plot.Xaxis]
      if (!item[plot.Xaxis] || !item[plot.type] || _mdata.has(sign)) {
        return
      }
      if (typeof(item[plot.Yaxis]) !== 'number') {
        item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
        if (isNaN(item[plot.Yaxis])) {
          return
        }
      }
        item.$type = item[plot.type]
        let sign = item.$type + item[plot.Xaxis]
      item.$type = item[plot.type]
        if (!_mdata.has(sign)) {
          let _sort = sort
          if (map.has(item.$type)) {
            _sort = map.get(item.$type)
          } else {
            map.set(item.$type, _sort)
            sort++
          }
      let _sort = sort
      if (map.has(item.$type)) {
        _sort = map.get(item.$type)
      } else {
        map.set(item.$type, _sort)
        sort++
      }
          item.$count = 1
          item.$sort = _sort
          _mdata.set(sign, item)
        } else {
          let _item = _mdata.get(sign)
          _item.$count++
          _item[plot.Yaxis] += item[plot.Yaxis]
          _mdata.set(sign, _item)
        }
      })
      item.$sort = _sort
      item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        item[plot.Yaxis] = item[plot.Yaxis] / item.$count
        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
      _mdata.set(sign, true)
        return item
      })
    } else if (plot.repeat === 'cumsum') {
      let _mdata = new Map()
      let map = new Map()
      let sort = 1
      _cdata.forEach(item => {
        if (typeof(item[plot.Yaxis]) !== 'number') {
          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
          if (isNaN(item[plot.Yaxis])) {
            return
          }
        } else if (!item[plot.Xaxis] || !item[plot.type]) {
          return
        }
        item.$type = item[plot.type]
        let sign = item.$type + item[plot.Xaxis]
        if (!_mdata.has(sign)) {
          let _sort = sort
          if (map.has(item.$type)) {
            _sort = map.get(item.$type)
          } else {
            map.set(item.$type, _sort)
            sort++
          }
          item.$sort = _sort
          _mdata.set(sign, item)
        } else {
          let _item = _mdata.get(sign)
          _item[plot.Yaxis] += item[plot.Yaxis]
          _mdata.set(sign, _item)
        }
      })
      _data = [..._mdata.values()]
      _data = _data.map(item => {
        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
        return item
      })
    } else { // plot.repeat === 'unrepeat'
      let _mdata = new Map()
      let map = new Map()
      let sort = 1
      _cdata.forEach(item => {
        let sign = item[plot.type] + item[plot.Xaxis]
        if (!item[plot.Xaxis] || !item[plot.type] || _mdata.has(sign)) {
          return
        }
        if (typeof(item[plot.Yaxis]) !== 'number') {
          item[plot.Yaxis] = parseFloat(item[plot.Yaxis])
          if (isNaN(item[plot.Yaxis])) {
            return
          }
        }
        item.$type = item[plot.type]
        let _sort = sort
        if (map.has(item.$type)) {
          _sort = map.get(item.$type)
        } else {
          map.set(item.$type, _sort)
          sort++
        }
        item.$sort = _sort
        item[plot.Yaxis] = +item[plot.Yaxis].toFixed(plot.$decimal)
        _mdata.set(sign, item)
      })
      _data = [..._mdata.values()]
    }
      _data.push(item)
    })
    this.setState({empty: _data.length === 0})
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -2103,30 +2103,76 @@
    delete result.message
    delete result.status
    result.func = btn.callbackFunc
    let ssoParam = null
    let sinParam = null
    let callParam = {...outParam, ...result}
    if (callParam.LTextOut) {
      callParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      callParam.secretkey = Utils.encrypt(callParam.LTextOut, callParam.timestamp)
      callParam.open_key = Utils.encryptOpenKey(callParam.secretkey, callParam.timestamp)
    }
    callParam.func = btn.callbackFunc
    callParam.userid = sessionStorage.getItem('LocalUserID') || ''
    callParam.LoginUID = sessionStorage.getItem('LocalLoginUID') || ''
    if (callParam.UpType === 'SSO' && window.GLOB.localSystemApi) {
    if (result.LTextOut) {
      callParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      callParam.secretkey = Utils.encrypt(callParam.LTextOut, callParam.timestamp)
      callParam.open_key = Utils.encryptOpenKey(callParam.secretkey, callParam.timestamp)
    } else {
      callParam = {...outParam}
      callParam.func = btn.callbackFunc
      callParam.MenuNO = 'sVersionDetail_LocalM'
      callParam.UpType = 'SSO'
      callParam.LTextOut = 'minke'
      callParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      callParam.secretkey = Utils.encrypt(callParam.LTextOut, callParam.timestamp)
      callParam.open_key = Utils.encryptOpenKey(callParam.secretkey, callParam.timestamp)
      callParam.userid = sessionStorage.getItem('LocalUserID') || ''
      callParam.LoginUID = sessionStorage.getItem('LocalLoginUID') || ''
      delete result.ErrCode
      delete result.ErrMesg
      sinParam = {...result}
      sinParam.func = 'sPC_TrdMenu_AddUpt_sso'
      if (window.GLOB.sysType === 'local') {
        if (!window.GLOB.systemType && window.GLOB.cloudServiceApi) {
          sinParam.rduri = window.GLOB.cloudServiceApi
        } else if (window.GLOB.localSystemApi) {
          sinParam.rduri = window.GLOB.localSystemApi
          sinParam.userid = sessionStorage.getItem('LocalUserID') || ''
          sinParam.LoginUID = sessionStorage.getItem('LocalLoginUID') || ''
        }
      }
    }
    if (result.UpType === 'SSO' && window.GLOB.localSystemApi) {
      ssoParam = fromJS(callParam).toJS()
      ssoParam.rduri = window.GLOB.localSystemApi
      delete ssoParam.UpType
    } else {
      delete callParam.UpType
    }
    if (ssoParam) {
    if (sinParam) {
      Api.genericInterface(sinParam).then(res => {
        if (!res.status) {
          this.execError(res)
          _resolve()
        } else {
          Api.genericInterface(callParam).then(re => {
            if (!re.status) {
              this.execError(re)
              _resolve()
            } else {
              if (params.length === 0) {
                this.execSuccess(res)
                _resolve()
              } else {
                this.outerLoopRequest(params, _resolve)
              }
            }
          })
        }
      })
    } else if (ssoParam) {
      Api.genericInterface(ssoParam).then(res => {
        if (!res.status) {
          this.execError(res)
src/templates/sharecomponent/chartcomponent/chartcompile/formconfig.jsx
@@ -235,22 +235,6 @@
        text: '堆叠'
      }]
    }, {
      type: 'radio',
      key: 'repeat',
      label: '重复数据',
      initVal: card.repeat || 'unrepeat',
      required: false,
      options: [{
        value: 'unrepeat',
        text: '去重'
      }, {
        value: 'average',
        text: '平均'
      }, {
        value: 'cumsum',
        text: '累加'
      }]
    }, {
      type: 'number',
      key: 'InfoDefNumber',
      label: '展示数',
src/templates/zshare/verifycard/index.jsx
@@ -1061,12 +1061,12 @@
      {
        obj_name: 'noteCodes',
        arr_field: 'templatecode,describe,id',
        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`))
        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 =u.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`))
        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=u.openid`))
      },
      {
        obj_name: 'scripts',
src/views/menudesign/index.jsx
@@ -1108,6 +1108,27 @@
    }, 400)
  }
  checklog = () => {
    const { oriConfig, config } = this.state
    return is(fromJS(oriConfig), fromJS(config))
  }
  updateLogConfig = (config) => {
    config.fstMenuId = this.state.config.fstMenuId || config.fstMenuId || ''
    config.parentId = this.state.config.parentId || config.parentId || ''
    this.setState({
      config: null
    }, () => {
      this.setState({
        config: config
      })
    })
    window.GLOB.customMenu = config
  }
  render () {
    const { view, comloading, MenuType, MenuId, config, settingshow, ParentId, menuloading, eyeopen, needUpdate } = this.state
@@ -1168,7 +1189,7 @@
                  <div className="mk-opeartion-list">
                    {config ? <Debug config={config}/> : null}
                    <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                    <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/>
                    {config ? <Versions MenuId={MenuId} Template="CustomPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                    <TableNodes config={config} />
                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                    <SysInterface config={config} updateConfig={this.updateConfig}/>
src/views/mobdesign/index.jsx
@@ -568,6 +568,7 @@
        
        config.uuid = MenuId
        config.MenuID = MenuId
        config.Template = 'webPage'
        config.open_edition = result.open_edition || ''
        config.direction = config.direction || sessionStorage.getItem('direction') || 'vertical'
        window.GLOB.urlFields = config.urlFields || []
@@ -686,6 +687,7 @@
    
    config.uuid = MenuId
    config.MenuID = MenuId
    config.Template = 'webPage'
    config.open_edition = result.open_edition || ''
    this.setState({
@@ -825,6 +827,7 @@
      config.uuid = MenuId
      config.MenuID = MenuId
      config.open_edition = ''
      config.Template = 'webPage'
      config.MenuName = urlParam.MenuName || ''
      // config.MenuNo = urlParam.MenuNo || ''
      config.MenuNo = ''
@@ -2055,6 +2058,24 @@
    window.GLOB.customMenu = config
  }
  checklog = () => {
    const { oriConfig, config } = this.state
    return is(fromJS(oriConfig), fromJS(config))
  }
  updateLogConfig = (config) => {
    this.setState({
      config: null
    }, () => {
      this.setState({
        config: config
      })
    })
    window.GLOB.customMenu = config
  }
  render () {
    const { view, viewType, comloading, loading, settingshow, controlshow, activeKey, MenuId, config, menuloading, adapters, eyeopen, needUpdate } = this.state
@@ -2130,7 +2151,7 @@
                <Button className="mk-border-purple set-login" onClick={this.setLoginView}><LoginOutlined /> 设为登录页</Button>
                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                <Transfer MenuID={MenuId} />
                <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/>
                {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                <Button type="default" onClick={this.closeView}>关闭</Button>
              </div>
            </div>
src/views/pcdesign/index.jsx
@@ -531,6 +531,7 @@
        config.uuid = MenuId
        config.MenuID = MenuId
        config.Template = 'webPage'
        config.open_edition = result.open_edition || ''
        window.GLOB.urlFields = config.urlFields || []
@@ -737,6 +738,7 @@
      
      config.uuid = MenuId
      config.MenuID = MenuId
      config.Template = 'webPage'
      config.open_edition = ''
      config.MenuName = urlParam.MenuName || ''
      config.MenuNo = ''
@@ -1676,6 +1678,24 @@
    })
  }
  checklog = () => {
    const { oriConfig, config } = this.state
    return is(fromJS(oriConfig), fromJS(config))
  }
  updateLogConfig = (config) => {
    this.setState({
      config: null
    }, () => {
      this.setState({
        config: config
      })
    })
    window.GLOB.customMenu = config
  }
  render () {
    const { view, loading, comloading, activeKey, settingshow, controlshow, MenuId, config, menuloading, eyeopen, needUpdate } = this.state
@@ -1742,7 +1762,7 @@
                <Button className="mk-border-purple" onClick={this.setLoginView}><LoginOutlined/> 设为登录页</Button>
                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                <Transfer MenuID={MenuId} />
                <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/>
                {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                <Button type="default" onClick={this.closeView}>关闭</Button>
              </div>
            </div>
src/views/tabledesign/index.jsx
@@ -818,6 +818,27 @@
    sessionStorage.setItem('settingshow', '' + !this.state.settingshow)
  }
  checklog = () => {
    const { oriConfig, config } = this.state
    return is(fromJS(oriConfig), fromJS(config))
  }
  updateLogConfig = (config) => {
    config.fstMenuId = this.state.config.fstMenuId || config.fstMenuId || ''
    config.parentId = this.state.config.parentId || config.parentId || ''
    this.setState({
      config: null
    }, () => {
      this.setState({
        config: config
      })
    })
    window.GLOB.customMenu = config
  }
  render () {
    const { view, activeKey, comloading, MenuId, config, settingshow, ParentId, menuloading } = this.state
@@ -875,7 +896,7 @@
                    {config ? <Debug config={config}/> : null}
                    {config ? <Transfer config={config}/> : null}
                    {config ? <Unattended config={config} updateConfig={this.updateConfig}/> : null}
                    <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/>
                    {config ? <Versions MenuId={MenuId} Template="BaseTable" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                    <TableNodes config={config} />
                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                    <PasteBaseTable type="page" insert={this.insert}/>