king
2021-01-04 82fe5225c6d678af65a9d7610b0ac5fb49a67f2c
2021-01-04
4个文件已修改
9个文件已添加
724 ■■■■■ 已修改文件
src/menu/components/group/normal-group/index.jsx 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/index.scss 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/tabcomponents/card.jsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/tabcomponents/index.jsx 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/tabcomponents/index.scss 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/tabsetting/index.jsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/tabsetting/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/tabsetting/settingform/index.jsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/tabsetting/settingform/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/card.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modelsource/option.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/index.jsx
New file
@@ -0,0 +1,172 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { is, fromJS } from 'immutable'
import { Icon, Popover } from 'antd'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('../tabsetting'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
class NormalGroup extends Component {
  static propTpyes = {
    group: PropTypes.object,
    deletecomponent: PropTypes.func,
    updateConfig: PropTypes.func,
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    group: null,
    editab: null,
  }
  UNSAFE_componentWillMount () {
    const { group } = this.props
    console.log(group)
    if (group.isNew) {
      let _group = {
        uuid: group.uuid,
        type: group.type,
        floor: group.floor,
        tabId: group.tabId || '',
        parentId: group.parentId || '',
        subtype: group.subtype,
        width: 24,
        name: group.name,
        setting: { width: 24, name: group.name },
        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
        components: []
      }
      this.setState({
        group: _group
      })
      this.props.updateConfig(_group)
    } else {
      this.setState({
        group: fromJS(group).toJS()
      })
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('tabsChange', this.handleTabsChange)
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  changeStyle = () => {
    const { group } = this.state
    MKEmitter.emit('changeStyle', [group.uuid], ['background', 'border', 'padding', 'margin'], group.style)
  }
  getStyle = (comIds, style) => {
    const { group } = this.state
    if (comIds.length !== 1 || comIds[0] !== group.uuid) return
    let _card = {...group, style}
    this.setState({
      group: _card
    })
    this.props.updateConfig(_card)
  }
  handleTabsChange = (parentId) => {
    const { group } = this.state
    if (parentId === group.parentId) {
      MKEmitter.emit('tabsChange', group.uuid)
    }
  }
  updateComponent = (component) => {
    const { group } = this.state
    if (!is(fromJS(group.setting), fromJS(component.setting))) {
      // 注册事件-标签变化,通知标签内元素
      MKEmitter.emit('tabsChange', group.uuid)
    }
    component.width = component.setting.width
    component.name = component.setting.name
    this.setState({
      group: component
    })
    this.props.updateConfig(component)
  }
  insert = (item, cell) => {
    let group = fromJS(this.state.group).toJS()
    group.components.forEach(stab => {
      if (stab.uuid === cell.uuid) {
        stab.components.push(item)
      }
    })
    this.setState({group})
    this.props.updateConfig(group)
  }
  render() {
    const { group } = this.state
    return (
      <div className="menu-group-edit-box" style={group.style}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <SettingComponent config={group} updateConfig={this.updateComponent} />
            <CopyComponent type="tabs" card={group}/>
            <PasteController type="tab" Tab={group} insert={this.insert} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(group.uuid)} />
          </div>
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        <TabComponents config={group} handleList={this.updateComponent} deleteCard={this.deleteCard} />
      </div>
    )
  }
}
const mapStateToProps = (state) => {
  return {
    menu: state.customMenu
  }
}
const mapDispatchToProps = () => {
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(NormalGroup)
src/menu/components/group/normal-group/index.scss
New file
@@ -0,0 +1,32 @@
.menu-group-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);
  }
}
.menu-group-edit-box::before {
  content: ' ';
  display: block;
  float: right;
  width: 20px;
  height: 28px;
  clear: right;
}
.menu-group-edit-box:hover {
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/group/tabcomponents/card.jsx
New file
@@ -0,0 +1,69 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar'))
const AntvPie = asyncComponent(() => import('@/menu/components/chart/antv-pie'))
const DataCard = asyncComponent(() => import('@/menu/components/card/data-card'))
const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card'))
const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'menu', id, originalIndex, floor: card.floor },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const [, drop] = useDrop({
    accept: 'menu',
    canDrop: () => true,
    drop: (item) => {
      const { id: draggedId, originalIndex, floor } = item
      if (originalIndex === undefined) {
        item.dropTargetId = id
      } else if (draggedId && floor === card.floor) {
        if (draggedId === id) return
        const { index: originIndex } = findCard(draggedId)
        if (originIndex === -1) return
        const { index: overIndex } = findCard(id)
        moveCard(draggedId, overIndex)
      }
    }
  })
  let style = { opacity: 1}
  if (isDragging) {
    style = { opacity: 0.3}
  }
  const getCardComponent = () => {
    if (card.type === 'bar' || card.type === 'line') {
      return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard} />)
    } else if (card.type === 'pie') {
      return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'card' && card.subtype === 'datacard') {
      return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard} />)
    } else if (card.type === 'card' && card.subtype === 'propcard') {
      return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    }
  }
  return (
    <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} ref={node => drag(drop(node))} style={style}>
      {getCardComponent()}
    </div>
  )
}
export default Card
src/menu/components/group/tabcomponents/index.jsx
New file
@@ -0,0 +1,181 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import { Empty, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import Card from './card'
import './index.scss'
const { confirm } = Modal
const Container = ({ config, handleList }) => {
  const [cards, setCards] = useState(config.components)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    handleList({...config, components: _cards})
  }
  if (!is(fromJS(cards), fromJS(config.components))) {
    setCards(config.components)
  }
  const findCard = id => {
    const card = cards.filter(c => `${c.uuid}` === id)[0]
    return {
      card,
      index: cards.indexOf(card),
    }
  }
  const updateConfig = (element) => {
    handleList({...config, components: cards.map(item => item.uuid === element.uuid ? element : item)})
  }
  const deleteCard = (id) => {
    const { card } = findCard(id)
    let uuids = []
    if (card.action && card.action.length) {
      card.action.forEach(act => {
        if (!act.origin) {
          uuids.push(act.uuid)
        }
      })
    }
    if (card.type === 'card') {
      card.subcards.forEach(_card => {
        _card.elements && _card.elements.forEach(cell => {
          if (cell.eleType === 'button') {
            uuids.push(cell.uuid)
          }
        })
        _card.backElements && _card.backElements.forEach(cell => {
          if (cell.eleType === 'button') {
            uuids.push(cell.uuid)
          }
        })
      })
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
      card.subcards.forEach(_card => {
        _card.elements && _card.elements.forEach(cell => {
          if (cell.eleType === 'button') {
            uuids.push(cell.uuid)
          }
        })
      })
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      card.cols && card.cols.forEach(col => {
        if (col.type !== 'action') return
        col.elements && col.elements.forEach(cell => {
          uuids.push(cell.uuid)
        })
      })
    }
    confirm({
      title: `确定删除《${card.name}》吗?`,
      onOk() {
        MKEmitter.emit('delButtons', uuids)
        handleList({...config, components: cards.filter(item => item.uuid !== card.uuid)})
      },
      onCancel() {}
    })
  }
  const [, drop] = useDrop({
    accept: 'menu',
    drop(item) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      } else if (item.component === 'tabs' || item.component === 'search' || item.component === 'group') { // 分组中不可添加标签页或搜索
        return
      }
      item.added = true
      let name = ''
      let names = {
        bar: '柱状图',
        line: '折线图',
        pie: '饼图',
        table: '表格',
        card: '卡片'
      }
      let i = 1
      while (!name && names[item.component]) {
        let _name = names[item.component] + i
        if (config.components.filter(com => com.name === _name).length === 0) {
          name = _name
        }
        i++
      }
      let dataName = ''
      while (!dataName) {
        let _dataName = Utils.getdataName()
        if (config.components.filter(com => com.dataName === _dataName).length === 0) {
          dataName = _dataName
        }
      }
      let newcard = {
        uuid: Utils.getuuid(),
        tabId: config.uuid,
        parentId: config.parentId,
        type: item.component,
        subtype: item.subtype,
        config: item.config,
        width: item.width || 24,
        dataName: dataName,
        name: name,
        floor: config.floor || 1, // 组件的层级
        isNew: true               // 新添加标志,用于初始化
      }
      console.log(newcard)
      let targetId = ''
      if (item.dropTargetId) {
        targetId = item.dropTargetId
        delete item.dropTargetId
      } else if (cards.length > 0) {
        targetId = cards.slice(-1)[0].uuid
      }
      const { index: overIndex } = findCard(`${targetId}`)
      const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] })
      handleList({...config, components: _cards})
    }
  })
  return (
    <div ref={drop} className="ant-row group-shell-inner">
      {cards.map(card => (
        <Card
          id={card.uuid}
          key={card.uuid}
          config={config}
          card={card}
          moveCard={moveCard}
          delCard={deleteCard}
          findCard={findCard}
          updateConfig={updateConfig}
        />
      ))}
      {cards.length === 0 ?
        <Empty description={
          <span>
            请添加组件。
            <span style={{display: 'block', fontSize: '12px', color: '#959595'}}>注:标签页、分组、搜索不可添加</span>
          </span>
        } /> : null
      }
    </div>
  )
}
export default Container
src/menu/components/group/tabcomponents/index.scss
New file
@@ -0,0 +1,17 @@
.group-shell-inner {
  margin: -8px;
  >.ant-col {
    padding: 8px;
  }
  .anticon {
    cursor: unset;
  }
  .mk-component-card {
    position: relative;
  }
  >.ant-empty {
    padding: 10px 0px;
  }
}
src/menu/components/group/tabsetting/index.jsx
New file
@@ -0,0 +1,81 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Icon, Modal } from 'antd'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import SettingForm from './settingform'
import './index.scss'
class DataSource extends Component {
  static propTpyes = {
    config: PropTypes.any,
    updateConfig: PropTypes.func
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    visible: false,
    setting: null
  }
  UNSAFE_componentWillMount () {
    const { config } = this.props
    this.setState({setting: fromJS(config.setting).toJS()})
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  editDataSource = () => {
    this.setState({
      visible: true
    })
  }
  verifySubmit = () => {
    const { config } = this.props
    this.verifyRef.handleConfirm().then(res => {
      this.setState({
        setting: res,
        visible: false
      })
      this.props.updateConfig({...config, setting: res})
    })
  }
  render () {
    const { visible, dict, setting } = this.state
    return (
      <div className="model-menu-setting-wrap">
        <Icon type="edit" onClick={() => this.editDataSource()} />
        <Modal
          wrapClassName="popview-modal"
          title={'标签页配置'}
          visible={visible}
          width={700}
          maskClosable={false}
          okText={dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          <SettingForm
            dict={dict}
            setting={setting}
            inputSubmit={this.verifySubmit}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
          />
        </Modal>
      </div>
    )
  }
}
export default DataSource
src/menu/components/group/tabsetting/index.scss
New file
@@ -0,0 +1,7 @@
.model-menu-setting-wrap {
  display: inline-block;
  >.anticon-edit {
    color: #1890ff;
  }
}
src/menu/components/group/tabsetting/settingform/index.jsx
New file
@@ -0,0 +1,134 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select } from 'antd'
import './index.scss'
class SettingForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,       // 字典项
    setting: PropTypes.object,    // 数据源配置
    inputSubmit: PropTypes.func   // 回车事件
  }
  state = {
    roleList: []
  }
  UNSAFE_componentWillMount () {
    let roleList = sessionStorage.getItem('sysRoles')
    if (roleList) {
      try {
        roleList = JSON.parse(roleList)
      } catch {
        roleList = []
      }
    } else {
      roleList = []
    }
    this.setState({roleList})
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  handleSubmit = (e) => {
    e.preventDefault()
    if (this.props.inputSubmit) {
      this.props.inputSubmit()
    }
  }
  render() {
    const { setting } = this.props
    const { getFieldDecorator } = this.props.form
    const { roleList } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <div className="model-menu-setting-form">
        <Form {...formItemLayout}>
          <Row gutter={24}>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="用于组件间的区分。">
                  <Icon type="question-circle" />
                  组件名称
                </Tooltip>
              }>
                {getFieldDecorator('name', {
                  initialValue: setting.name,
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '组件名称!'
                    }
                  ]
                })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。">
                  <Icon type="question-circle" />
                  宽度
                </Tooltip>
              }>
                {getFieldDecorator('width', {
                  initialValue: setting.width || 24,
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '宽度!'
                    }
                  ]
                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="黑名单">
                {getFieldDecorator('blacklist', {
                  initialValue: setting.blacklist || []
                })(
                  <Select
                    showSearch
                    mode="multiple"
                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  >
                    {roleList.map(option =>
                      <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option>
                    )}
                  </Select>
                )}
              </Form.Item>
            </Col>
          </Row>
        </Form>
      </div>
    )
  }
}
export default Form.create()(SettingForm)
src/menu/components/group/tabsetting/settingform/index.scss
New file
@@ -0,0 +1,11 @@
.model-menu-setting-form {
  position: relative;
  .anticon-question-circle {
    color: #c49f47;
    margin-right: 3px;
  }
  .ant-input-number {
    width: 100%;
  }
}
src/menu/components/tabs/tabcomponents/index.jsx
@@ -142,6 +142,7 @@
        pie: '饼图',
        search: '搜索',
        table: '表格',
        group: '分组',
        card: '卡片'
      }
      let i = 1
