From 5902ba5c3ff85efc78c95364196cd6ab5d2d1601 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期日, 11 十月 2020 12:21:17 +0800
Subject: [PATCH] 2020-10-11

---
 src/tabviews/custom/components/chart/antv-bar-line/index.jsx           |    4 
 src/tabviews/custom/components/card/cardItem/index.scss                |    0 
 src/menu/actioncomponent/formconfig.jsx                                |   12 
 src/menu/components/card/cardcellcomponent/index.scss                  |   15 
 src/tabviews/custom/components/card/cardItem/index.jsx                 |   59 +++
 src/menu/actioncomponent/actionform/index.jsx                          |   24 
 src/menu/actioncomponent/dragaction/index.jsx                          |    2 
 src/menu/components/card/cardcellcomponent/dragaction/action.jsx       |   78 ++++
 src/menu/components/card/cardcellcomponent/dragaction/index.jsx        |   57 ++
 src/menu/components/card/cardcellcomponent/elementform/index.jsx       |    8 
 src/menu/datasource/index.jsx                                          |    7 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx         |   17 
 src/menu/components/card/data-card/index.scss                          |    3 
 src/tabviews/custom/components/card/data-card/asyncButtonComponent.jsx |   34 +
 src/tabviews/custom/index.scss                                         |    4 
 src/tabviews/custom/components/card/data-card/index.scss               |   38 ++
 src/menu/datasource/verifycard/index.jsx                               |   17 
 src/tabviews/custom/components/card/data-card/index.jsx                |  118 ++++++
 src/tabviews/custom/components/card/cardcellList/index.jsx             |  125 ++++++
 src/assets/css/action.scss                                             |   19 +
 src/menu/components/card/cardcellcomponent/index.jsx                   |  237 ++++++++++++
 src/menu/stylecontroller/index.jsx                                     |   39 +
 src/menu/components/card/cardcomponent/index.jsx                       |    8 
 src/menu/components/card/data-card/index.jsx                           |    2 
 src/menu/components/card/cardcellcomponent/formconfig.jsx              |   53 --
 src/tabviews/custom/index.jsx                                          |   13 
 src/tabviews/custom/components/card/cardcellList/index.scss            |   40 ++
 src/utils/option.js                                                    |   30 +
 28 files changed, 916 insertions(+), 147 deletions(-)

diff --git a/src/assets/css/action.scss b/src/assets/css/action.scss
index 20d7c02..f5f5a7d 100644
--- a/src/assets/css/action.scss
+++ b/src/assets/css/action.scss
@@ -16,6 +16,13 @@
     border-color: #1890ff;
   }
 
