king
2024-05-07 2aa5ab63b4bbce5c36dbb3511b205b3b5f6af9bd
src/menu/stylecontroller/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import { is, fromJS } from 'immutable'
import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button, message } from 'antd'
import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button, message, Checkbox } from 'antd'
import {
  ColumnHeightOutlined,
  FontSizeOutlined,
@@ -28,7 +28,9 @@
  ArrowLeftOutlined,
  ArrowRightOutlined,
  SwapOutlined,
  EnterOutlined
  EnterOutlined,
  DragOutlined,
  EyeOutlined
} from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
@@ -51,10 +53,12 @@
    backgroundImage: '',
    options: [],
    borposition: 'outer',
    type: ''
    type: '',
    logo: sessionStorage.getItem('CloudLogo') || MainLogo
  }
  callback = null
  timer = null
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
@@ -95,6 +99,8 @@
    }
    this.callback = callback
    this.timer = null
    let card = fromJS(style).toJS()
    let borposition = 'outer'
@@ -125,30 +131,37 @@
  onCloseDrawer = () => {
    let card = fromJS(this.state.card).toJS()
    let check = false
    if (card.borderWidth === '0px') {
    if (card.borderWidth === '0px' || !card.borderWidth) {
      delete card.borderWidth
      delete card.borderColor
      check = true
    } else if (card.borderLeftWidth === '0px') {
      delete card.borderLeftWidth
      delete card.borderLeftColor
      check = true
    } else if (card.borderRightWidth === '0px') {
      delete card.borderRightWidth
      delete card.borderRightColor
      check = true
    } else if (card.borderTopWidth === '0px') {
      delete card.borderTopWidth
      delete card.borderTopColor
      check = true
    } else if (card.borderBottomWidth === '0px') {
      delete card.borderBottomWidth
      delete card.borderBottomColor
      check = true
    }
    if (check) {
    if (card.borderLeftWidth === '0px' || !card.borderLeftWidth) {
      delete card.borderLeftWidth
      delete card.borderLeftColor
    }
    if (card.borderRightWidth === '0px' || !card.borderRightWidth) {
      delete card.borderRightWidth
      delete card.borderRightColor
    }
    if (card.borderTopWidth === '0px' || !card.borderTopWidth) {
      delete card.borderTopWidth
      delete card.borderTopColor
    }
    if (card.borderBottomWidth === '0px' || !card.borderBottomWidth) {
      delete card.borderBottomWidth
      delete card.borderBottomColor
    }
    if (/0px 0px 0px | transparent/.test(card.boxShadow)) {
      delete card.hShadow
      delete card.vShadow
      delete card.shadowBlur
      delete card.shadowColor
      delete card.boxShadow
    }
    if (!is(fromJS(this.state.card), fromJS(card))) {
      this.callback && this.callback(card)
    }
@@ -162,7 +175,7 @@
    this.callback = null
  }
  updateStyle = (style) => {
  updateStyle = (style, delay) => {
    const { card } = this.state
    let _style = {
@@ -176,8 +189,12 @@
      }
    })
    if (_style.position === 'relative' || _style.position === 'absolute') {
    if (_style.position === 'relative') {
      _style.zIndex = 1
    } else if (_style.position === 'absolute') {
      _style.zIndex = 2
    } else if (_style.position === 'fixed') {
      _style.zIndex = 3
    } else {
      delete _style.zIndex
    }
@@ -186,7 +203,15 @@
      card: _style,
    })
    this.callback && this.callback(_style)
    this.timer && clearTimeout(this.timer)
    if (delay) {
      this.timer = setTimeout(() => {
        this.callback && this.callback(_style)
      }, 300)
    } else {
      this.callback && this.callback(_style)
    }
  }
  /**
@@ -203,7 +228,7 @@
      value = 300
    }
    this.updateStyle({fontSize: `${value}px`})
    this.updateStyle({fontSize: `${value}px`}, true)
  }
  /**
@@ -214,7 +239,7 @@
    if (isNaN(value) || value < 1 || value > 10) return
    this.updateStyle({lineHeight: value})
    this.updateStyle({lineHeight: value}, true)
  }
  /**
@@ -225,7 +250,7 @@
    if (isNaN(value) || value < 0 || value > 100) return
    this.updateStyle({letterSpacing: `${value}px`})
    this.updateStyle({letterSpacing: `${value}px`}, true)
  }
  /**
@@ -236,56 +261,7 @@
    if (isNaN(value) || value < 0 || value > 100) return
    this.updateStyle({textIndent: `${value}px`})
  }
  /**
   * @description 修改字体粗细
   */
  boldChange = (val) => {
    this.updateStyle({fontWeight: val})
  }
  /**
   * @description 自动换行
   */
  wordBreakChange = (val) => {
    this.updateStyle({wordBreak: val})
  }
  /**
   * @description 修改字体颜色 ,颜色控件
   */
  changeFontColor = (val) => {
    this.updateStyle({color: val})
  }
  /**
   * @description 字体对齐
   */
  changeTextAlign = (e) => {
    this.updateStyle({textAlign: e.target.value})
  }
  /**
   * @description 字体样式,倾斜
   */
  changeFontStyle = (e) => {
    this.updateStyle({fontStyle: e.target.value})
  }
  /**
   * @description 字体装饰,下划线、贯穿线、上划线
   */
  changeTextDecoration = (e) => {
    this.updateStyle({textDecoration: e.target.value})
  }
  /**
   * @description 修改背景颜色 ,颜色控件
   */
  changeBackgroundColor = (val) => {
    this.updateStyle({backgroundColor: val})
    this.updateStyle({textIndent: `${value}px`}, true)
  }
  changeBackground = (val) => {
@@ -312,33 +288,12 @@
  }
  /**
   * @description 修改背景大小
   */
  changeBackgroundSize = (val) => {
    this.updateStyle({backgroundSize: val})
  }
  /**
   * @description 修改背景位置
   */
  changeBackgroundPositon= (val) => {
    this.updateStyle({backgroundPosition: val})
  }
  /**
   * @description 修改背景重复设置
   */
  changeBackgroundRepeat = (val) => {
    this.updateStyle({backgroundRepeat: val})
  }
  /**
   * @description 修改阴影颜色 ,颜色控件
   */
  changeShadowColor = (val) => {
    const { card } = this.state
    let boxShadow = `${card.hShadow || '0px'} ${card.vShadow || '0px'} ${card.shadowBlur || '0px'} ${val}`
    let boxShadow = `${card.hShadow || '0px'} ${card.vShadow || '0px'} ${card.shadowBlur || '0px'} ${val || 'transparent'}`
    this.updateStyle({shadowColor: val, boxShadow})
  }
