king
2022-11-14 5ec0f02101cb4255c6398856bbf17a2a0b2c9a7e
2022-11-14
53个文件已修改
5个文件已添加
1122 ■■■■ 已修改文件
src/components/normalform/modalform/styleInput/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/options.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/prop-card/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.jsx 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.scss 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/index.scss 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/iframe/index.jsx 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/iframe/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/iframe/options.jsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/normalform/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/timeline/normal-timeline/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/card.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulesource/option.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/mobshell/card.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modulesource/option.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/card.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/modulesource/option.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/data-card/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/data-card/index.scss 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/prop-card/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/prop-card/index.scss 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.scss 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-dashboard/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-dashboard/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-pie/index.jsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-pie/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-scatter/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-scatter/index.scss 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/custom-chart/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/custom-chart/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/iframe/index.jsx 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/iframe/index.scss 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/option.js 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/styleInput/index.jsx
@@ -23,11 +23,11 @@
  UNSAFE_componentWillMount () {
    const { config } = this.props
    let val = config.initval || ''
    let val = config.initval || config.initVal || ''
    let options = config.options || ['px', 'vh', 'vw', '%']
    let unit = options[0]
    if (val) {
    if (val && typeof(val) === 'string') {
      if (val.indexOf('px') > -1) {
        unit = 'px'
      } else if (val.indexOf('%') > -1) {
src/menu/components/card/cardcellcomponent/index.jsx
@@ -420,7 +420,8 @@
        if (cell.uuid === res.uuid) {
          res.eleType = cell.eleType || null
          res.style = cell.style || null
          res.modal = cell.modal || null
          // res.modal = cell.modal || null
          // res.config = cell.config || null
          res.wrapStyle = cell.wrapStyle || null
          // res = {...cell, ...res}
src/menu/components/carousel/data-card/index.jsx
@@ -14,6 +14,7 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
@@ -213,7 +214,11 @@
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    _card.style.height = res.height
    // _card.style.height = res.height
    if (res.title && !_card.headerStyle) {
      _card.headerStyle = { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }
    }
    this.updateComponent(_card)
  }
@@ -234,9 +239,11 @@
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-data-carousel-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <NormalForm title="轮播-动态数据" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
@@ -252,7 +259,9 @@
        } trigger="hover">
          <ToolOutlined/>
        </Popover>
        <div style={{height: card.wrap.height}}>
        <CardSimpleComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/>
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
src/menu/components/carousel/data-card/options.jsx
@@ -18,6 +18,13 @@
  const cardWrapForm = [
    {
      type: 'text',
      field: 'title',
      label: '标题',
      initval: wrap.title || '',
      required: false
    },
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: wrap.name || '',
src/menu/components/carousel/prop-card/index.jsx
@@ -14,6 +14,7 @@
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
@@ -278,7 +279,11 @@
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    _card.style.height = res.height
    // _card.style.height = res.height
    if (res.title && !_card.headerStyle) {
      _card.headerStyle = { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }
    }
    this.updateComponent(_card)
  }
@@ -299,9 +304,11 @@
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-prop-carousel-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <PlusOutlined className="plus" title="添加卡片" onClick={this.addCard}/>
@@ -320,9 +327,11 @@
        } trigger="hover">
          <ToolOutlined/>
        </Popover>
        <div style={{height: card.wrap.height}}>
        {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}>
          {card.subcards.map((subcard) => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        </Carousel> : null}
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -69,14 +69,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
src/menu/components/chart/antv-bar/index.jsx
@@ -9,7 +9,7 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import { chartColors } from '@/utils/option.js'
import './index.scss'
@@ -228,7 +228,7 @@
      const chart = new Chart({
        container: card.uuid + 'canvas',
        autoFit: true,
        height: this.wrap.offsetHeight - 25
        height: getHeight(plot.height)
      })
  
      chart.data(dv.rows)
@@ -554,7 +554,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 25,
      height: getHeight(plot.height)
    })
    // chart.axis(plot.Xaxis, { label: { style: { fill: color } }, tickLine: {style: { stroke: color }}, line: { style: { stroke: color } } })
@@ -948,7 +948,7 @@
      const chart = new Chart({
        container: card.uuid + 'canvas',
        autoFit: true,
        height: this.wrap.offsetHeight - 25
        height: getHeight(plot.height)
      })
      chart.data(dv.rows)
@@ -1354,10 +1354,12 @@
  render() {
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-line-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-line-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
@@ -1375,7 +1377,7 @@
          <ToolOutlined/>
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="canvas" id={card.uuid + 'canvas'}></div>
        {appType !== 'mob' ? <ActionComponent
          config={card}
          updateaction={this.updateComponent}
src/menu/components/chart/antv-bar/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  .canvas {
    margin: 0px;
    padding: 15px 10px 10px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  .chart-header {
src/menu/components/chart/antv-dashboard/chartcompile/formconfig.jsx
@@ -43,14 +43,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
src/menu/components/chart/antv-dashboard/index.jsx
@@ -8,7 +8,7 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
@@ -227,7 +227,7 @@
    const chart = new Chart({
      container: card.uuid + 'dashboard',
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: getHeight(plot.height)
    })
    
    chart.data(data)
@@ -326,7 +326,7 @@
    const chart = new Chart({
      container: card.uuid + 'dashboard',
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: getHeight(plot.height),
      padding: [0, 0, 0, 0],
    })
    chart.data(data)
@@ -532,9 +532,10 @@
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-dashboard-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-dashboard-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
@@ -549,7 +550,7 @@
          <ToolOutlined/>
        </Popover>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'dashboard'} ref={ref => this.wrap = ref}></div>
        <div className="canvas" id={card.uuid + 'dashboard'}></div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
src/menu/components/chart/antv-dashboard/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  
  .canvas {
    margin: 0px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  >.anticon-tool {
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -69,14 +69,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'cascader',
src/menu/components/chart/antv-pie/index.jsx
@@ -9,7 +9,7 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import './index.scss'
@@ -143,6 +143,22 @@
    }
  }
  getHeight = (val) => {
    if (typeof(val) === 'string') {
      if (val.indexOf('px') > -1) {
        val = parseFloat(val)
      } else if (val.indexOf('vw') > -1) {
        val = parseFloat(val)
        val = document.body.clientWidth * val / 100
      } else if (val.indexOf('vh') > -1) {
        val = parseFloat(val)
        val = document.body.clientHeight * val / 100
      }
    }
    return parseInt(val || 400)
  }
  viewrender = () => {
    const { card } = this.state
@@ -248,7 +264,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: getHeight(plot.height),
      padding: 0,
    })
@@ -419,7 +435,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 30
      height: getHeight(plot.height)
    })
    if (plot.shape !== 'nightingale' && plot.show !== 'value') {
@@ -689,9 +705,10 @@
  render() {
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-pie-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-pie-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
@@ -707,7 +724,7 @@
          <ToolOutlined />
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="canvas" id={card.uuid + 'canvas'}></div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
src/menu/components/chart/antv-pie/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  
  .canvas {
    margin: 0px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  >.anticon-tool {
src/menu/components/chart/antv-scatter/chartcompile/formconfig.jsx
@@ -43,14 +43,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
src/menu/components/chart/antv-scatter/index.jsx
@@ -8,7 +8,7 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import './index.scss'
@@ -185,7 +185,7 @@
    const chart = new Chart({
      container: card.uuid + 'canvas',
      autoFit: true,
      height: this.wrap.offsetHeight - 25
      height: getHeight(plot.height)
    })
    chart.data(data);
@@ -374,9 +374,10 @@
  render() {
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-scatter-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-scatter-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
@@ -394,7 +395,7 @@
          <ToolOutlined/>
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="canvas" id={card.uuid + 'canvas'}></div>
        {appType !== 'mob' ? <ActionComponent config={card} updateaction={this.updateComponent}/> : null}
        <div className="component-name">
          <div className="center">
src/menu/components/chart/antv-scatter/index.scss
@@ -5,14 +5,11 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  
  .canvas {
    margin: 0px;
    padding: 15px 10px 10px;
    padding: 15px;
    letter-spacing: 0px;
    flex: 1;
  }
  .chart-header {
src/menu/components/chart/chart-custom/chartcompile/formconfig.jsx
@@ -54,14 +54,13 @@
      required: true
    },
    {
      type: 'number',
      type: 'styleInput',
      key: 'height',
      label: '高度',
      label: '图表高度',
      initVal: card.height,
      min: 100,
      max: 1000,
      decimal: 0,
      required: true
      tooltip: '图表绘图区域的高度,不包括标题及内外边距。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
src/menu/components/chart/chart-custom/index.jsx
@@ -10,7 +10,7 @@
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import { resetStyle, getTables, getHeight } from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import './index.scss'
@@ -255,9 +255,10 @@
  render() {
    const { card, appType } = this.state
    let _style = resetStyle(card.style)
    _style.height = 'auto'
    return (
      <div className="menu-custom-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
      <div className="menu-custom-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
@@ -272,7 +273,9 @@
          <ToolOutlined />
        </Popover>
        <NormalHeader config={card} updateComponent={this.updateComponent}/>
        <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
        <div className="canvas-wrap" style={{height: card.plot.height}}>
          <div className="canvas" id={card.uuid + 'canvas'} style={{height: getHeight(card.plot.height)}} ref={ref => this.wrap = ref}></div>
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
src/menu/components/chart/chart-custom/index.scss
@@ -5,14 +5,14 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  display: flex;
  flex-flow: column;
  .canvas-wrap {
    padding: 15px;
  }
  .canvas {
    margin: 0px;
    padding: 0px;
    letter-spacing: 0px;
    flex: 1;
  }
  .chart-header {
src/menu/components/iframe/index.jsx
New file
@@ -0,0 +1,193 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Input } from 'antd'
import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, SettingOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import getWrapForm from './options'
import './index.scss'
const { Search } = Input
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
class NormalIframe extends Component {
  static propTpyes = {
    card: PropTypes.object,
    deletecomponent: PropTypes.func,
    updateConfig: PropTypes.func,
  }
  state = {
    card: null
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    if (card.isNew) {
      let _card = {
        uuid: card.uuid,
        type: card.type,
        format: 'object',   // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        wrap: { title: '', name: card.name, datatype: 'static', width: card.width || 24, height: '300px', linkType: 'fixed' },
        style: { marginLeft: '0px', marginRight: '0px', marginTop: '0px', marginBottom: '0px' },
        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
        columns: [],
        scripts: [],
      }
      if (card.config) {
        let config = fromJS(card.config).toJS()
        _card.wrap = config.wrap
        _card.wrap.name = card.name
        _card.style = config.style
        _card.setting = config.setting
        _card.columns = config.columns
        _card.scripts = config.scripts
      }
      this.updateComponent(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (!window.GLOB.styling || !card.errors) { // 样式修改时不做筛查
      card.errors = []
      if (card.wrap.datatype === 'dynamic') {
        let columns = card.columns.map(c => c.field)
        if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
          card.errors.push({ level: 0, detail: '未设置数据源!'})
        } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
          card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
        } else if (!card.setting.primaryKey) {
          card.errors.push({ level: 0, detail: '未设置主键!'})
        } else if (!columns.includes(card.setting.primaryKey)) {
          card.errors.push({ level: 0, detail: '主键已失效!'})
        } else if (!card.setting.supModule) {
          card.errors.push({ level: 0, detail: '未设置上级组件!'})
        }
      }
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
    }
    this.setState({
      card: card
    })
    this.props.updateConfig(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', ['border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
  }
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
  getWrapForms = () => {
    const { card } = this.state
    return getWrapForm(card.wrap, card.columns)
  }
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    this.updateComponent(_card)
  }
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    return (
      <div className="menu-iframe-edit-box" style={_style} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <NormalForm title="时间轴设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="iframe" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype === 'dynamic' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
          </div>
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        {card.wrap.linkType === 'input' ? <div className="input-box">
          <Search placeholder="请输入地址" enterButton="确定"/>
        </div> : null}
        <div className="iframe-wrap" style={{height: card.wrap.height}}>
          <iframe title="mk" className="iframe" src={card.wrap.linkUrl || 'http://www.minkesoft.com/index.html'} frameBorder="0"></iframe>
        </div>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
}
export default NormalIframe
src/menu/components/iframe/index.scss
New file
@@ -0,0 +1,53 @@
.menu-iframe-edit-box {
  position: relative;
  box-sizing: border-box;
  background: #ffffff;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 50px;
  .anticon-tool {
    position: absolute;
    z-index: 2;
    font-size: 16px;
    right: 1px;
    top: 1px;
    cursor: pointer;
    padding: 5px;
    background: rgba(255, 255, 255, 0.55);
  }
  .input-box {
    position: absolute;
    top: 0px;
    width: 100%;
    height: 45px;
    padding-top: 5px;
    .ant-input-group-wrapper {
      width: 40%;
      max-width: 400px;
      float: right;
    }
  }
  .normal-header.hidden + .input-box {
    position: relative;
  }
  .iframe-wrap {
    .iframe {
      width: 100%;
      height: 100%;
      vertical-align: top;
    }
  }
}
.menu-iframe-edit-box::after {
  display: block;
  content: ' ';
  clear: both;
}
.menu-iframe-edit-box:hover {
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/iframe/options.jsx
New file
@@ -0,0 +1,124 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, columns) {
  let roleList = sessionStorage.getItem('sysRoles')
  let appType = sessionStorage.getItem('appType')
  if (roleList) {
    try {
      roleList = JSON.parse(roleList)
    } catch (e) {
      roleList = []
    }
  } else {
    roleList = []
  }
  const balconyWrapForm = [
    {
      type: 'text',
      field: 'title',
      label: '标题',
      initval: wrap.title || '',
      required: false
    },
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: wrap.name || '',
      tooltip: '用于组件间的区分。',
      required: true
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: wrap.width || 24,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      precision: 0,
      required: true
    },
    {
      type: 'radio',
      field: 'datatype',
      label: '数据来源',
      initval: wrap.datatype || 'static',
      tooltip: '选择静态值,无需配置数据源。',
      required: false,
      options: [
        {value: 'dynamic', label: '动态'},
        {value: 'static', label: '静态'},
      ],
      controlFields: [
        {field: 'linkField', values: ['dynamic']},
        {field: 'linkType', values: ['static']},
      ]
    },
    {
      type: 'styleInput',
      field: 'height',
      label: '高度',
      initval: wrap.height || '',
      tooltip: 'ifram高度。',
      required: true,
      options: ['px', 'vh', 'vw']
    },
    {
      type: 'radio',
      field: 'linkType',
      label: '链接类型',
      initval: wrap.linkType || 'fixed',
      required: false,
      options: [
        {value: 'fixed', label: '固定链接'},
        {value: 'input', label: '输入链接'},
      ],
      controlFields: [
        {field: 'linkUrl', values: ['fixed']},
      ]
    },
    {
      type: 'textarea',
      field: 'linkUrl',
      label: '地址链接',
      initval: wrap.linkUrl || '',
      required: true,
      span: 24
    },
    {
      type: 'select',
      field: 'linkField',
      label: '地址链接',
      initval: wrap.linkField || '',
      required: columns.length > 0,
      options: columns
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
      initval: wrap.permission || 'false',
      required: false,
      options: [
        {value: 'true', label: '启用'},
        {value: 'false', label: '禁用'},
      ],
      forbid: !appType
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
      initval: wrap.blacklist || [],
      required: false,
      options: roleList,
      forbid: !!appType
    },
  ]
  return balconyWrapForm
}
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -913,6 +913,7 @@
          values.uuid = card.uuid
          values.verify = card.verify || null
          values.modal = card.modal || null
          values.config = card.config || null
          if (values.OpenType === 'form') {
            if (values.formType !== 'scan') {
src/menu/components/share/normalform/index.jsx
@@ -8,6 +8,7 @@
import './index.scss'
const MKTable = asyncComponent(() => import('@/components/normalform/modalform/mkTable'))
const StyleInput = asyncComponent(() => import('@/components/normalform/modalform/styleInput'))
class SettingForm extends Component {
  static propTpyes = {
@@ -80,6 +81,8 @@
        content = (<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit}/>)
      } else if (item.type === 'number') {
        content = (<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.handleSubmit}/>)
      } else if (item.type === 'styleInput') {
        content = (<StyleInput config={item}/>)
      } else if (item.type === 'select') {
        content = (<Select mode={item.multi ? 'multiple' : ''}>
          {item.options.map((option, index) =>
src/menu/components/timeline/normal-timeline/index.jsx
@@ -28,8 +28,7 @@
  }
  state = {
    card: null,
    back: false
    card: null
  }
  UNSAFE_componentWillMount () {
src/menu/menushell/card.jsx
@@ -28,6 +28,7 @@
const CustomChart = asyncComponent(() => import('@/menu/components/chart/chart-custom'))
const Timeline = asyncComponent(() => import('@/menu/components/timeline/normal-timeline'))
const Voucher = asyncComponent(() => import('@/menu/components/module/voucher'))
const Iframe = asyncComponent(() => import('@/menu/components/iframe'))
const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
  const originalIndex = findCard(id).index
@@ -113,6 +114,8 @@
      return (<Timeline card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'chart') {
      return (<CustomChart card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'iframe') {
      return (<Iframe card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'module' && card.subtype === 'voucher') {
      return (<Voucher card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    }
src/menu/menushell/index.jsx
@@ -98,6 +98,7 @@
        tree: '树形列表',
        balcony: '浮动卡',
        timeline: '时间轴',
        iframe: 'iframe',
        card: '卡片'
      }
      let i = 1
src/menu/modulesource/option.jsx
@@ -26,6 +26,7 @@
import chart from '@/assets/mobimg/chart.png'
import tree from '@/assets/mobimg/tree.png'
import timeline from '@/assets/mobimg/timeline.png'
import Iframe from '@/assets/img/newpage.jpg'
// import Voucher from '@/assets/mobimg/voucher.jpg'
// 组件配置信息
@@ -60,5 +61,6 @@
  { type: 'menu', url: Editor, component: 'editor', subtype: 'brafteditor', title: '富文本', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '自定义', width: 24 },
  { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '分组', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Iframe, component: 'iframe', subtype: 'iframe', title: 'iframe', width: 24, forbid: ['billPrint'] },
  // { type: 'menu', url: Voucher, component: 'module', subtype: 'voucher', title: '凭证', width: 24, forbid: ['billPrint'] },
]
src/menu/pastecontroller/index.jsx
@@ -59,7 +59,7 @@
  pasteSubmit = () => {
    let appType = sessionStorage.getItem('appType')
    let options = ['tabs', 'timeline', 'datacard', 'propcard', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
    let options = ['tabs', 'timeline', 'datacard', 'propcard', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'iframe']
    if (appType === 'mob') {
      options.push('menubar', 'topbar')
src/mob/mobshell/card.jsx
@@ -30,6 +30,7 @@
const Balcony = asyncComponent(() => import('@/menu/components/card/balcony'))
const Timeline = asyncComponent(() => import('@/menu/components/timeline/normal-timeline'))
const OfficialAccount = asyncComponent(() => import('@/mob/components/official'))
const Iframe = asyncComponent(() => import('@/menu/components/iframe'))
const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
  const originalIndex = findCard(id).index
@@ -139,6 +140,8 @@
      return (<Timeline card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'officialAccount') {
      return (<OfficialAccount card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'iframe') {
      return (<Iframe card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    }
  }
src/mob/modulesource/option.jsx
@@ -27,6 +27,7 @@
import CommonBar from '@/assets/mobimg/commonbar.png'
import timeline from '@/assets/mobimg/timeline.png'
import officialAccount from '@/assets/mobimg/guanzhu.jpg'
import Iframe from '@/assets/img/newpage.jpg'
// 组件配置信息
export const menuOptions = [
@@ -61,4 +62,5 @@
  { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '分组', width: 24 },
  { type: 'menu', url: Login, component: 'login', subtype: 'normallogin', title: '注册/登录', width: 24 },
  { type: 'menu', url: officialAccount, component: 'officialAccount', subtype: 'officialAccount', title: '关注公众号(小程序中)', width: 24, adapter: 'mini' },
  { type: 'menu', url: Iframe, component: 'iframe', subtype: 'iframe', title: 'iframe', width: 24 }
]
src/pc/menushell/card.jsx
@@ -29,6 +29,7 @@
const Balcony = asyncComponent(() => import('@/menu/components/card/balcony'))
const CustomChart = asyncComponent(() => import('@/menu/components/chart/chart-custom'))
const Timeline = asyncComponent(() => import('@/menu/components/timeline/normal-timeline'))
const Iframe = asyncComponent(() => import('@/menu/components/iframe'))
const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
  const originalIndex = findCard(id).index
@@ -136,6 +137,8 @@
      return (<Timeline card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'chart') {
      return (<CustomChart card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'iframe') {
      return (<Iframe card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    }
  }
src/pc/modulesource/option.jsx
@@ -27,6 +27,7 @@
import chart from '@/assets/mobimg/chart.png'
import tree from '@/assets/mobimg/tree.png'
import timeline from '@/assets/mobimg/timeline.png'
import Iframe from '@/assets/img/newpage.jpg'
// 组件配置信息
export const menuOptions = [
@@ -61,4 +62,5 @@
  { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '自定义', width: 24 },
  { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '分组', width: 24 },
  { type: 'menu', url: Login, component: 'login', subtype: 'normallogin', title: '注册/登录', width: 24 },
  { type: 'menu', url: Iframe, component: 'iframe', subtype: 'iframe', title: 'iframe', width: 24 }
]
src/tabviews/custom/components/card/prop-card/index.jsx
@@ -185,7 +185,7 @@
  }
  /**
   * @description 图表数据更新,刷新内容
   * @description 数据更新,刷新内容
   */
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { sync, config, BID, BData, selected } = this.state
src/tabviews/custom/components/carousel/data-card/index.jsx
@@ -12,6 +12,7 @@
import './index.scss'
const CardItem = asyncComponent(() => import('../cardItem'))
const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader'))
class DataCard extends Component {
  static propTpyes = {
@@ -76,8 +77,6 @@
      _cols.set(item.field, item)
    })
    _card.style.height = _config.style.height
    if (_card.setting.click) {
      _card.style.cursor = 'pointer'
    }
@@ -88,6 +87,9 @@
      }
      return item
    })
    _card.style.height = _config.wrap.height
    _config.style.height = 'auto'
    _config.wrap.speed = (_config.wrap.speed || 3) * 1000
@@ -329,7 +331,9 @@
        footer={null}
        destroyOnClose
      >
        {data && data.length > 0 ? <div className="custom-data-carousel-box" style={config.style}>
        {visible ? <div className="custom-data-carousel-box" style={config.style}>
          <NormalHeader config={config}/>
          <div className="carousel-wrap" style={{height: config.wrap.height}}>
          {data.length > 1 && config.wrap.autoplay === 'false' ? <div className="prev" onClick={() => this.node && this.node.prev()}><LeftOutlined /></div> : null}
          {data.length > 1 && config.wrap.autoplay === 'false' ? <div className="next" onClick={() => this.node && this.node.next()}><RightOutlined /></div> : null}
          <Carousel
@@ -346,6 +350,7 @@
              </div>
            ))}
          </Carousel>
          </div>
        </div> : null}
        {config.wrap.modalContent !== 'update' ? <div className="mk-footer">
          <Checkbox defaultChecked={false} onChange={this.onTipChange}>不在提醒</Checkbox>
@@ -364,6 +369,8 @@
            <Spin />
          </div> : null
        }
        <NormalHeader config={config}/>
        <div className="carousel-wrap" style={{height: config.wrap.height}}>
        {data && data.length > 0 ? <Carousel
          autoplay={config.wrap.autoplay !== 'false'}
          dots={config.wrap.dots !== 'false'}
@@ -376,8 +383,8 @@
              <CardItem card={card} cards={config} data={item}/>
            </div>
          ))}
        </Carousel> : null}
        {!data || data.length === 0 ? <Empty description={false}/> : null}
          </Carousel> : <Empty description={false}/>}
        </div>
      </div>
    )
  }
src/tabviews/custom/components/carousel/data-card/index.scss
@@ -5,7 +5,6 @@
  background-size: cover;
  position: relative;
  min-height: 30px;
  overflow: hidden;
  .card-item-box {
    position: relative;
@@ -15,10 +14,15 @@
    overflow: hidden;
  }
  .carousel-wrap {
    position: relative;
    overflow: hidden;
  }
  .ant-empty {
    width: 100%;
    min-height: 100px;
    padding-top: 15px;
    position: absolute;
    top: calc(50% - 34px);
    left: calc(50% - 92px);
    .ant-empty-image {
      height: 60px;
@@ -53,6 +57,9 @@
}
.mk-carousel-modal {
  .ant-modal-body {
    padding: 20px;
  }
  .ant-modal-close-x {
    width: 40px;
    height: 40px;
src/tabviews/custom/components/carousel/prop-card/index.jsx
@@ -12,6 +12,7 @@
import './index.scss'
const CardItem = asyncComponent(() => import('../cardItem'))
const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader'))
class PropCard extends Component {
  static propTpyes = {
@@ -78,7 +79,7 @@
    })
    _config.subcards.forEach(card => {
      card.style.height = _config.style.height
      card.style.height = _config.wrap.height
      if (card.setting.click) {
        card.style.cursor = 'pointer'
      }
@@ -89,6 +90,8 @@
        return item
      })
    })
    _config.style.height = 'auto'
    _config.wrap.speed = (_config.wrap.speed || 3) * 1000
@@ -353,6 +356,8 @@
        destroyOnClose
      >
        <div className="custom-prop-carousel-box" style={config.style}>
          <NormalHeader config={config}/>
          <div className="carousel-wrap" style={{height: config.wrap.height}}>
          {config.subcards.length > 1 && config.wrap.autoplay === 'false' ? <div className="prev" onClick={() => this.node && this.node.prev()}><LeftOutlined /></div> : null}
          {config.subcards.length > 1 && config.wrap.autoplay === 'false' ? <div className="next" onClick={() => this.node && this.node.next()}><RightOutlined /></div> : null}
          <Carousel
@@ -369,6 +374,7 @@
              </div>
            ))}
          </Carousel>
          </div>
        </div>
        {config.wrap.modalContent !== 'update' ? <div className="mk-footer">
          <Checkbox defaultChecked={false} onChange={this.onTipChange}>不在提醒</Checkbox>
@@ -387,6 +393,8 @@
            <Spin />
          </div> : null
        }
        <NormalHeader config={config}/>
        <div className="carousel-wrap" style={{height: config.wrap.height}}>
        <Carousel
          autoplay={config.wrap.autoplay !== 'false'}
          dots={config.wrap.dots !== 'false'}
@@ -401,6 +409,7 @@
          ))}
        </Carousel>
      </div>
      </div>
    )
  }
}
src/tabviews/custom/components/carousel/prop-card/index.scss
@@ -5,13 +5,17 @@
  background-size: cover;
  min-height: 30px;
  position: relative;
  overflow: hidden;
  .card-item-box {
    position: relative;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    overflow: hidden;
  }
  .carousel-wrap {
    position: relative;
    overflow: hidden;
  }