+  // 闈掕壊
+  .mk-cyan, .mk-cyan:hover, .mk-cyan:active, .mk-cyan:focus {
+    color: #fff;
+    background-color: #13c2c2;
+    border-color: #13c2c2;
+  }
+
   // 榛樿涓庤櫄绾�
   .mk-default, .mk-default:hover, .mk-default:active, .mk-default:focus {
     color: rgba(0, 0, 0, 0.65);
@@ -137,6 +144,9 @@
   .mk-icon.mk-primary, .mk-icon.mk-border-primary {
     color: #1890ff;
   }
+  .mk-icon.mk-cyan {
+    color: #13c2c2;
+  }
   .mk-icon.mk-default, .mk-icon.mk-dashed {
     color: rgba(0, 0, 0, 0.65);
   }
@@ -162,7 +172,13 @@
   // 閾炬帴棰滆壊
   .mk-link, .mk-link:hover, .mk-link:active, .mk-link:focus {
     background: transparent;
+    border-color: transparent;
+    line-height: 1.5;
     .anticon {
+      margin-left: 0px;
+      line-height: inherit;
+    }
+    span + .anticon {
       margin-left: 5px;
     }
   }
@@ -172,6 +188,9 @@
   .mk-link.mk-primary, .mk-link.mk-border-primary {
     color: #1890ff;
   }
+  .mk-link.mk-cyan {
+    color: #13c2c2;
+  }
   .mk-link.mk-default, .mk-link.mk-dashed {
     color: rgba(0, 0, 0, 0.65);
   }
diff --git a/src/menu/actioncomponent/actionform/index.jsx b/src/menu/actioncomponent/actionform/index.jsx
index afda12b..45f53e9 100644
--- a/src/menu/actioncomponent/actionform/index.jsx
+++ b/src/menu/actioncomponent/actionform/index.jsx
@@ -2,7 +2,7 @@
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
 import { Form, Row, Col, Input, Select, Icon, Radio, notification, Tooltip, InputNumber, Cascader } from 'antd'
-import { btnIcons, btnClasses, formRule } from '@/utils/option.js'
+import { btnIcons, btnCustomClasses, formRule } from '@/utils/option.js'
 
 import Api from '@/api'
 import options from '@/store/options.js'
@@ -10,15 +10,15 @@
 
 const { TextArea } = Input
 const actionTypeOptions = {
-  pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent'],
-  prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent'],
-  exec: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent'],
-  excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'icon', 'class', 'sheet', 'execSuccess', 'execError', 'syncComponent'],
-  excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'execSuccess', 'execError', 'pagination', 'search'],
-  popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'popClose'],
-  tab: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'linkmenu'],
-  innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'icon', 'class'],
-  funcbutton: ['label', 'OpenType', 'funcType', 'show', 'icon', 'class']
+  pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent', 'width'],
+  prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent', 'width'],
+  exec: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'icon', 'class', 'execSuccess', 'execError', 'syncComponent', 'width'],
+  excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'icon', 'class', 'sheet', 'execSuccess', 'execError', 'syncComponent', 'width'],
+  excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'execSuccess', 'execError', 'pagination', 'search', 'width'],
+  popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'popClose', 'width'],
+  tab: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'linkmenu', 'width'],
+  innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'icon', 'class', 'width'],
+  funcbutton: ['label', 'OpenType', 'funcType', 'show', 'icon', 'class', 'width']
 }
 
 class MainSearch extends Component {
@@ -98,7 +98,7 @@
       funcType: _funcType,
       formlist: this.props.formlist.map(item => {
         if (item.key === 'class') {
-          item.options = btnClasses
+          item.options = btnCustomClasses
         } else if (item.key === 'icon') {
           item.options = btnIcons
         } else if (item.key === 'Ot') {
@@ -385,7 +385,7 @@
     const fields = []
 
     this.state.formlist.forEach((item, index) => {
-      if (item.hidden) return
+      if (item.hidden || item.forbid) return
 
       if (item.type === 'text') { // 鏂囨湰鎼滅储
         let _rules = []
diff --git a/src/menu/actioncomponent/dragaction/index.jsx b/src/menu/actioncomponent/dragaction/index.jsx
index 0f4bc9e..f563e5a 100644
--- a/src/menu/actioncomponent/dragaction/index.jsx
+++ b/src/menu/actioncomponent/dragaction/index.jsx
@@ -102,7 +102,7 @@
     newcard.Ot = 'requiredSgl'
     newcard.OpenType = 'prompt'
     newcard.icon = ''
-    newcard.class = 'default'
+    newcard.class = 'primary'
     newcard.intertype = 'system'
     newcard.method = 'POST'
     newcard.execSuccess = 'grid'
diff --git a/src/menu/actioncomponent/formconfig.jsx b/src/menu/actioncomponent/formconfig.jsx
index 6d01bd1..1e55179 100644
--- a/src/menu/actioncomponent/formconfig.jsx
+++ b/src/menu/actioncomponent/formconfig.jsx
@@ -292,6 +292,18 @@
       }]
     },
     {
+      type: 'number',
+      key: 'width',
+      min: 1,
+      max: 24,
+      precision: 0,
+      label: '瀹藉害',
+      initVal: card.width || 12,
+      tooltip: '姣忚绛夊垎涓�24浠姐��',
+      forbid: type !== 'card',
+      required: true
+    },
+    {
       type: 'select',
       key: 'show',
       label: "鏄剧ず涓�",
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
new file mode 100644
index 0000000..3568be8
--- /dev/null
+++ b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
@@ -0,0 +1,78 @@
+import React from 'react'
+import { useDrag, useDrop } from 'react-dnd'
+import { Icon, Popover, Button } from 'antd'
+import './index.scss'
+
+const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, profileCard, changeStyle }) => {
+  const originalIndex = findCard(id).index
+  const [{ isDragging }, drag] = useDrag({
+    item: { type: 'action', id, originalIndex },
+    collect: monitor => ({
+      isDragging: monitor.isDragging(),
+    }),
+  })
+  const [, drop] = useDrop({
+    accept: 'action',
+    canDrop: () => true,
+    drop({ id: draggedId }) {
+      if (!draggedId) return
+      if (!cardIds.includes(draggedId)) return
+
+      if (draggedId !== id) {
+        const { index: overIndex } = findCard(id)
+        moveCard(draggedId, overIndex)
+      }
+    },
+  })
+
+  let _style = {opacity: isDragging ? 0 : 1}
+
+  if (card.style) {
+    _style = {...card.style, opacity: isDragging ? 0 : 1}
+  }
+
+  let hasProfile = false
+  if (['pop', 'prompt', 'exec'].includes(card.OpenType)) {
+    hasProfile = true
+  } else if (card.OpenType === 'excelIn' || card.OpenType === 'excelOut') {
+    hasProfile = true
+  } else if (card.funcType === 'print') {
+    hasProfile = true
+  }
+
+  let btnElement = null
+  if (card.show === 'icon') {
+    btnElement = (card.icon ? <Button className={'mk-link mk-' + card.class} style={card.btnstyle} type="link"><Icon type={card.icon}/></Button> : null)
+  } else if (card.show === 'link') {
+    btnElement = (
+      <Button className={'mk-link mk-' + card.class} style={card.btnstyle} type="link">{card.label}{card.icon ? <Icon type={card.icon}/> : null}</Button>
+    )
+  } else {
+    btnElement = (
+      <Button
+        className={'mk-btn mk-' + card.class}
+        icon={card.icon}
+        style={card.btnstyle}
+        // onDoubleClick={() => doubleClickCard(id)}
+      >
+        {card.label}
+      </Button>
+    )
+  }
+
+  return (
+    <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+      <div className="mk-popover-control">
+        <Icon className="edit" title="edit" type="edit" onClick={() => editCard(id)} />
+        <Icon className="close" title="close" type="close" onClick={() => delCard(id)} />
+        <Icon className="style" title="璋冩暣鏍峰紡" onClick={() => changeStyle(id)} type="font-colors" />
+        {hasProfile ? <Icon className="profile" title="setting" type="profile" onClick={() => profileCard(id)} /> : null}
+      </div>
+    } trigger="hover">
+      <div ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width} style={_style}>
+        {btnElement}
+      </div>
+    </Popover>
+  )
+}
+export default Card
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index a39e9df..3aac343 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -9,7 +9,7 @@
 import demo4 from '@/assets/img/demo4.jpg'
 import demo5 from '@/assets/img/demo5.jpg'
 
-const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard }) => {
+const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, changeStyle }) => {
   const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
     item: { type: 'action', id, originalIndex },
@@ -32,18 +32,9 @@
   })
 
   let _style = {opacity: isDragging ? 0 : 1}
-
-  _style.textAlign = card.align
-  _style.color = card.color
   
-  if (card.padding) {
-    _style.padding = card.padding
-  }
-  if (card.fontSize) {
-    _style.fontSize = card.fontSize + 'px'
-  }
-  if (card.fontWeight) {
-    _style.fontWeight = card.fontWeight
+  if (card.style) {
+    _style = {...card.style, opacity: isDragging ? 0 : 1}
   }
 
   const getContent = () => {
@@ -102,7 +93,7 @@
       <div className="mk-popover-control">
         <Icon className="edit" title="edit" type="edit" onClick={() => editCard(id)} />
         <Icon className="close" title="close" type="close" onClick={() => delCard(id)} />
-        {/* <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" /> */}
+        <Icon className="style" title="璋冩暣鏍峰紡" onClick={() => changeStyle(id)} type="font-colors" />
       </div>
     } trigger="hover">
       <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width} style={_style}>
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
index 313a8af..88955b9 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -4,9 +4,10 @@
 import update from 'immutability-helper'
 
 import Card from './card'
+import Action from './action'
 import './index.scss'
 
-const Container = ({list, handleList, handleMenu, deleteMenu }) => {
+const Container = ({list, handleList, handleMenu, deleteMenu, profileAction, handleStyle }) => {
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -31,6 +32,16 @@
     handleMenu(card)
   }
 
+  const changeStyle = id => {
+    const { card } = findCard(id)
+    handleStyle(card)
+  }
+
+  const profileCard = id => {
+    const { card } = findCard(id)
+    profileAction(card)
+  }
+
   const delCard = id => {
     const { card } = findCard(id)
     deleteMenu(card)
@@ -45,18 +56,38 @@
 
   return (
     <div ref={drop} className="ant-row card-detail-row">
-      {cards.map(card => (
-        <Card
-          id={card.uuid}
-          key={card.uuid}
-          cardIds={cardIds}
-          card={card}
-          moveCard={moveCard}
-          editCard={editCard}
-          delCard={delCard}
-          findCard={findCard}
-        />
-      ))}
+      {cards.map(card => {
+        if (card.eleType === 'button') {
+          return (
+            <Action
+              id={card.uuid}
+              key={card.uuid}
+              cardIds={cardIds}
+              card={card}
+              moveCard={moveCard}
+              editCard={editCard}
+              changeStyle={changeStyle}
+              profileCard={profileCard}
+              delCard={delCard}
+              findCard={findCard}
+            />
+          )
+        } else {
+          return (
+            <Card
+              id={card.uuid}
+              key={card.uuid}
+              cardIds={cardIds}
+              card={card}
+              moveCard={moveCard}
+              editCard={editCard}
+              changeStyle={changeStyle}
+              delCard={delCard}
+              findCard={findCard}
+            />
+          )
+        }
+      })}
     </div>
   )
 }
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index ea5a9c6..8f9719d 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -9,11 +9,11 @@
 import './index.scss'
 
 const cardTypeOptions = {
-  text: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'color', 'align', 'padding', 'prefix', 'postfix'],
-  number: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'color', 'align', 'padding', 'prefix', 'postfix'],
+  text: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'align', 'padding', 'prefix', 'postfix'],
+  number: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'align', 'padding', 'prefix', 'postfix'],
   picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'radius', 'padding', 'url'],