@@ -444,14 +399,6 @@
    this.updateStyle(_style)
  }
  changeWidth = (val) => {
    this.updateStyle({width: val})
  }
  changeHeight = (val) => {
    this.updateStyle({height: val})
  }
  changeNormalStyle = (val, type) => {
    this.updateStyle({[type]: val})
  }
@@ -488,12 +435,106 @@
    if (res.copyType !== 'style') {
      message.warning('配置信息格式错误!', 5)
      return
    } else if (JSON.stringify(res.options) !== JSON.stringify(options)) {
      message.warning('样式选项不一致,不可粘贴!', 5)
      return
    }
    let style = res.data || {}
    if (JSON.stringify(res.options) !== JSON.stringify(options)) {
      res.options.forEach(n => {
        if (options.includes(n)) return
        if (n === 'width') {
          delete style.width
        } else if (n === 'height') {
          delete style.height
        } else if (n === 'font') {
          if (options.includes('font1')) {
            ['lineHeight', 'letterSpacing', 'fontStyle', 'textAlign', 'textDecoration'].forEach(m => {
              delete style[m]
            })
          } else if (options.includes('font2')) {
          } else {
            ['fontSize', 'fontWeight', 'lineHeight', 'letterSpacing', 'color', 'fontStyle', 'textAlign', 'textDecoration'].forEach(m => {
              delete style[m]
            })
          }
        } else if (n === 'font1') {
          if (options.includes('font') || options.includes('font2')) {
          } else {
            ['fontSize', 'fontWeight', 'color'].forEach(m => {
              delete style[m]
            })
          }
        } else if (n === 'font2') {
          if (options.includes('font')) {
            ['textIndent', 'wordBreak'].forEach(m => {
              delete style[m]
            })
          } else if (options.includes('font1')) {
            ['lineHeight', 'letterSpacing', 'fontStyle', 'textAlign', 'textDecoration', 'textIndent', 'wordBreak'].forEach(m => {
              delete style[m]
            })
          } else {
            ['fontSize', 'fontWeight', 'lineHeight', 'letterSpacing', 'color', 'fontStyle', 'textAlign', 'textDecoration', 'textIndent', 'wordBreak'].forEach(m => {
              delete style[m]
            })
          }
        } else if (n === 'background') {
          if (!options.includes('backgroundColor')) {
            delete style.backgroundColor
          }
          delete style.backgroundImage
          delete style.backgroundSize
          delete style.backgroundRepeat
          delete style.backgroundPosition
        } else if (n === 'backgroundColor') {
          if (!options.includes('background')) {
            delete style.backgroundColor
          }
        } else if (n === 'border') {
          Object.keys(style).forEach(key => {
            if (!/border/.test(key)) return
            delete style[key]
          })
        } else if (n === 'shadow') {
          delete style.boxShadow
          delete style.hShadow
          delete style.vShadow
          delete style.shadowBlur
          delete style.shadowColor
        } else if (n === 'margin') {
          delete style.marginTop
          delete style.marginBottom
          delete style.marginLeft
          delete style.marginRight
        } else if (n === 'padding') {
          delete style.paddingTop
          delete style.paddingBottom
          delete style.paddingLeft
          delete style.paddingRight
        } else if (n === 'float') {
          delete style.float
        } else if (n === 'minHeight') {
          delete style.minHeight
        } else if (n === 'clear') {
          delete style.clear
        } else if (n === 'display') {
          delete style.display
        } else if (n === 'position') {
          delete style.position
          delete style.top
          delete style.bottom
          delete style.left
          delete style.right
        } else if (n === 'transform') {
          delete style.transform
        } else if (n === 'overflow') {
          delete style.overflow
        }
      })
    }
    let backgroundImage = ''
    if (style.backgroundImage && /^url/ig.test(style.backgroundImage)) {
@@ -528,7 +569,7 @@
  }
  render () {
    const { card, options, backgroundImage, borposition, fonts, type } = this.state
    const { card, options, backgroundImage, borposition, fonts, type, logo } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -544,7 +585,7 @@
      <Drawer
        title={
          <div className="header-logo">
            <img src={MainLogo} alt=""/>
            <img src={logo} alt=""/>
          </div>
        }
        placement="left"
@@ -566,7 +607,7 @@
                    label={<ColumnWidthOutlined title="宽度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.width || ''} options={['px', 'vh', 'vw', '%', 'auto']} onChange={this.changeWidth}/>
                    <StyleInput clear={true} defaultValue={card.width || ''} options={['px', 'vh', 'vw', '%', 'auto']} onChange={(val) => this.changeNormalStyle(val, 'width')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
@@ -577,7 +618,7 @@
                    label={<ColumnHeightOutlined title="高度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.height || ''} options={['px', 'vh', 'vw']} onChange={this.changeHeight}/>
                    <StyleInput clear={true} defaultValue={card.height || ''} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'height')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
@@ -589,7 +630,7 @@
                </Col> : null}
                {fonts.includes('fontWeight') ? <Col span={12}>
                  <Form.Item colon={false} label={<BoldOutlined title="字体粗细"/>}>
                    <Select defaultValue={card.fontWeight || 'normal'} onChange={this.boldChange}>
                    <Select defaultValue={card.fontWeight || 'normal'} onChange={(val) => this.changeNormalStyle(val, 'fontWeight')}>
                      <Option value="normal">normal</Option>
                      <Option value="bold">bold</Option>
                      <Option value="bolder">bolder</Option>
@@ -623,7 +664,7 @@
                </Col> : null}
                {fonts.includes('wordBreak') ? <Col span={12}>
                  <Form.Item colon={false} label={<EnterOutlined title="自动换行"/>}>
                    <Select defaultValue={card.wordBreak || 'normal'} onChange={this.wordBreakChange}>
                    <Select defaultValue={card.wordBreak || 'normal'} onChange={(val) => this.changeNormalStyle(val, 'wordBreak')}>
                      <Option value="normal">normal</Option>
                      <Option value="break-all">break-all</Option>
                    </Select>
@@ -635,14 +676,14 @@
                    label={<FontColorsOutlined title="字体颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <ColorSketch value={card.color || ''} onChange={this.changeFontColor} />
                    <ColorSketch value={card.color || ''} onChange={(val) => this.changeNormalStyle(val, 'color')} />
                  </Form.Item>
                  <Form.Item
                    colon={false}
                    label={<BgColorsOutlined title="系统色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <SysColorSketch onChange={this.changeFontColor} />
                    <SysColorSketch onChange={(val) => this.changeNormalStyle(val, 'color')} />
                  </Form.Item>
                </Col> : null}
                {fonts.includes('fontStyle') ? <Col span={24}>
@@ -651,7 +692,7 @@
                    label={' '}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group defaultValue={card.fontStyle || 'normal'} onChange={this.changeFontStyle}>
                    <Radio.Group defaultValue={card.fontStyle || 'normal'} onChange={(e) => this.changeNormalStyle(e.target.value, 'fontStyle')}>
                      <Radio.Button value="normal"><span title="标准">N</span></Radio.Button>
                      <Radio.Button value="italic"><ItalicOutlined title="斜体"/></Radio.Button>
                      <Radio.Button value="oblique" style={{fontStyle: 'oblique'}}><span title="倾斜">B</span></Radio.Button>
@@ -664,7 +705,7 @@
                    label={' '}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group className="text-align" defaultValue={card.textAlign || 'left'} onChange={this.changeTextAlign}>
                    <Radio.Group className="text-align" defaultValue={card.textAlign || 'left'} onChange={(e) => this.changeNormalStyle(e.target.value, 'textAlign')}>
                      <Radio.Button value="left"><AlignLeftOutlined title="左对齐"/></Radio.Button>
                      <Radio.Button value="center"><AlignCenterOutlined title="居中对齐"/></Radio.Button>
                      <Radio.Button value="right"><AlignRightOutlined title="右对齐"/></Radio.Button>
@@ -677,12 +718,31 @@
                    label={' '}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group className="text-decoration" defaultValue={card.textDecoration || 'none'} onChange={this.changeTextDecoration}>
                    <Radio.Group className="text-decoration" defaultValue={card.textDecoration || 'none'} onChange={(e) => this.changeNormalStyle(e.target.value, 'textDecoration')}>
                      <Radio.Button value="none"><span title="标准">N</span></Radio.Button>
                      <Radio.Button value="underline"><UnderlineOutlined title="下划线"/></Radio.Button>
                      <Radio.Button value="line-through"><StrikethroughOutlined title="中划线"/></Radio.Button>
                      <Radio.Button value="overline" style={{textDecoration: 'overline'}}><span title="上划线">O</span></Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </Col> : null}
                {options.includes('fontFamily') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label=" "
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Checkbox.Group options={[
                      { label: '微软雅黑', value: 'Microsoft YaHei' },
                      { label: '宋体', value: 'Simsun' },
                      { label: '黑体', value: 'Simhei' },
                      { label: '仿宋', value: 'FangSong' },
                      { label: '楷体', value: 'KaiTi' },
                      // { label: 'Helvetica', value: 'Helvetica' },
                      // { label: 'Arial', value: 'Arial' },
                      // { label: 'Verdana', value: 'Verdana' },
                      // { label: 'Georgia', value: 'Georgia' },
                    ]} defaultValue={card.fontFamily} onChange={(val) => this.changeNormalStyle(val, 'fontFamily')} />
                  </Form.Item>
                </Col> : null}
              </Panel> : null}
@@ -693,14 +753,14 @@
                    label={<BgColorsOutlined title="背景颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <ColorSketch allowClear={true} value={card.backgroundColor || ''} onChange={this.changeBackgroundColor} />
                    <ColorSketch allowClear={true} value={card.backgroundColor || ''} onChange={(val) => this.changeNormalStyle(val, 'backgroundColor')} />
                  </Form.Item>
                  <Form.Item
                    colon={false}
                    label={<BgColorsOutlined title="系统色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <SysColorSketch onChange={this.changeBackgroundColor} />
                    <SysColorSketch onChange={(val) => this.changeNormalStyle(val, 'backgroundColor')} />
                  </Form.Item>
                </Col>
                {window.develop === true ? <Col span={24}>
@@ -727,7 +787,7 @@
                    label="比例"
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.backgroundSize || 'cover'} onChange={this.changeBackgroundSize}>
                    <Select defaultValue={card.backgroundSize || 'cover'} onChange={(val) => this.changeNormalStyle(val, 'backgroundSize')}>
                      <Option value="100%">100%</Option>
                      <Option value="100% 100%">100% 100%</Option>
                      <Option value="auto 100%">auto 100%</Option>
@@ -744,7 +804,7 @@
                    label="重复"
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.backgroundRepeat || 'no-repeat'} onChange={this.changeBackgroundRepeat}>
                    <Select defaultValue={card.backgroundRepeat || 'no-repeat'} onChange={(val) => this.changeNormalStyle(val, 'backgroundRepeat')}>
                      <Option value="repeat">repeat</Option>
                      <Option value="no-repeat">no-repeat</Option>
                      <Option value="repeat-x">repeat-x</Option>
@@ -758,7 +818,7 @@
                    label="位置"
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.backgroundPosition || 'center'} onChange={this.changeBackgroundPositon}>
                    <Select defaultValue={card.backgroundPosition || 'center'} onChange={(val) => this.changeNormalStyle(val, 'backgroundPosition')}>
                      <Option value="center">center</Option>
                      <Option value="center top">center top</Option>
                      <Option value="center bottom">center bottom</Option>
@@ -832,11 +892,11 @@
                    label={<ColumnWidthOutlined title="边框宽度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    {borposition === 'outer' ? <StyleInput defaultValue={card.borderWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'left' ? <StyleInput defaultValue={card.borderLeftWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'right' ? <StyleInput defaultValue={card.borderRightWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'top' ? <StyleInput defaultValue={card.borderTopWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'bottom' ? <StyleInput defaultValue={card.borderBottomWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'outer' ? <StyleInput defaultValue={card.borderWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'left' ? <StyleInput defaultValue={card.borderLeftWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'right' ? <StyleInput defaultValue={card.borderRightWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'top' ? <StyleInput defaultValue={card.borderTopWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'bottom' ? <StyleInput defaultValue={card.borderBottomWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                  </Form.Item>
                </Col>
                <Col span={24}>
@@ -845,11 +905,11 @@
                    label={<BgColorsOutlined title="边框颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    {borposition === 'outer' ? <ColorSketch value={card.borderColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'left' ? <ColorSketch value={card.borderLeftColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'right' ? <ColorSketch value={card.borderRightColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'top' ? <ColorSketch value={card.borderTopColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'bottom' ? <ColorSketch value={card.borderBottomColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'outer' ? <ColorSketch allowClear={true} value={card.borderColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'left' ? <ColorSketch allowClear={true} value={card.borderLeftColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'right' ? <ColorSketch allowClear={true} value={card.borderRightColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'top' ? <ColorSketch allowClear={true} value={card.borderTopColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'bottom' ? <ColorSketch allowClear={true} value={card.borderBottomColor || ''} onChange={this.changeBorderColor} /> : null}
                  </Form.Item>
                  <Form.Item
                    colon={false}
@@ -876,7 +936,7 @@
                    label={<BgColorsOutlined title="阴影颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <ColorSketch value={card.shadowColor || ''} onChange={this.changeShadowColor} />
                    <ColorSketch allowClear={true} value={card.shadowColor || ''} onChange={this.changeShadowColor} />
                  </Form.Item>
                  <Form.Item
                    colon={false}
@@ -1026,6 +1086,7 @@
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.clear || 'none'} onChange={(e) => this.changeNormalStyle(e.target.value, 'clear')}>
                      <Radio value="none">左浮动</Radio>
                      <Radio value="left">不浮动</Radio>
                      <Radio value="right">右浮动</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
@@ -1034,7 +1095,7 @@
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<SwapOutlined title="浮动"/>}
                    label={<SwapOutlined title="显示"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.display || 'block'} onChange={(e) => this.changeNormalStyle(e.target.value, 'display')}>
@@ -1044,17 +1105,33 @@
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('overflow') ? <Panel header="溢出" key="overflow">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<EyeOutlined title="溢出"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.overflow || 'hidden'} onChange={(e) => this.changeNormalStyle(e.target.value, 'overflow')}>
                      <Radio value="hidden">隐藏</Radio>
                      <Radio value="visible">显示</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('position') ? <Panel header="定位" key="position">
                <div style={{paddingLeft: '35px', fontSize: '12px'}}>注:定位效果请在运行环境中查看。</div>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<SwapOutlined title="定位"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.position || 'unset'} onChange={(e) => this.changeNormalStyle(e.target.value, 'position')}>
                      <Radio value="unset">无</Radio>
                      <Radio value="relative">相对定位</Radio>
                      <Radio value="absolute">绝对定位</Radio>
                      <Radio value="relative">相对</Radio>
                      <Radio value="absolute">绝对</Radio>
                      <Radio value="fixed">固定</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
@@ -1062,7 +1139,7 @@
                  <Form.Item
                    colon={false}
                    label={<ArrowUpOutlined title="上"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.top || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'top')}/>
                  </Form.Item>
@@ -1071,7 +1148,7 @@
                  <Form.Item
                    colon={false}
                    label={<ArrowDownOutlined title="下"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.bottom || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'bottom')}/>
                  </Form.Item>