src/menu/menushell/card.jsx
@@ -12,6 +12,7 @@
const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card'))
const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => {
  const originalIndex = findCard(id).index
@@ -29,10 +30,14 @@
      if (originalIndex === undefined) {
        item.dropTargetId = id
      } else if (draggedId && floor === card.floor) {
        if (draggedId !== id) {
          const { index: overIndex } = findCard(id)
          moveCard(draggedId, overIndex)
        }
        if (draggedId === id) return
        const { index: originIndex } = findCard(draggedId)
        if (originIndex === -1) return
        const { index: overIndex } = findCard(id)
        moveCard(draggedId, overIndex)
      }
    }
  })
@@ -59,6 +64,8 @@
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'group' && card.subtype === 'normalgroup') {
      return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    }
  }
  return (
src/menu/menushell/index.jsx
@@ -115,6 +115,7 @@
        delete item.added // 删除组件添加标记
        return
      }
      console.log(item)
      if (item.component === 'search') { // 搜索组件不可重复添加
        if (cards.filter(card => card.type === 'search').length > 0) {
          notification.warning({
@@ -134,6 +135,7 @@
        pie: '饼图',
        search: '搜索',
        table: '表格',
        group: '分组',
        card: '卡片'
      }
      let i = 1
src/menu/modelsource/option.jsx
@@ -16,7 +16,7 @@
// 组件配置信息
export const menuOptions = [
  { type: 'menu', url: tabs, component: 'tabs', subtype: 'tabs', title: '标签页', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: group, component: 'group', subtype: 'group', title: '分组', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '分组', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '搜索条件', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '数据卡', config: `[{"uuid":"160135809128212dm7i29fim9ksto9od","setting":{"width":6},"style":{"paddingTop":"15px","marginTop":"4px","paddingRight":"15px","marginRight":"8px","marginLeft":"8px","backgroundColor":"rgba(255, 255, 255, 1)","borderColor":"#e8e8e8","paddingLeft":"15px","marginBottom":"4px","borderWidth":"1px","paddingBottom":"10px"},"backStyle":{},"elements":[{"datatype":"static","width":12,"marks":null,"height":1,"value":"关单","style":{},"prefix":"","postfix":"","format":"","eleType":"text","uuid":"160231860159931untbea62sgokunc5s"},{"datatype":"static","width":12,"marks":null,"style":{"color":"rgba(250, 219, 20, 1)","textAlign":"right"},"btnstyle":{},"eleType":"icon","icon":"question-circle","field":"","uuid":"1602318768361nv8ql4t47sgcsn88b0u"},{"datatype":"static","width":24,"marks":null,"height":1,"innerHeight":36,"value":"100","style":{"fontSize":"24px","fontWeight":"500","color":"rgba(0, 0, 0, 1)"},"prefix":"","btnstyle":{},"postfix":"","format":"","eleType":"text","uuid":"1602318817884v70gtgb65ubnm8mbcvv"},{"color":"#1890ff","width":24,"marks":null,"maxValue":100,"style":{"color":"rgba(250, 140, 22, 1)","paddingTop":"20px","paddingBottom":"10px"},"btnstyle":{},"eleType":"slider","field":"int1","uuid":"16023188871233rkktuvpp1h077igrsu"},{"eleType":"splitline","width":24,"color":"#e8e8e8","uuid":"1602320017038n31bk9o831ggug0tu0b","marks":null,"style":{"marginTop":"10px","marginBottom":"10px"},"btnstyle":{}},{"datatype":"static","width":12,"marks":null,"height":1,"value":"100","style":{"marginTop":"6px"},"prefix":"关单","btnstyle":{},"postfix":"","format":"","eleType":"text","uuid":"1602320061243drd7lf3agvn04kgr175"}],"backElements":[]}]` },
  { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '属性卡', config: `[{"uuid":"1603681387259qaqf1127f72esmtchge","setting":{"width":6,"type":"simple"},"style":{"paddingTop":"15px","marginTop":"8px","paddingRight":"15px","marginRight":"8px","marginLeft":"8px","borderColor":"#e8e8e8","paddingLeft":"15px","marginBottom":"8px","borderWidth":"1px","paddingBottom":"15px"},"backStyle":{},"elements":[{"datatype":"static","width":12,"marks":null,"height":1,"value":"超时工单","style":{"color":"rgba(67, 67, 67, 0.51)"},"prefix":"","postfix":"","format":"","eleType":"text","uuid":"1603681402945qnkgm7q8cng65evn5ev"},{"eleType":"icon","datatype":"static","width":12,"icon":"question-circle","tooltip":"超时工单","uuid":"1603681473384i2crkbtofg4pu76k06a","marks":null,"style":{"textAlign":"right","color":"rgba(250, 219, 20, 1)"}},{"datatype":"static","width":24,"marks":null,"height":1,"innerHeight":36,"value":"100","style":{"fontSize":"24px","color":"rgba(0, 0, 0, 1)"},"prefix":"","postfix":"","format":"","eleType":"number","uuid":"1603681539870d704ufqf98kc6t7537t"},{"color":"rgba(250, 219, 20, 1)","datatype":"static","width":24,"marks":null,"maxValue":100,"value":50,"style":{"paddingTop":"10px","paddingBottom":"10px"},"eleType":"slider","uuid":"1603683067556mvupau0odvrtv45u7o8"},{"eleType":"splitline","width":24,"color":"#e8e8e8","uuid":"1603683117981t9k55k8an430fuppmci","marks":null,"style":{"paddingTop":"5px","paddingBottom":"5px"}},{"datatype":"static","width":12,"marks":null,"height":1,"value":"100","style":{"color":"rgba(0, 0, 0, 0.65)","marginTop":"10px"},"prefix":"超时工单  ","postfix":"","format":"","eleType":"text","uuid":"1603683136553uvsmkfohkft9idbfkhu"}],"backElements":[]}]` },