-  icon: ['eleType', 'icon', 'fontSize', 'width', 'height', 'color', 'align', 'padding', 'tooltip'],
-  link: ['eleType', 'datatype', 'value', 'labelfield', 'fontSize', 'width', 'height', 'color', 'align', 'padding', 'prefix'],
+  icon: ['eleType', 'icon', 'fontSize', 'width', 'height', 'align', 'padding', 'tooltip'],
+  link: ['eleType', 'datatype', 'value', 'labelfield', 'fontSize', 'width', 'height', 'align', 'padding', 'prefix'],
   slider: ['eleType', 'field', 'width', 'color', 'padding', 'maxValue'],
   splitline: ['eleType', 'color', 'width', 'padding'],
 }
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 082a0c0..81020a7 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -148,54 +148,11 @@
       ]
     },
     {
-      type: 'radio',
-      key: 'align',
-      label: '瀵归綈鏂瑰紡',
-      initVal: card.align || 'left',
-      required: true,
-      options: [
-        { value: 'left', text: '宸﹀榻�' },
-        { value: 'center', text: '灞呬腑' },
-        { value: 'right', text: '鍙冲榻�' },
-      ]
-    },
-    {
-      type: 'number',
-      key: 'fontSize',
-      min: 12,
-      max: 50,
-      label: '瀛椾綋澶у皬',
-      initVal: card.fontSize || 14,
-      required: true,
-    },
-    {
-      type: 'select',
-      key: 'fontWeight',
-      label: '瀛椾綋绮楃粏',
-      initVal: card.fontWeight || 'normal',
-      required: true,
-      options: [
-        { value: 'normal', text: '姝e父' },
-        { value: 'bold', text: 'bold' },
-        { value: 'bolder', text: 'bolder' },
-        { value: 'lighter', text: 'lighter' },
-        { value: '100', text: '100' },
-        { value: '200', text: '200' },
-        { value: '300', text: '300' },
-        { value: '400', text: '400' },
-        { value: '500', text: '500' },
-        { value: '600', text: '600' },
-        { value: '700', text: '700' },
-        { value: '800', text: '800' },
-        { value: '900', text: '900' }
-      ]
-    },
-    {
       type: 'color',
       key: 'color',
       label: '棰滆壊',
       initVal: card.color,
-      required: false
+      required: true
     },
     {
       type: 'number',
@@ -249,14 +206,6 @@
         { value: 'true', text: '鏈�' },
         { value: 'false', text: '鏃�' }
       ]
-    },
-    {
-      type: 'text',
-      key: 'padding',
-      label: '鍐呰竟璺�',
-      initVal: card.padding,
-      tooltip: '鍐呰竟璺濋渶瑕佹寜鐓у浐瀹氭牸寮忓~鍐欙紝渚嬶細5px锛堜笂涓嬪乏鍙冲潎涓�5鍍忕礌锛夛紝5px 10px锛堜笂涓�5鍍忕礌锛屽乏鍙�10鍍忕礌锛夛紝5px 10px 15px锛堜笂5鍍忕礌锛屽乏鍙�10鍍忕礌锛屼笅15鍍忕礌锛夛紝5px 10px 5px 10px锛堜笂5鍍忕礌锛屽彸10鍍忕礌锛屼笅5鍍忕礌锛屽乏10鍍忕礌锛�',
-      required: false
     },
   ]
 
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 50a91b6..3e9eefb 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -16,6 +16,10 @@
 import DragElement from './dragaction'
 import ActionForm from '@/menu/actioncomponent/actionform'
 import CreateFunc from '@/templates/zshare/createfunc'
+import VerifyCard from '@/templates/zshare/verifycard'
+import VerifyPrint from '@/menu/actioncomponent/verifyprint'
+import VerifyExcelIn from '@/menu/actioncomponent/verifyexcelin'
+import VerifyExcelOut from '@/menu/actioncomponent/verifyexcelout'
 import './index.scss'
 
 const { confirm } = Modal