@@ -1080,7 +1157,7 @@
                  <Form.Item
                    colon={false}
                    label={<ArrowLeftOutlined title="左"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.left || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'left')}/>
                  </Form.Item>
@@ -1089,12 +1166,34 @@
                  <Form.Item
                    colon={false}
                    label={<ArrowRightOutlined title="右"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.right || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'right')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('transform') ? <Panel header="位置变换" key="transform">
                <div style={{paddingLeft: '50px', fontSize: '12px'}}>注:变换效果请在运行环境中查看。</div>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<DragOutlined title="变换"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.transform || ''} onChange={(val) => this.changeNormalStyle(val, 'transform')}>
                      <Option value="">无</Option>
                      <Option value="translateY(-50%)">上移50%</Option>
                      <Option value="translateY(50%)">下移50%</Option>
                      <Option value="translateX(-50%)">左移50%</Option>
                      <Option value="translateX(50%)">右移50%</Option>
                      <Option value="translate(-50%, -50%)">左上移50%</Option>
                      <Option value="translate(-50%, 50%)">左下移50%</Option>
                      <Option value="translate(50%, -50%)">右上移50%</Option>
                      <Option value="translate(50%, 50%)">右下移50%</Option>
                    </Select>
                  </Form.Item>
                </Col>
              </Panel> : null}
            </Collapse> : null}
          </Form>
          <div style={{textAlign: 'right', lineHeight: '60px', marginBottom: '30px'}}>