| | |
| | | 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); |
| | |
| | | .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); |
| | | } |
| | |
| | | // 链接颜色 |
| | | .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; |
| | | } |
| | | } |
| | |
| | | .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); |
| | | } |
| | |
| | | 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' |
| | |
| | | |
| | | 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 { |
| | |
| | | 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') { |
| | |
| | | const fields = [] |
| | | |
| | | this.state.formlist.forEach((item, index) => { |
| | | if (item.hidden) return |
| | | if (item.hidden || item.forbid) return |
| | | |
| | | if (item.type === 'text') { // 文本搜索 |
| | | let _rules = [] |
| | |
| | | newcard.Ot = 'requiredSgl' |
| | | newcard.OpenType = 'prompt' |
| | | newcard.icon = '' |
| | | newcard.class = 'default' |
| | | newcard.class = 'primary' |
| | | newcard.intertype = 'system' |
| | | newcard.method = 'POST' |
| | | newcard.execSuccess = 'grid' |
| | |
| | | }] |
| | | }, |
| | | { |
| | | 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: "显示为", |
New file |
| | |
| | | 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 |
| | |
| | | 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 }, |
| | |
| | | }) |
| | | |
| | | 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 = () => { |
| | |
| | | <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}> |
| | |
| | | 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) |
| | |
| | | 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) |
| | |
| | | |
| | | 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> |
| | | ) |
| | | } |
| | |
| | | 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'], |
| | | } |
| | |
| | | ] |
| | | }, |
| | | { |
| | | 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: '正常' }, |
| | | { 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', |
| | |
| | | { 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 |
| | | }, |
| | | ] |
| | | |
| | |
| | | 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 |
| | |
| | | class CardCellComponent extends Component { |
| | | static propTpyes = { |
| | | cards: PropTypes.object, // 菜单配置信息 |
| | | card: PropTypes.object, |
| | | cardCell: PropTypes.object, |
| | | side: PropTypes.string, |
| | | elements: PropTypes.array, // 元素集 |
| | | updateElement: PropTypes.func // 菜单配置更新 |
| | | } |
| | |
| | | formlist: null, // 表单信息 |
| | | elements: null, // 按钮组 |
| | | visible: false, // 模态框控制 |
| | | actvisible: false // 按钮编辑模态框 |
| | | actvisible: false, // 按钮编辑模态框 |
| | | profVisible: false |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | 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() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | 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) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | |
| | | * @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) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | 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) |
| | | }) |
| | | } |
| | | } |
| | |
| | | |
| | | 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 |
| | | }) |
| | | |
| | |
| | | |
| | | 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 |
| | | }) |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @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"> |
| | |
| | | list={elements} |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleElement} |
| | | handleStyle={this.handleStyle} |
| | | profileAction={this.profileAction} |
| | | deleteMenu={this.deleteElement} |
| | | /> |
| | | {/* 编辑按钮:复制、编辑 */} |
| | |
| | | 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> |
| | | ) |
| | | } |
| | |
| | | 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; |
| | | } |
| | |
| | | newcard.Ot = 'requiredSgl' |
| | | newcard.OpenType = 'prompt' |
| | | newcard.icon = '' |
| | | newcard.class = 'default' |
| | | newcard.class = 'primary' |
| | | newcard.intertype = 'system' |
| | | newcard.method = 'POST' |
| | | newcard.execSuccess = 'grid' |
| | |
| | | _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) |
| | |
| | | |
| | | 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"> |
| | |
| | | <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" /> |
| | |
| | | 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: [] |
| | |
| | | background-size: cover; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | min-height: 50px; |
| | | min-height: 100px; |
| | | |
| | | .card-control { |
| | | position: absolute; |
| | |
| | | .anticon-tool { |
| | | right: auto; |
| | | left: 1px; |
| | | padding: 1px; |
| | | } |
| | | } |
| | | .anticon-tool { |
| | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | sourcelist: [], |
| | | mainSearch: [], |
| | | visible: false, |
| | | loading: false, |
| | | setting: null |
| | |
| | | |
| | | editDataSource = () => { |
| | | this.setState({ |
| | | visible: true |
| | | visible: true, |
| | | mainSearch: [] |
| | | }) |
| | | } |
| | | |
| | |
| | | |
| | | render () { |
| | | const { config, menu } = this.props |
| | | const { visible, dict, loading } = this.state |
| | | const { visible, dict, loading, mainSearch } = this.state |
| | | |
| | | return ( |
| | | <div className="model-datasource"> |
| | |
| | | <VerifyCard |
| | | dict={dict} |
| | | menu={menu} |
| | | mainSearch={mainSearch} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | |
| | | } |
| | | |
| | | 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() |
| | |
| | | } |
| | | |
| | | 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') |
| | | |
| | |
| | | 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') |
| | |
| | | |
| | | 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"> |
| | |
| | | <TabPane tab="自定义脚本" key="scripts"> |
| | | <CustomScriptsForm |
| | | setting={setting} |
| | | searches={config.search} |
| | | searches={searches} |
| | | initsql={this.state.initsql} |
| | | dict={this.props.dict} |
| | | customScripts={scripts} |
| | |
| | | this.updateStyle({height: _val}) |
| | | } |
| | | |
| | | changeBorderRadius = (val) => { |
| | | this.updateStyle({borderRadius: val}) |
| | | } |
| | | |
| | | changeMarginOrPadding = (val, type) => { |
| | | changeNormalStyle = (val, type) => { |
| | | this.updateStyle({[type]: val}) |
| | | } |
| | | |
| | |
| | | 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} |
| | |
| | | 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}> |
| | |
| | | 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}> |
| | |
| | | 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}> |
| | |
| | | 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} |
| | |
| | | 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}> |
| | |
| | | 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}> |
| | |
| | | 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}> |
| | |
| | | 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} |
New file |
| | |
| | | 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 |
New file |
| | |
| | | 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 |
New file |
| | |
| | | .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; |
| | | } |
| | | } |
New file |
| | |
| | | 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> |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | 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 |
New file |
| | |
| | | .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; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, // 字典 |
| | | config: true, // 图表配置信息 |
| | | config: null, // 图表配置信息 |
| | | empty: true, // 图表数据为空 |
| | | loading: false, // 数据加载状态 |
| | | chartId: Utils.getuuid(), // 图表Id |
| | |
| | | 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> |
| | |
| | | // 通用组件 |
| | | 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 = { |
| | |
| | | <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 |
| | | } |
| | |
| | | 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" |
| | |
| | | padding-top: 30px; |
| | | } |
| | | |
| | | .ant-col { |
| | | padding-bottom: 16px; |
| | | } |
| | | |
| | | .ant-modal-mask { |
| | | position: absolute; |
| | | } |
| | |
| | | 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'}, |