@@ -23,7 +27,8 @@
 class CardCellComponent extends Component {
   static propTpyes = {
     cards: PropTypes.object,         // 鑿滃崟閰嶇疆淇℃伅
-    card: PropTypes.object,
+    cardCell: PropTypes.object,
+    side: PropTypes.string,
     elements: PropTypes.array,       // 鍏冪礌闆�
     updateElement: PropTypes.func    // 鑿滃崟閰嶇疆鏇存柊
   }
@@ -34,7 +39,8 @@
     formlist: null,      // 琛ㄥ崟淇℃伅
     elements: null,      // 鎸夐挳缁�
     visible: false,      // 妯℃�佹鎺у埗
-    actvisible: false    // 鎸夐挳缂栬緫妯℃�佹
+    actvisible: false,   // 鎸夐挳缂栬緫妯℃�佹
+    profVisible: false
   }
 
   /**
@@ -50,10 +56,19 @@
 
   componentDidMount () {
     MKEmitter.addListener('cardAddElement', this.cardAddElement)
+    MKEmitter.addListener('submitStyle', this.getStyle)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.props.cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  UNSAFE_componentWillReceiveProps(nextProps) {
+    if (this.props.side !== nextProps.side) {
+      this.setState({
+        elements: fromJS(nextProps.elements).toJS()
+      })
+    }
   }
 
   /**
@@ -67,17 +82,107 @@
   }
 
   cardAddElement = (ids, element) => {
-    if (!ids || ids.length !== 2 || ids[0] !== this.props.cards.uuid || ids[1] !== this.props.card.uuid) return
+    const { cards, cardCell } = this.props
+
+    if (!ids || ids.length !== 2 || ids[0] !== cards.uuid || ids[1] !== cardCell.uuid) return
 
     const { elements } = this.state
 
     this.setState({elements: [...elements, element]})
 
+    this.handleElement(element)
+  }
+
+  handleStyle = (element) => {
+    const { cards, cardCell } = this.props
+
+    let _style = element.style ? fromJS(element.style).toJS() : {}
+    let options = ['font', 'border', 'padding', 'margin']
+
     if (element.eleType === 'button') {
-      this.handleAction(element)
-    } else {
-      this.handleElement(element)
+      options.push('background')
+      if (element.btnstyle) {
+        _style = {..._style, ...element.btnstyle}
+      }
+    } else if (element.eleType === 'picture') {
+      options = ['border', 'margin']
+    } else if (element.eleType === 'slider') {
+      options = ['padding', 'margin']
+    } else if (element.eleType === 'splitline') {
+      options = ['padding', 'margin']
     }
+
+    this.setState({
+      card: element
+    })
+
+    MKEmitter.emit('changeStyle', [cards.uuid, cardCell.uuid, element.uuid], options, _style)
+  }
+
+  getStyle = (comIds, style) => {
+    const { cards, cardCell } = this.props
+    const { card, elements } = this.state
+
+    if (comIds.length !== 3 || comIds[0] !== cards.uuid || comIds[1] !== cardCell.uuid) return
+
+    let _card = fromJS(card).toJS()
+    
+    if (card.eleType === 'button') { // 鎷嗗垎style
+      let _style = fromJS(style).toJS()
+      _card.style = {}
+
+      if (_style.marginTop) {
+        _card.style.marginTop = _style.marginTop
+        delete _style.marginTop
+      }
+      if (_style.marginBottom) {
+        _card.style.marginBottom = _style.marginBottom
+        delete _style.marginBottom
+      }
+      if (_style.marginLeft) {
+        _card.style.marginLeft = _style.marginLeft
+        delete _style.marginLeft
+      }
+      if (_style.marginRight) {
+        _card.style.marginRight = _style.marginRight
+        delete _style.marginRight
+      }
+      if (_style.paddingTop) {
+        _card.style.paddingTop = _style.paddingTop
+        delete _style.paddingTop
+      }
+      if (_style.paddingBottom) {
+        _card.style.paddingBottom = _style.paddingBottom
+        delete _style.paddingBottom
+      }
+      if (_style.paddingLeft) {
+        _card.style.paddingLeft = _style.paddingLeft
+        delete _style.paddingLeft
+      }
+      if (_style.paddingRight) {
+        _card.style.paddingRight = _style.paddingRight
+        delete _style.paddingRight
+      }
+      if (_style.textAlign) {
+        _card.style.textAlign = _style.textAlign
+        delete _style.textAlign
+      }
+
+      _card.btnstyle = _style
+    } else {
+      _card.style = style
+    }
+
+    let _elements = elements.map(cell => {
+      if (cell.uuid === _card.uuid) return _card
+      return cell
+    })
+
+    this.setState({
+      elements: _elements
+    }, () => {
+      this.props.updateElement(_elements)
+    })
   }
 
   /**
@@ -93,11 +198,15 @@
    * @description 鍏冪礌缂栬緫锛岃幏鍙栧厓绱犺〃鍗曚俊鎭�
    */
   handleElement = (card) => {
-    this.setState({
-      visible: true,
-      card: card,
-      formlist: getCardCellForm(card)
-    })
+    if (card.eleType === 'button') {
+      this.handleAction(card)
+    } else {
+      this.setState({
+        visible: true,
+        card: card,
+        formlist: getCardCellForm(card)
+      })
+    }
   }
 
   /**
@@ -172,14 +281,14 @@
         this.setState({
           actvisible: true,
           card: card,
-          formlist: getActionForm(card, functip, cards.setting, menu.permFuncField, '', menulist, modules)
+          formlist: getActionForm(card, functip, cards.setting, menu.permFuncField, 'card', menulist, modules)
         })
       })
     } else {
       this.setState({
         actvisible: true,
         card: card,
-        formlist: getActionForm(card, functip, cards.setting, menu.permFuncField, '', menulist, modules)
+        formlist: getActionForm(card, functip, cards.setting, menu.permFuncField, 'card', menulist, modules)
       })
     }
   }
@@ -264,7 +373,11 @@
 
     this.elementFormRef.handleConfirm().then(ele => {
       let _elements = elements.map(cell => {
-        if (cell.uuid === ele.uuid) return ele
+        if (cell.uuid === ele.uuid) {
+          ele.style = cell.style || {}
+          ele.btnstyle = cell.btnstyle || {}
+          return ele
+        }
         return cell
       })
 
@@ -285,7 +398,12 @@
 
     this.actionFormRef.handleConfirm().then(ele => {
       let _elements = elements.map(cell => {
-        if (cell.uuid === ele.uuid) return ele
+        if (cell.uuid === ele.uuid) {
+          ele.eleType = 'button'
+          ele.style = cell.style || {}
+          return ele
+        }
+
         return cell
       })
 
@@ -320,9 +438,46 @@
     })
   }
 
+  /**
+   * @description 楠岃瘉淇℃伅閰嶇疆
+   */
+  profileAction = (element) => {
+    this.setState({
+      profVisible: true,
+      card: element
+    })
+  }
+
+  /**
+   * @description 楠岃瘉淇℃伅淇濆瓨
+   */
+  verifySubmit = () => {
+    const { elements } = this.state
+    
+    this.verifyRef.handleConfirm().then(res => {
+      console.log(res)
+      let _elements = elements.map(cell => {
+        if (cell.uuid === res.uuid) {
+          res.eleType = 'button'
+          res.style = cell.style || {}
+          return res
+        }
+
+        return cell
+      })
+
+      this.setState({
+        elements: _elements,
+        actvisible: false
+      }, () => {
+        this.props.updateElement(_elements)
+      })
+    })
+  }
+
   render() {
     const { cards } = this.props
-    const { elements, visible, actvisible, card, dict } = this.state
+    const { elements, visible, actvisible, profVisible, card, dict } = this.state
 
     return (
       <div className="model-menu-card-cell-list">
@@ -330,6 +485,8 @@
           list={elements}
           handleList={this.handleList}
           handleMenu={this.handleElement}
+          handleStyle={this.handleStyle}
+          profileAction={this.profileAction}
           deleteMenu={this.deleteElement}
         />
         {/* 缂栬緫鎸夐挳锛氬鍒躲�佺紪杈� */}
@@ -374,6 +531,54 @@
             wrappedComponentRef={(inst) => this.actionFormRef = inst}
           />
         </Modal>
+        {/* 鎸夐挳浣跨敤绯荤粺瀛樺偍杩囩▼鏃讹紝楠岃瘉淇℃伅妯℃�佹 */}
+        <Modal
+          wrapClassName="model-table-action-verify-modal"
+          title={'楠岃瘉淇℃伅'}
+          visible={profVisible}
+          width={'75vw'}
+          maskClosable={false}
+          style={{minWidth: '900px', maxWidth: '1200px'}}
+          okText={dict['model.submit']}
+          onOk={this.verifySubmit}
+          onCancel={() => { this.setState({ profVisible: false }) }}
+          destroyOnClose
+        >
+          {card && !card.execMode && card.OpenType !== 'excelIn' && card.OpenType !== 'excelOut' ?
+            <VerifyCard
+              // floor={this.props.type}
+              card={card}
+              dict={dict}
+              config={cards}
+              columns={cards.columns}
+              wrappedComponentRef={(inst) => this.verifyRef = inst}
+            /> : null
+          }
+          {card && card.execMode ?
+            <VerifyPrint
+              card={card}
+              dict={dict}
+              columns={cards.columns}
+              wrappedComponentRef={(inst) => this.verifyRef = inst}
+            /> : null
+          }
+          {card && card.OpenType === 'excelIn' ?
+            <VerifyExcelIn
+              card={card}
+              dict={dict}
+              columns={cards.columns}
+              wrappedComponentRef={(inst) => this.verifyRef = inst}
+            /> : null
+          }
+          {card && card.OpenType === 'excelOut' ?
+            <VerifyExcelOut
+              card={card}
+              dict={dict}
+              config={cards}
+              wrappedComponentRef={(inst) => this.verifyRef = inst}
+            /> : null
+          }
+        </Modal>
       </div>
     )
   }