@@ -44,6 +48,9 @@
}
.mk-carousel-modal {
  .ant-modal-body {
    padding: 20px;
  }
  .ant-modal-close-x {
    width: 40px;
    height: 40px;
src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -108,7 +108,9 @@
      })
    }
    _config.style.height = config.plot.height || 400
    _config.plot.height = Utils.getHeight(_config.plot.height)
    _config.style.height = 'auto'
    _config.style.minHeight = _config.plot.height
    let transfield = {}
    _config.columns.forEach(col => {
@@ -557,7 +559,9 @@
    if (_element) {
      _element.innerHTML = ''
    }
    setTimeout(() => {
    this.viewrender()
    }, 100)
  }
  /**
@@ -903,7 +907,7 @@
    const chart = new Chart({
      container: this.state.chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 25
      height: plot.height
    })
    chart.data(_data)
@@ -1087,7 +1091,7 @@
    const chart = new Chart({
      container: this.state.chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 25
      height: plot.height
    })
    
    // 坐标轴格式化
@@ -1497,7 +1501,7 @@
    const chart = new Chart({
      container: this.state.chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 25
      height: plot.height
    })
    chart.data(_data)
@@ -1846,7 +1850,7 @@
          </div> : null
        }
        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
        <div className="canvas-wrap" ref={ref => this.wrap = ref}>
        <div className="canvas-wrap">
          {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
          <div className={'chart-action' + (config.plot.download === 'enable' ? ' downable' : '')}>
            {config.action.map(item => {
src/tabviews/custom/components/chart/antv-bar-line/index.scss
@@ -5,13 +5,10 @@
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  display: flex;
  flex-flow: column;
  .canvas-wrap {
    margin: 0 0px;
    position: relative;
    flex: 1;
    .chart-action {
      position: absolute;
      top: 0px;
@@ -43,9 +40,8 @@
  .canvas {
    margin: 0;
    padding: 15px 10px 10px;
    padding: 15px;
    letter-spacing: 0px;
    height: 100%;
  }
  .canvas.empty {
    div {
src/tabviews/custom/components/chart/antv-dashboard/index.jsx
@@ -107,7 +107,9 @@
      }
    }
    _config.style.height = config.plot.height || 400
    _config.plot.height = Utils.getHeight(_config.plot.height)
    _config.style.height = 'auto'
    _config.style.minHeight = _config.plot.height
    this.setState({
      config: _config,
@@ -334,7 +336,7 @@
    const chart = new Chart({
      container: chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: plot.height
    })
    
    chart.data(data)
@@ -443,7 +445,7 @@
    const chart = new Chart({
      container: chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: plot.height,
      padding: [0, 0, 0, 0],
    })
    chart.data([_data])
@@ -627,7 +629,7 @@
          </div> : null
        }
        <NormalHeader config={config} />
        <div className="canvas-wrap" ref={ref => this.wrap = ref}>
        <div className="canvas-wrap">
          {config.plot.download === 'enable' && this.state.chart ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
          <div className="canvas" id={this.state.chartId}></div>
        </div>
src/tabviews/custom/components/chart/antv-dashboard/index.scss
@@ -5,13 +5,10 @@
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  display: flex;
  flex-flow: column;
  
  .canvas-wrap {
    margin: 0 0px;
    position: relative;
    flex: 1;
    .download {
      position: absolute;
      z-index: 1;
src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -64,7 +64,9 @@
      _sync = false
    }
    _config.style.height = config.plot.height || 400
    _config.plot.height = Utils.getHeight(_config.plot.height)
    _config.style.height = 'auto'
    _config.style.minHeight = _config.plot.height
    let decimal = 0
    _config.columns.forEach(col => {
@@ -378,14 +380,15 @@
          return
        }
        let sign = item[plot.type] + item[plot.Xaxis]
        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)
          if (map.has(item.$type)) {
            _sort = map.get(item.$type)
          } else {
            map.set(item.type, _sort)
            map.set(item.$type, _sort)
            sort++
          }
@@ -421,14 +424,15 @@
          return
        }
        let sign = item[plot.type] + item[plot.Xaxis]
        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)
          if (map.has(item.$type)) {
            _sort = map.get(item.$type)
          } else {
            map.set(item.type, _sort)
            map.set(item.$type, _sort)
            sort++
          }
@@ -463,11 +467,13 @@
          }
        }
        item.$type = item[plot.type]
        let _sort = sort
        if (map.has(item.type)) {
          _sort = map.get(item.type)
        if (map.has(item.$type)) {
          _sort = map.get(item.$type)
        } else {
          map.set(item.type, _sort)
          map.set(item.$type, _sort)
          sort++
        }
@@ -535,7 +541,7 @@
    const chart = new Chart({
      container: chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 30,
      height: plot.height,
      padding: 0,
    })
@@ -731,7 +737,7 @@
    const chart = new Chart({
      container: chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 30
      height: plot.height
    })
    if (plot.shape !== 'nightingale' && plot.show !== 'value') {
@@ -1039,7 +1045,7 @@
          </div> : null
        }
        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
        <div className="canvas-wrap" ref={ref => this.wrap = ref}>
        <div className="canvas-wrap">
          {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
          <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div>
        </div>
src/tabviews/custom/components/chart/antv-pie/index.scss
@@ -5,13 +5,10 @@
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  display: flex;
  flex-flow: column;
  
  .canvas-wrap {
    margin: 0 0px;
    position: relative;
    flex: 1;
    .download {
      position: absolute;
      z-index: 1;
@@ -33,7 +30,6 @@
    margin: 0;
    padding: 15px;
    letter-spacing: 0px;
    height: 100%;
  }
  .canvas.empty {
    div {
src/tabviews/custom/components/chart/antv-scatter/index.jsx
@@ -64,7 +64,9 @@
      _sync = false
    }
    _config.style.height = config.plot.height || 400
    _config.plot.height = Utils.getHeight(_config.plot.height)
    _config.style.height = 'auto'
    _config.style.minHeight = _config.plot.height
    this.setState({
      config: _config,
@@ -307,7 +309,7 @@
    const chart = new Chart({
      container: chartId,
      autoFit: true,
      height: this.wrap.offsetHeight - 25
      height: plot.height
    })
    chart.data(data);
@@ -422,7 +424,7 @@
          </div> : null
        }
        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
        <div className="canvas-wrap" ref={ref => this.wrap = ref}>
        <div className="canvas-wrap">
          {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
          <div className={'chart-action' + (config.plot.download === 'enable' ? ' downable' : '')}>
            {config.action.map(item => {
src/tabviews/custom/components/chart/antv-scatter/index.scss
@@ -5,13 +5,10 @@
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  display: flex;
  flex-flow: column;
  .canvas-wrap {
    margin: 0 0px;
    position: relative;
    flex: 1;
    .chart-action {
      position: absolute;
      top: 0px;
@@ -44,9 +41,8 @@
  .canvas {
    margin: 0;
    padding: 15px 10px 10px;
    padding: 15px;
    letter-spacing: 0px;
    height: 100%;
  }
  .canvas.empty {
    div {
src/tabviews/custom/components/chart/custom-chart/index.jsx
@@ -58,7 +58,8 @@
      _sync = false
    }
    _config.style.height = config.plot.height || 400
    _config.plot.height = Utils.getHeight(_config.plot.height)
    _config.style.height = 'auto'
    this.setState({
      config: _config,
@@ -347,7 +348,9 @@
          </div> : null
        }
        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
        <div className={'canvas' + (empty ? ' empty' : '')} ref={ref => this.wrap = ref}></div>
        <div className="canvas-wrap" style={{height: (config.plot.height + 30) + 'px'}}>
          <div className={'canvas' + (empty ? ' empty' : '')} style={{height: config.plot.height + 'px'}} ref={ref => this.wrap = ref}></div>
        </div>
        {empty ? <Empty description={false}/> : null}
      </div>
    )
src/tabviews/custom/components/chart/custom-chart/index.scss
@@ -5,14 +5,15 @@
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 100px;
  display: flex;
  flex-flow: column;
  .canvas-wrap {
    padding: 15px;
  }
  .canvas {
    margin: 0;
    padding: 0px;
    letter-spacing: 0px;
    flex: 1;
    height: 100%;
  }
  .canvas.empty {
    div {
src/tabviews/custom/components/iframe/index.jsx
New file
@@ -0,0 +1,249 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Input, Modal, notification, Empty } from 'antd'
import Api from '@/api'
import UtilsDM from '@/utils/utils-datamanage.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
const { Search } = Input
class NormalIframe extends Component {
  static propTpyes = {
    data: PropTypes.array,           // 统一查询数据
    config: PropTypes.object,        // 组件配置信息
    mainSearch: PropTypes.any,       // 外层搜索条件
  }
  state = {
    BID: '',                   // 上级ID
    config: null,              // 图表配置信息
    loading: false,            // 数据加载状态
    activeKey: '',             // 选中数据
    sync: false,               // 是否统一请求数据
    data: {},                  // 数据
    linkUrl: ''
  }
  UNSAFE_componentWillMount () {
    const { data } = this.props
    let _config = fromJS(this.props.config).toJS()
    let _data = { $$empty: true }
    let _sync = false
    let BID = ''
    let BData = ''
    let linkUrl = ''
    if (_config.setting.supModule) {
      BData = window.GLOB.CacheData.get(_config.setting.supModule)
    } else {
      BData = window.GLOB.CacheData.get(_config.$pageId)
    }
    if (BData) {
      BID = BData.$BID || ''
    }
    if (_config.wrap.datatype === 'dynamic') {
      _sync = _config.setting.sync === 'true'
      if (_sync && data) {
        _data = data[_config.dataName] || {$$empty: true}
        if (Array.isArray(_data)) {
          _data = _data[0] || {$$empty: true}
        }
        _sync = false
      }
      linkUrl = _data[_config.wrap.linkField] || ''
    } else {
      if (_config.wrap.linkType !== 'input') {
        linkUrl = _config.wrap.linkUrl || ''
      }
    }
    this.setState({
      linkUrl: linkUrl,
      sync: _sync,
      data: _data,
      BID: BID || '',
      config: _config,
      arr_field: _config.columns.map(col => col.field).join(','),
    }, () => {
      if (_config.wrap.datatype === 'dynamic' && _config.setting.sync !== 'true' && _config.setting.onload === 'true') {
        setTimeout(() => {
          this.loadData()
        }, _config.setting.delay || 0)
      }
    })
  }
  componentDidMount () {
    MKEmitter.addListener('reloadData', this.reloadData)
    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('reloadData', this.reloadData)
    MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
  }
  /**
   * @description 数据更新,刷新内容
   */
  UNSAFE_componentWillReceiveProps (nextProps) {
    const { sync, config } = this.state
    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
      let _data = { $$empty: true }
      if (nextProps.data && nextProps.data[config.dataName]) {
        _data = nextProps.data[config.dataName]
        if (Array.isArray(_data)) {
          _data = _data[0] || {$$empty: true}
        }
      }
      let linkUrl = _data[config.wrap.linkField] || ''
      this.setState({sync: false, data: _data, linkUrl})
    } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
      this.setState({}, () => {
        this.loadData()
      })
    }
  }
  resetParentParam = (MenuID, id, data) => {
    const { config } = this.state
    if (!config.setting.supModule || config.setting.supModule !== MenuID) return
    if (id !== this.state.BID || id !== '') {
      this.setState({ BID: id }, () => {
        this.loadData()
      })
    }
  }
  reloadData = (menuId) => {
    const { config } = this.state
    if (menuId !== config.uuid) return
    this.loadData()
  }
  async loadData () {
    const { mainSearch } = this.props
    const { config, arr_field, BID } = this.state
    if (config.wrap.datatype === 'static') {
      this.setState({
        data: {$$empty: true}
      })
      return
    } else if (config.setting.supModule && !BID) { // BID 不存在时,不做查询
      this.setState({
        data: {$$empty: true}
      })
      return
    }
    let searches = config.setting.useMSearch && mainSearch ? mainSearch : []
    let requireFields = searches.filter(item => item.required && item.value === '')
    if (requireFields.length > 0) {
      return
    }
    let _orderBy = config.setting.order || ''
    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
    let result = await Api.genericInterface(param)
    if (result.status) {
      let _data = {}
      if (result.data && result.data[0]) {
        _data = result.data[0]
      }
      this.setState({
        linkUrl: _data[config.wrap.linkField] || '',
        data: _data,
        loading: false
      })
    } else {
      this.setState({
        loading: false
      })
      if (result.ErrCode === 'N') {
        Modal.error({
          title: result.message,
        })
      } else {
        notification.error({
          top: 92,
          message: result.message,
          duration: 10
        })
      }
    }
  }
  inputUrl = (e) => {
    let val = e.target.value
    let submit = /\n/g.test(val)
    val = val.replace(/\n/g, '')
    if (/\s/.test(val)) {
      submit = false
    }
    if (submit) {
      this.setState({linkUrl: val}, () => {
        let node = document.getElementById(this.state.config.uuid)
        node && node.select && node.select()
      })
    }
  }
  enterUrl = (val) => {
    this.setState({linkUrl: val}, () => {
      let node = document.getElementById(this.state.config.uuid)
      node && node.select && node.select()
    })
  }
  render() {
    const { config, linkUrl } = this.state
    return (
      <div className="menu-iframe-box" style={config.style}>
        {config.wrap.title || config.wrap.linkType === 'input' ? <div className="iframe-header" style={config.headerStyle}>
          <span className="title">{config.wrap.title}</span>
          {config.wrap.linkType === 'input' ? <Search id={config.uuid} placeholder="请输入地址" onChange={this.inputUrl} onSearch={this.enterUrl} enterButton="确定"/> : null}
        </div> : null}
        <div className="iframe-wrap" style={{height: config.wrap.height}}>
          {linkUrl ? <iframe title="mk" className="iframe" src={linkUrl} frameBorder="0"></iframe> : <Empty description={false}/>}
        </div>
      </div>
    )
  }
}
export default NormalIframe
src/tabviews/custom/components/iframe/index.scss
New file
@@ -0,0 +1,63 @@
.menu-iframe-box {
  position: relative;
  box-sizing: border-box;
  background: #ffffff;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 50px;
  .iframe-header {
    position: relative;
    height: 45px;
    padding-right: 8px;
    border-bottom: 1px solid #e8e8e8;
    overflow: hidden;
    letter-spacing: 0px;
    line-height: 45px;
    box-sizing: content-box;
    .title {
      text-decoration: inherit;
      font-weight: inherit;
      font-style: inherit;
      float: left;
      line-height: inherit;
      margin-left: 10px;
      position: relative;
      z-index: 1;
      min-height: 45px;
      min-width: 30px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .ant-input-search {
      margin-top: 5px;
      width: 40%;
      max-width: 400px;
      float: right;
    }
  }
  .ant-empty {
    position: absolute;
    top: calc(50% - 34px);
    left: calc(50% - 92px);
    .ant-empty-image {
      height: 60px;
    }
  }
  .iframe-wrap {
    position: relative;
    .iframe {
      width: 100%;
      height: 100%;
      vertical-align: top;
      margin-top: 0px;
    }
  }
}
src/tabviews/custom/index.jsx
@@ -39,6 +39,7 @@
const CustomChart = asyncComponent(() => import('./components/chart/custom-chart'))
const TimeLine = asyncComponent(() => import('./components/timeline/normal-timeline'))
const Voucher = asyncComponent(() => import('./components/module/voucher'))
const Iframe = asyncComponent(() => import('./components/iframe'))
const DebugTable = asyncComponent(() => import('@/tabviews/debugtable'))
const TableNodes = asyncComponent(() => import('@/tabviews/zshare/tablenodes'))
const MkInterfaces = asyncComponent(() => import('@/tabviews/custom/components/interfaces'))
@@ -1265,6 +1266,12 @@
            <Voucher config={item}/>
          </Col>
        )
      } else if (item.type === 'iframe') {
        return (
          <Col span={item.width} style={style} key={item.uuid}>
            <Iframe config={item} data={data} mainSearch={mainSearch}/>
          </Col>
        )
      } else {
        return null
      }