diff --git a/src/menu/components/card/cardcellcomponent/index.scss b/src/menu/components/card/cardcellcomponent/index.scss
index b5adb09..7d08668 100644
--- a/src/menu/components/card/cardcellcomponent/index.scss
+++ b/src/menu/components/card/cardcellcomponent/index.scss
@@ -16,6 +16,21 @@
     cursor: pointer;
   }
 
+  .card-cell {
+    border-style: solid;
+    border-width: 0;
+  }
+  .card-button-cell {
+    float: left;
+    button {
+      background-size: cover;
+      background-position: center center;
+      span {
+        font-style: inherit;
+        text-decoration: inherit;
+      }
+    }
+  }
   .card-cell:hover {
     box-shadow: 0px 0px 1px #d8d8d8;
   }
diff --git a/src/menu/components/card/cardcomponent/index.jsx b/src/menu/components/card/cardcomponent/index.jsx
index 3fa532f..cc22efb 100644
--- a/src/menu/components/card/cardcomponent/index.jsx
+++ b/src/menu/components/card/cardcomponent/index.jsx
@@ -153,7 +153,7 @@
     newcard.Ot = 'requiredSgl'
     newcard.OpenType = 'prompt'
     newcard.icon = ''
-    newcard.class = 'default'
+    newcard.class = 'primary'
     newcard.intertype = 'system'
     newcard.method = 'POST'
     newcard.execSuccess = 'grid'
@@ -177,7 +177,7 @@
       _style = card.style ? fromJS(card.style).toJS() : {}
     } else if (side === 'back') {
       _style = card.backStyle ? fromJS(card.backStyle).toJS() : {}
-      options = ['background', 'border', 'padding', 'margin']
+      options = ['background', 'padding']
     }
 
     MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, _style)
@@ -214,7 +214,7 @@
 
     return (
       <div className={'ant-col card-item ant-col-' + (card.setting.width || 6)} style={_style}>
-        <CardCellComponent cards={cards} card={card} elements={elements} updateElement={this.updateCard}/>
+        <CardCellComponent cards={cards} cardCell={card} side={side} elements={elements} updateElement={this.updateCard}/>
         <div className="card-control">
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control">
@@ -222,8 +222,8 @@
               <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" />
               <Icon className="edit" type="edit" onClick={() => this.setState({settingVisible: true})} />
               <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
-              {card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null}
               <Icon className="close" title="鍒犻櫎鍗$墖" type="delete" onClick={() => this.props.deleteElement(card)} />
+              {card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null}
             </div>
           } trigger="hover">
             <Icon type="tool" />
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index fb12bfa..0069951 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -68,7 +68,7 @@
         subcards: [{
           uuid: Utils.getuuid(),
           setting: { width: 6, type: 'simple'},
-          style: {borderWidth: '1px', borderColor: '#e8e8e8'},
+          style: {borderWidth: '1px', borderColor: '#e8e8e8', paddingTop: '15px', paddingBottom: '15px', paddingLeft: '15px', paddingRight: '15px'},
           backStyle: {},
           elements: [],
           backElements: []
diff --git a/src/menu/components/card/data-card/index.scss b/src/menu/components/card/data-card/index.scss
index af06905..e6cfc02 100644
--- a/src/menu/components/card/data-card/index.scss
+++ b/src/menu/components/card/data-card/index.scss
@@ -7,7 +7,7 @@
   background-size: cover;
   border-style: solid;
   border-width: 0;
-  min-height: 50px;
+  min-height: 100px;
   
   .card-control {
     position: absolute;
@@ -16,6 +16,7 @@
     .anticon-tool {
       right: auto;
       left: 1px;
+      padding: 1px;
     }
   }
   .anticon-tool {
diff --git a/src/menu/datasource/index.jsx b/src/menu/datasource/index.jsx
index bead534..5520997 100644
--- a/src/menu/datasource/index.jsx
+++ b/src/menu/datasource/index.jsx
@@ -18,6 +18,7 @@
   state = {
     dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     sourcelist: [],
+    mainSearch: [],
     visible: false,
     loading: false,
     setting: null
@@ -35,7 +36,8 @@
 
   editDataSource = () => {
     this.setState({
-      visible: true
+      visible: true,
+      mainSearch: []
     })
   }
 
@@ -54,7 +56,7 @@
 
   render () {
     const { config, menu } = this.props
-    const { visible, dict, loading } = this.state
+    const { visible, dict, loading, mainSearch } = this.state
 
     return (
       <div className="model-datasource">
@@ -75,6 +77,7 @@
           <VerifyCard
             dict={dict}
             menu={menu}
+            mainSearch={mainSearch}
             config={config}
             wrappedComponentRef={(inst) => this.verifyRef = inst}
           />
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index 99a1ff7..e1b3e56 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -122,12 +122,16 @@
   }
 
   UNSAFE_componentWillMount() {
-    const { config } = this.props
+    const { config, mainSearch } = this.props
+
+    let search = config.search || []
+    search = [...search, ...mainSearch]
 
     this.setState({
       columns: fromJS(config.columns).toJS(),
       setting: fromJS(config.setting).toJS(),
-      scripts: fromJS(config.scripts).toJS()
+      scripts: fromJS(config.scripts).toJS(),
+      searches: search
     })
 
     this.getsysScript()
@@ -410,8 +414,7 @@
   }
 
   sqlverify = (resolve, reject, change = false, testScripts) => {
-    const { config } = this.props
-    const { columns, setting, scripts } = this.state
+    const { columns, setting, scripts, searches } = this.state
 
     let _scripts = scripts.filter(item => item.status !== 'false')
 
@@ -431,7 +434,7 @@
     if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) {
       let param = {
         func: 's_debug_sql',
-        LText: SettingUtils.getDebugSql(setting, _scripts, columns, config.search)
+        LText: SettingUtils.getDebugSql(setting, _scripts, columns, searches)
       }
       param.LText = Utils.formatOptions(param.LText)
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -469,7 +472,7 @@
 
   render() {
     const { menu, config } = this.props
-    const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading } = this.state
+    const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches } = this.state
 
     return (
       <div id="model-verify-card-box-tab">
@@ -510,7 +513,7 @@
           <TabPane tab="鑷畾涔夎剼鏈�" key="scripts">
             <CustomScriptsForm
               setting={setting}
-              searches={config.search}
+              searches={searches}
               initsql={this.state.initsql}
               dict={this.props.dict}
               customScripts={scripts}
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index 82faa61..2e80909 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -260,11 +260,7 @@
     this.updateStyle({height: _val})
   }
 
-  changeBorderRadius = (val) => {
-    this.updateStyle({borderRadius: val})
-  }
-
-  changeMarginOrPadding = (val, type) => {
+  changeNormalStyle = (val, type) => {
     this.updateStyle({[type]: val})
   }
 
@@ -502,7 +498,7 @@
                     label={<Icon title="鍦嗚" type="radius-setting" />}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.borderRadius || ''} options={['px', '%']} onChange={this.changeBorderRadius}/>
+                    <StyleInput defaultValue={card.borderRadius || ''} options={['px', '%']} onChange={(val) => this.changeNormalStyle(val, 'borderRadius')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -512,7 +508,7 @@
                     colon={false}
                     label={<Icon title="涓婅竟璺�" type="arrow-up"/>}
                   >
-                    <StyleInput defaultValue={card.marginTop} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginTop')}/>
+                    <StyleInput defaultValue={card.marginTop} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginTop')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -520,7 +516,7 @@
                     colon={false}
                     label={<Icon title="涓嬭竟璺�" type="arrow-down"/>}
                   >
-                    <StyleInput defaultValue={card.marginBottom} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginBottom')}/>
+                    <StyleInput defaultValue={card.marginBottom} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginBottom')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -528,7 +524,7 @@
                     colon={false}
                     label={<Icon title="宸﹁竟璺�" type="arrow-left"/>}
                   >
-                    <StyleInput defaultValue={card.marginLeft} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginLeft')}/>
+                    <StyleInput defaultValue={card.marginLeft} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginLeft')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -536,7 +532,7 @@
                     colon={false}
                     label={<Icon title="鍙宠竟璺�" type="arrow-right"/>}
                   >
-                    <StyleInput defaultValue={card.marginRight} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginRight')}/>
+                    <StyleInput defaultValue={card.marginRight} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginRight')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -546,7 +542,7 @@
                     colon={false}
                     label={<Icon title="涓婅竟璺�" type="arrow-up"/>}
                   >
-                    <StyleInput defaultValue={card.paddingTop} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingTop')}/>
+                    <StyleInput defaultValue={card.paddingTop} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingTop')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -554,7 +550,7 @@
                     colon={false}
                     label={<Icon title="涓嬭竟璺�" type="arrow-down"/>}
                   >
-                    <StyleInput defaultValue={card.paddingBottom} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingBottom')}/>
+                    <StyleInput defaultValue={card.paddingBottom} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingBottom')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -562,7 +558,7 @@
                     colon={false}
                     label={<Icon title="宸﹁竟璺�" type="arrow-left"/>}
                   >
-                    <StyleInput defaultValue={card.paddingLeft} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingLeft')}/>
+                    <StyleInput defaultValue={card.paddingLeft} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingLeft')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -570,7 +566,22 @@
                     colon={false}
                     label={<Icon title="鍙宠竟璺�" type="arrow-right"/>}
                   >
-                    <StyleInput defaultValue={card.paddingRight} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingRight')}/>
+                    <StyleInput defaultValue={card.paddingRight} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingRight')}/>
+                  </Form.Item>
+                </Col>
+              </Panel> : null}
+              {options.includes('float') ? <Panel header="娴姩" key="float">
+                <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<Icon title="娴姩" type="swap" />}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <Radio.Group defaultValue={card.float || 'left'} onChange={(e) => this.changeNormalStyle(e.target.value, 'float')}>
+                      <Radio value="left">宸︽诞鍔�</Radio>
+                      <Radio value="right">鍙虫诞鍔�</Radio>
+                      <Radio value="none">涓嶆诞鍔�</Radio>
+                    </Radio.Group>
                   </Form.Item>
                 </Col>
               </Panel> : null}
diff --git a/src/tabviews/custom/components/card/cardItem/index.jsx b/src/tabviews/custom/components/card/cardItem/index.jsx
new file mode 100644
index 0000000..25eb2cd
--- /dev/null
+++ b/src/tabviews/custom/components/card/cardItem/index.jsx
@@ -0,0 +1,59 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Col } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+
+import './index.scss'
+
+const CardCellComponent = asyncComponent(() => import('../cardcellList'))
+
+class CardBoxComponent extends Component {
+  static propTpyes = {
+    cards: PropTypes.object,         // 鍗$墖琛岄厤缃俊鎭�
+    card: PropTypes.object,          // 鍗$墖閰嶇疆淇℃伅
+    data: PropTypes.object
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    card: null,            // 鍗$墖淇℃伅锛屽寘鎷鍙嶉潰
+  }
+
+  /**
+   * @description 鎼滅储鏉′欢鍒濆鍖�
+   */
+  UNSAFE_componentWillMount () {
+
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  render() {
+    const { card } = this.props
+
+    return (
+      <Col span={card.setting.width || 6}>
+        <div className={'card-item'} style={card.style}>
+          <CardCellComponent elements={card.elements} updateElement={this.updateCard}/>
+        </div>
+      </Col>
+    )
+  }
+}
+
+export default CardBoxComponent
\ No newline at end of file
diff --git a/src/tabviews/custom/components/card/cardItem/index.scss b/src/tabviews/custom/components/card/cardItem/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/tabviews/custom/components/card/cardItem/index.scss
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
new file mode 100644
index 0000000..dbab48a
--- /dev/null
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -0,0 +1,125 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Button, Icon } from 'antd'
+
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+
+import './index.scss'
+
+class CardCellComponent extends Component {
+  static propTpyes = {
+    cards: PropTypes.object,         // 鑿滃崟閰嶇疆淇℃伅
+    cardCell: PropTypes.object,
+    elements: PropTypes.array,       // 鍏冪礌闆�
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    card: null,          // 缂栬緫涓厓绱�
+    elements: null,      // 鎸夐挳缁�
+  }
+
+  /**
+   * @description 鎼滅储鏉′欢鍒濆鍖�
+   */
+  UNSAFE_componentWillMount () {
+    const { elements } = this.props
+
+    this.setState({
+      elements: fromJS(elements).toJS()
+    })
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  getContent = (card) => {
+    if (card.eleType === 'text' || card.eleType === 'number') {
+      let val = `${card.prefix || ''}${card.value || ''}${card.postfix || ''}`
+      return <span key={card.uuid}>{val}</span>
+    } else if (card.eleType === 'icon') {
+      return (<Icon key={card.uuid} type={card.icon}/>)
+    } else if (card.eleType === 'slider') {
+      return (
+        <div className="ant-mk-slider" key={card.uuid}>
+          <div className="ant-mk-slider-rail"></div>
+          <div className="ant-mk-slider-track" style={{width: '30%', backgroundColor: card.color}}></div>
+          <div className="ant-mk-slider-handle" style={{left: '30%', borderColor: card.color}}></div>
+        </div>
+      )
+    } else if (card.eleType === 'picture') {
+      let _imagestyle = {}
+
+      if (card.url) {
+        _imagestyle = {backgroundImage: `url('${card.url}')`}
+      } else {
+        _imagestyle = {backgroundImage: `url('')`}
+      }
+
+      if (card.radius === 'true') {
+        _imagestyle.borderRadius = '50%'
+      }
+
+      if (card.lenWidRadio === '16:9') {
+        _imagestyle.paddingTop = '56.25%'
+      } else if (card.lenWidRadio === '3:2') {
+        _imagestyle.paddingTop = '66.67%'
+      } else if (card.lenWidRadio === '4:3') {
+        _imagestyle.paddingTop = '75%'
+      } else {
+        _imagestyle.paddingTop = '100%'
+      }
+
+      return (
+        <div className="ant-mk-picture" key={card.uuid} style={_imagestyle}></div>
+      )
+    } else if (card.eleType === 'splitline') {
+      return (
+        <div className="ant-mk-splitline" key={card.uuid} style={{backgroundColor: card.color}}></div>
+      )
+    } else if (card.eleType === 'button') {
+      if (card.show === 'icon') {
+        return (card.icon ? <Button key={card.uuid} className={'mk-link mk-' + card.class} style={card.btnstyle} type="link"><Icon type={card.icon}/></Button> : null)
+      } else if (card.show === 'link') {
+        return (
+          <Button key={card.uuid} className={'mk-link mk-' + card.class} style={card.btnstyle} type="link">{card.label}{card.icon ? <Icon type={card.icon}/> : null}</Button>
+        )
+      } else {
+        return (
+          <Button
+            key={card.uuid}
+            className={'mk-btn mk-' + card.class}
+            icon={card.icon}
+            style={card.btnstyle}
+          >
+            {card.label}
+          </Button>
+        )
+      }
+    }
+  }
+
+  render() {
+    const { elements } = this.state
+
+    return (
+      <div className="model-menu-card-cell-list">
+        {elements.map(item => this.getContent(item))}
+      </div>
+    )
+  }
+}
+
+export default CardCellComponent
\ No newline at end of file
diff --git a/src/tabviews/custom/components/card/cardcellList/index.scss b/src/tabviews/custom/components/card/cardcellList/index.scss
new file mode 100644
index 0000000..7d08668
--- /dev/null
+++ b/src/tabviews/custom/components/card/cardcellList/index.scss
@@ -0,0 +1,40 @@
+.model-menu-card-cell-list {
+  position: relative;
+  .ant-form-item-label {
+    .anticon-question-circle {
+      color: #c49f47;
+      position: absolute;
+      left: 5px;
+      top: 5px;
+    }
+  }
+
+  .card-detail-row > .anticon-plus {
+    color: #26C281;
+    font-size: 16px;
+    padding: 5px;
+    cursor: pointer;
+  }
+
+  .card-cell {
+    border-style: solid;
+    border-width: 0;
+  }
+  .card-button-cell {
+    float: left;
+    button {
+      background-size: cover;
+      background-position: center center;
+      span {
+        font-style: inherit;
+        text-decoration: inherit;
+      }
+    }
+  }
+  .card-cell:hover {
+    box-shadow: 0px 0px 1px #d8d8d8;
+  }
+  .ant-slider {
+    margin: 0px;
+  }
+}
diff --git a/src/tabviews/custom/components/card/data-card/asyncButtonComponent.jsx b/src/tabviews/custom/components/card/data-card/asyncButtonComponent.jsx
new file mode 100644
index 0000000..5fb9c1a
--- /dev/null
+++ b/src/tabviews/custom/components/card/data-card/asyncButtonComponent.jsx
@@ -0,0 +1,34 @@
+import React, {Component} from 'react'
+import { Button } from 'antd'
+
+/**
+ * @description 寮傛鍔犺浇妯″潡
+ * @param {*} importComponent
+ */
+export default function asyncComponent(importComponent) {
+  return class extends Component {
+    constructor(props) {
+      super(props)
+
+      this.state = {
+        component: null
+      }
+    }
+
+    async componentDidMount() {
+      const {default: component} = await importComponent()
+
+      this.setState({component})
+    }
+
+    // <Button className="loading-skeleton" disabled={true}></Button> // 楠ㄦ灦鎸夐挳
+    render() {
+      const C = this.state.component
+      const btn = this.props.btn || {}
+
+      return C ?
+        <C {...this.props} /> :
+        <Button icon={btn.OpenType === 'excelOut' ? 'download' : 'upload'} disabled={true} title={btn.label} style={{border: 0, background: 'transparent'}}></Button>
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
new file mode 100644
index 0000000..8e459c4
--- /dev/null
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -0,0 +1,118 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Spin, Empty, notification } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import Api from '@/api'
+// import Utils from '@/utils/utils.js'
+import UtilsDM from '@/utils/utils-datamanage.js'
+import zhCN from '@/locales/zh-CN/main.js'
+import enUS from '@/locales/en-US/main.js'
+import './index.scss'
+
+const CardItem = asyncComponent(() => import('../cardItem'))
+
+class DataCard extends Component {
+  static propTpyes = {
+    BID: PropTypes.any,              // 鐖剁骇Id
+    data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
+    config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
+    mainSearch: PropTypes.any,       // 鍏ㄥ眬鎼滅储鏉′欢
+    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
+    dataManager: PropTypes.any,      // 鏁版嵁鏉冮檺
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 瀛楀吀
+    config: null,              // 鍥捐〃閰嶇疆淇℃伅
+    empty: false,
+    loading: false,            // 鏁版嵁鍔犺浇鐘舵��
+    data: null                 // 鏁版嵁
+  }
+
+  UNSAFE_componentWillMount () {
+    let _config = fromJS(this.props.config).toJS()
+    console.log(_config)
+
+    this.setState({
+      config: _config,
+      arr_field: _config.columns.map(col => col.field).join(','),
+    }, () => {
+      this.loadData()
+    })
+  }
+
+  /**
+   * @description 鏍¢獙鍥捐〃鐨勬寜閽粍锛屽鏋滀负缁熻鍥捐〃锛岃绠楀浘琛ㄥ瓧娈�
+   */
+  componentDidMount () {
+
+  }
+
+  /**
+   * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹�
+   */
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  async loadData () {
+    const { mainSearch, BID, menuType, dataManager } = this.props
+    const { config, arr_field } = this.state
+    
+    let searches = []
+    if (mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
+      searches = [...mainSearch, ...searches]
+    }
+
+    this.setState({
+      loading: true
+    })
+
+    let _orderBy = config.setting.order || ''
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, config.setting.pageSize, BID, menuType, dataManager)
+
+    let result = await Api.genericInterface(param)
+    if (result.status) {
+      this.setState({
+        data: result.data,
+        loading: false
+      })
+    } else {
+      this.setState({
+        loading: false
+      })
+      notification.error({
+        top: 92,
+        message: result.message,
+        duration: 10
+      })
+    }
+  }
+
+  render() {
+    const { config, empty, loading, data } = this.state
+
+    return (
+      <div className="custom-card-box" style={config.style}>
+        {loading ?
+          <div className="loading-mask">
+            <div className="ant-spin-blur"></div>
+            <Spin />
+          </div> : null
+        }
+        {data && data.length > 0 ? data.map((item, index) => (
+          <CardItem key={index} card={config.subcards[0]} cards={config} data={item} />
+        )) : null}
+        {empty ? <Empty description={false}/> : null}
+      </div>
+    )
+  }
+}
+
+export default DataCard
\ No newline at end of file
diff --git a/src/tabviews/custom/components/card/data-card/index.scss b/src/tabviews/custom/components/card/data-card/index.scss
new file mode 100644
index 0000000..b8bd982
--- /dev/null
+++ b/src/tabviews/custom/components/card/data-card/index.scss
@@ -0,0 +1,38 @@
+.custom-card-box {
+  background: #ffffff;
+  min-height: 100px;
+
+  .card-item {
+    border-style: solid;
+  }
+
+  .ant-empty {
+    position: absolute;
+    top: calc(50% - 34px);
+    left: calc(50% - 92px);
+
+    .ant-empty-image {
+      height: 60px;
+    }
+  }
+  .loading-mask {
+    position: absolute;
+    left: 20px;
+    top: 0;
+    right: 20px;
+    bottom: 30px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    text-align: justify;
+    z-index: 1;
+
+    .ant-spin-blur {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      opacity: 0.5;
+      background: #ffffff;
+    }
+  }
+}
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
index eaa801d..1ca90a9 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -29,7 +29,7 @@
 
   state = {
     dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 瀛楀吀
-    config: true,              // 鍥捐〃閰嶇疆淇℃伅
+    config: null,              // 鍥捐〃閰嶇疆淇℃伅
     empty: true,               // 鍥捐〃鏁版嵁涓虹┖
     loading: false,            // 鏁版嵁鍔犺浇鐘舵��
     chartId: Utils.getuuid(),  // 鍥捐〃Id
@@ -1026,7 +1026,7 @@
     const { showHeader, config, loading, title, plot, empty, chartFields, selectFields } = this.state
 
     return (
-      <div className="custom-line-chart-plot-box">
+      <div className="custom-line-chart-plot-box" style={config.style}>
         {loading ?
           <div className="loading-mask">
             <div className="ant-spin-blur"></div>
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index d120eff..e361d2b 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -19,6 +19,7 @@
 // 閫氱敤缁勪欢
 const AntvBarAndLine = asyncSpinComponent(() => import('./components/chart/antv-bar-line'))
 const AntvTabs = asyncSpinComponent(() => import('./components/tabs/antv-tabs'))
+const DataCard = asyncSpinComponent(() => import('./components/card/data-card'))
 
 class NormalTable extends Component {
   static propTpyes = {
@@ -450,6 +451,16 @@
             <AntvTabs config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} />
           </Col>
         )
+      } else if (item.type === 'card') {
+        if (item.subtype === 'datacard') {
+          return (
+            <Col span={item.width} key={item.uuid}>
+              <DataCard config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} dataManager={dataManager} />
+            </Col>
+          )
+        } else {
+          return null
+        }
       } else {
         return null
       }
@@ -463,7 +474,7 @@
     return (
       <div className="custom-page-wrap" id={this.state.ContainerId} style={config ? config.style : null}>
         {loadingview && <Spin size="large" />}
-        <Row gutter={8}>{this.getComponents()}</Row>
+        <Row>{this.getComponents()}</Row>
         {options.sysType !== 'cloud' ? <Button
           icon="copy"
           shape="circle"
diff --git a/src/tabviews/custom/index.scss b/src/tabviews/custom/index.scss
index 5094f4d..a5e974e 100644
--- a/src/tabviews/custom/index.scss
+++ b/src/tabviews/custom/index.scss
@@ -12,10 +12,6 @@
     padding-top: 30px;
   }
 
-  .ant-col {
-    padding-bottom: 16px;
-  }
-
   .ant-modal-mask {
     position: absolute;
   }
diff --git a/src/utils/option.js b/src/utils/option.js
index fbdaff3..1e17c21 100644
--- a/src/utils/option.js
+++ b/src/utils/option.js
@@ -329,6 +329,36 @@
   text: '鐧藉簳绱'
 }]
 
+// 鎸夐挳棰滆壊闆�
+export const btnCustomClasses = [{
+  value: 'primary',
+  text: '钃濊壊'
+}, {
+  value: 'yellow',
+  text: '榛勮壊'
+}, {
+  value: 'orange',
+  text: '姗欒壊'
+}, {
+  value: 'danger',
+  text: '绾㈣壊'
+}, {
+  value: 'green',
+  text: '缁胯壊'
+}, {
+  value: 'dgreen',
+  text: '娣辩豢鑹�'
+}, {
+  value: 'purple',
+  text: '绱壊'
+}, {
+  value: 'cyan',
+  text: '闈掕壊'
+}, {
+  value: 'gray',
+  text: '鐏拌壊'
+}]
+
 export const calendarColors = [
   {name: 'red', value: '#d0021b'},
   {name: 'orange', value: '#f5a623'},

--
Gitblit v1.8.0