src/tabviews/custom/popview/index.jsx
@@ -38,6 +38,7 @@
const CustomChart = asyncComponent(() => import('../components/chart/custom-chart'))
const TimeLine = asyncComponent(() => import('../components/timeline/normal-timeline'))
const Voucher = asyncComponent(() => import('../components/module/voucher'))
const Iframe = asyncComponent(() => import('../components/iframe'))
class CustomPage extends Component {
  static propTpyes = {
@@ -987,6 +988,12 @@
            <Voucher config={item}/>
          </Col>
        )
      } else if (item.type === 'iframe') {
        return (
          <Col span={item.width} style={style} key={item.uuid}>
            <Iframe config={item} data={data} mainSearch={mainSearch}/>
          </Col>
        )
      } else {
        return null
      }
src/utils/option.js
@@ -45,15 +45,15 @@
// 系统模板
export const sysTemps = [
  // {
  //   title: '基础表格',
  //   type: 'CommonTable',
  //   url: nortable,
  //   baseconfig: '',
  //   isSystem: true
  // },
  {
    title: '基础表格',
    type: 'CommonTable',
    url: nortable,
    baseconfig: '',
    isSystem: true
  },
  {
    title: '基础表格(新)',
    type: 'BaseTable',
    url: nortable,
    baseconfig: '',
src/utils/utils-custom.js
@@ -872,6 +872,25 @@
}
/**
 * @description 获取图表高度
 */
export function getHeight (val) {
  if (typeof(val) === 'string') {
    if (val.indexOf('px') > -1) {
      val = parseFloat(val)
    } else if (val.indexOf('vw') > -1) {
      val = parseFloat(val)
      val = document.body.clientWidth * val / 100
    } else if (val.indexOf('vh') > -1) {
      val = parseFloat(val)
      val = document.body.clientHeight * val / 100
    }
  }
  return parseInt(val || 400) - 30
}
/**
 * @description 获取表名
 */
export function getTables (config, pops) {
src/utils/utils.js
@@ -59,6 +59,25 @@
  }
  /**
   * @description 获取图表高度
   */
  static getHeight (val) {
    if (typeof(val) === 'string') {
      if (val.indexOf('px') > -1) {
        val = parseFloat(val)
      } else if (val.indexOf('vw') > -1) {
        val = parseFloat(val)
        val = document.body.clientWidth * val / 100
      } else if (val.indexOf('vh') > -1) {
        val = parseFloat(val)
        val = document.body.clientHeight * val / 100
      }
    }
    return parseInt(val || 400) - 30
  }
  /**
   * @description 数据源名称,用于统一查询
   * @return {String}  name
   */
src/views/billprint/index.jsx
@@ -64,7 +64,9 @@
          tempId: param.tempId,
          urlParam: param
        }, () => {
          setTimeout(() => {
          this.getMenuParam()
          }, 200)
        })
      } catch (e) {
        notification.warning({
@@ -199,11 +201,7 @@
    window.GLOB.dataFormat = false // 打印去除水印
    if (window.GLOB.mainSystemApi) { // 从单点登录服务器取打印配置信息
      _param.rduri = window.GLOB.mainSystemApi
    }
    Api.genericInterface(_param).then(result => {
    Api.getCacheConfig(_param).then(result => {
      if (result.status) {
        let config = ''
src/views/menudesign/index.jsx
@@ -1038,7 +1038,8 @@
        tree: '树形列表',
        chart: '自定义图表',
        editor: '富文本',
        group: '分组'
        group: '分组',
        iframe: 'iframe'
      }
      let subforbid = {
        editable: '可编辑表格',