| | |
| | | .barcode-box { |
| | | display: inline-block; |
| | | overflow-y: hidden; |
| | | height: 100%; |
| | | float: left; |
| | | svg { |
| | | vertical-align: top; |
| | | } |
| | |
| | | import { Icon, Button, Popover } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const Card = ({ id, card, moveCard, findCard, editCard, delCard, copyCard, profileCard, doubleClickCard }) => { |
| | | const Card = ({ id, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle, profileCard, doubleClickCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'action', id, originalIndex }, |
| | |
| | | btnElement = ( |
| | | <Button |
| | | type="link" |
| | | className={'mk-icon mk-' + card.class} |
| | | icon={card.icon} |
| | | style={card.btnstyle} |
| | | onDoubleClick={() => doubleClickCard(id)} |
| | | >{card.icon ? '' : card.label}</Button> |
| | | ) |
| | |
| | | btnElement = ( |
| | | <Button |
| | | type="link" |
| | | className={'mk-link mk-' + card.class} |
| | | style={card.btnstyle} |
| | | onDoubleClick={() => doubleClickCard(id)} |
| | | >{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} |
| | |
| | | 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="copy" title="copy" type="copy" onClick={() => copyCard(id)} /> |
| | | <Icon className="close" title="close" type="close" onClick={() => delCard(id)} /> |
| | | {hasProfile ? <Icon className="profile" title="setting" type="profile" onClick={() => profileCard(id)} /> : null} |
| | | <Icon className="edit" title="编辑" type="edit" onClick={() => editCard(id)} /> |
| | | <Icon className="copy" title="复制" type="copy" onClick={() => copyCard(id)} /> |
| | | <Icon className="close" title="删除" type="close" onClick={() => delCard(id)} /> |
| | | <Icon className="style" title="调整样式" onClick={() => changeStyle(id)} type="font-colors" /> |
| | | {hasProfile ? <Icon className="profile" title="验证" type="profile" onClick={() => profileCard(id)} /> : null} |
| | | </div> |
| | | } trigger="hover"> |
| | | <div className="page-card" style={{ opacity: opacity}}> |
| | |
| | | import Card from './card' |
| | | import './index.scss' |
| | | |
| | | const Container = ({list, handleList, handleMenu, deleteMenu, profileMenu, doubleClickCard }) => { |
| | | const Container = ({list, handleList, handleMenu, deleteMenu, profileMenu, changeBtnStyle, dropButton, doubleClickCard }) => { |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | |
| | | const profileCard = id => { |
| | | const { card } = findCard(id) |
| | | profileMenu(card) |
| | | } |
| | | |
| | | const changeStyle = id => { |
| | | const { card } = findCard(id) |
| | | changeBtnStyle(card) |
| | | } |
| | | |
| | | const delCard = id => { |
| | |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'action', |
| | | drop() {} |
| | | drop(item) { |
| | | const { index } = findCard(item.id) |
| | | if (index > -1) return |
| | | dropButton(item.id) |
| | | } |
| | | }) |
| | | |
| | | return ( |
| | |
| | | editCard={editCard} |
| | | delCard={delCard} |
| | | findCard={findCard} |
| | | changeStyle={changeStyle} |
| | | profileCard={profileCard} |
| | | doubleClickCard={doubleClickBtn} |
| | | /> |
| | |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('addButton', this.addButton) |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | /** |
| | |
| | | return |
| | | } |
| | | MKEmitter.removeListener('addButton', this.addButton) |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { config } = this.props |
| | | const { card, actionlist } = this.state |
| | | |
| | | if (comIds.length !== 2 || comIds[0] !== config.uuid) return |
| | | |
| | | let _card = fromJS(card).toJS() |
| | | _card.btnstyle = style |
| | | |
| | | let _actionlist = actionlist.map(cell => { |
| | | if (cell.uuid === _card.uuid) return _card |
| | | return cell |
| | | }) |
| | | |
| | | this.setState({ |
| | | actionlist: _actionlist |
| | | }, () => { |
| | | this.props.updateaction({...config, action: _actionlist}) |
| | | }) |
| | | } |
| | | |
| | | changeBtnStyle = (element) => { |
| | | const { config } = this.props |
| | | |
| | | let _style = element.btnstyle ? fromJS(element.btnstyle).toJS() : {} |
| | | let options = ['font', 'border', 'background'] |
| | | |
| | | this.setState({ |
| | | card: element |
| | | }) |
| | | |
| | | MKEmitter.emit('changeStyle', [config.uuid, element.uuid], options, _style) |
| | | } |
| | | |
| | | addButton = (cardId, element) => { |
| | |
| | | */ |
| | | handleSubmit = () => { |
| | | const { config } = this.props |
| | | let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666' } |
| | | let _actionlist = fromJS(this.state.actionlist).toJS() |
| | | |
| | | |
| | | this.actionFormRef.handleConfirm().then(btn => { |
| | | _actionlist = _actionlist.filter(item => !item.origin || item.uuid === btn.uuid) |
| | | |
| | |
| | | } |
| | | |
| | | if (item.uuid === btn.uuid) { |
| | | btn.btnstyle = item.btnstyle || {} |
| | | |
| | | if (btn.class !== item.class || btn.show !== item.show || !btn.btnstyle.color) { |
| | | if (btn.show === 'link' || btn.show === 'icon') { |
| | | btn.btnstyle.color = color[btn.class] |
| | | btn.btnstyle.background = 'transparent' |
| | | } else { |
| | | btn.btnstyle.color = '#ffffff' |
| | | btn.btnstyle.background = color[btn.class] |
| | | } |
| | | } |
| | | return btn |
| | | } else { |
| | | return item |
| | |
| | | } |
| | | } |
| | | |
| | | dropButton = (id) => { |
| | | let config = fromJS(this.props.config).toJS() |
| | | |
| | | let btn = null |
| | | if (config.subtype === 'normaltable') { |
| | | config.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | |
| | | col.elements = col.elements.filter(item => { |
| | | if (item.uuid === id) { |
| | | btn = item |
| | | } |
| | | return item.uuid !== id |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | if (!btn) return |
| | | |
| | | btn.Ot = 'requiredSgl' |
| | | config.action.push(btn) |
| | | |
| | | this.setState({ |
| | | actionlist: config.action |
| | | }, () => { |
| | | this.props.updateaction(config) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { actionlist, visible, card, dict, profVisible } = this.state |
| | | |
| | | return ( |
| | | <div className={'model-menu-action-list length' + actionlist.length}> |
| | | <div className={'model-menu-action-list'}> |
| | | <DragElement |
| | | list={actionlist} |
| | | handleList={this.handleList} |
| | | dropButton={this.dropButton} |
| | | handleMenu={this.handleAction} |
| | | deleteMenu={this.deleteElement} |
| | | profileMenu={this.profileAction} |
| | | changeBtnStyle={this.changeBtnStyle} |
| | | doubleClickCard={this.btnDoubleClick} |
| | | /> |
| | | {/* 编辑按钮:复制、编辑 */} |
| | |
| | | |
| | | 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) |
| | | btnElement = (<Button style={card.btnstyle} type="link"><Icon type={card.icon}/></Button>) |
| | | } 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> |
| | | ) |
| | | btnElement = (<Button 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} |
| | | > |
| | | {card.label} |
| | | </Button> |
| | | ) |
| | | btnElement = (<Button icon={card.icon} style={card.btnstyle}> {card.label} </Button>) |
| | | } |
| | | |
| | | return ( |
| | |
| | | import Action from './action' |
| | | import './index.scss' |
| | | |
| | | const Container = ({list, handleList, handleMenu, deleteMenu, profileAction, handleStyle, handleSubConfig }) => { |
| | | const Container = ({list, handleList, handleMenu, deleteMenu, profileAction, handleStyle, dropButton, handleSubConfig }) => { |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'action', |
| | | drop() {} |
| | | drop(item) { |
| | | const { index } = findCard(item.id) |
| | | if (index > -1) return |
| | | dropButton(item.id) |
| | | } |
| | | }) |
| | | |
| | | return ( |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps(nextProps) { |
| | | const { cards } = this.props |
| | | if (this.props.side !== nextProps.side) { |
| | | this.setState({ |
| | | elements: fromJS(nextProps.elements).toJS() |
| | |
| | | } else if (nextProps.elements.length === 0 && this.state.elements.length > 0) { |
| | | this.setState({ |
| | | elements: [] |
| | | }) |
| | | } else if (cards.subtype === 'normaltable' && this.state.elements.length > nextProps.elements.length) { // 表格中按钮移出 |
| | | this.setState({ |
| | | elements: fromJS(nextProps.elements).toJS() |
| | | }) |
| | | } |
| | | } |
| | |
| | | */ |
| | | handleActionSubmit = () => { |
| | | const { elements } = this.state |
| | | let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666' } |
| | | |
| | | this.actionFormRef.handleConfirm().then(res => { |
| | | let _elements = elements.map(cell => { |
| | | if (cell.uuid === res.uuid) { |
| | | res = {...cell, ...res} |
| | | delete res.focus |
| | | let btnstyle = {} |
| | | |
| | | if (res.class !== cell.class || res.show !== cell.show || !res.btnstyle) { |
| | | if (res.show === 'link' || res.show === 'icon') { |
| | | btnstyle.color = color[res.class] |
| | | btnstyle.backgroundColor = 'transparent' |
| | | } else { |
| | | btnstyle.color = '#ffffff' |
| | | btnstyle.backgroundColor = color[res.class] |
| | | } |
| | | } |
| | | res.btnstyle = {...res.btnstyle, ...btnstyle} |
| | | |
| | | return res |
| | | } |
| | | return cell |
| | |
| | | }) |
| | | } |
| | | |
| | | dropButton = (id) => { |
| | | const { cards } = this.props |
| | | let index = cards.action.findIndex(item => item.uuid === id) |
| | | |
| | | if (index === -1) return |
| | | |
| | | let btn = cards.action[index] |
| | | btn.eleType = 'button' |
| | | |
| | | let _elements = [...this.state.elements, btn] |
| | | let _action = cards.action.filter(item => item.uuid !== id) |
| | | |
| | | this.setState({ |
| | | elements: _elements |
| | | }, () => { |
| | | this.props.updateElement(_elements, _action) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { cards } = this.props |
| | | const { elements, visible, actvisible, profVisible, card, dict } = this.state |
| | |
| | | handleList={this.handleList} |
| | | handleMenu={this.handleElement} |
| | | handleStyle={this.handleStyle} |
| | | dropButton={this.dropButton} |
| | | profileAction={this.profileAction} |
| | | handleSubConfig={this.handleSubConfig} |
| | | deleteMenu={this.deleteElement} |
| | |
| | | ) |
| | | |
| | | class EditableCell extends Component { |
| | | updateCard = (vals) => { |
| | | updateCard = (vals, action) => { |
| | | const { column } = this.props |
| | | this.props.upComponent({...column, elements: vals}) |
| | | this.props.upComponent({...column, elements: vals}, action) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | |
| | | return !is(fromJS(column), fromJS(nextProps.column)) || |
| | | !is(fromJS(config.columns), fromJS(nextProps.config.columns)) || |
| | | !is(fromJS(config.action), fromJS(nextProps.config.action)) || |
| | | !is(fromJS(config.search), fromJS(nextProps.config.search)) |
| | | } |
| | | |
| | |
| | | ) |
| | | } else if (column && column.type === 'action') { |
| | | return ( |
| | | <td style={{padding: '0 5px', textAlign: column.Align, minWidth: column.Width || 100}} className={className}> |
| | | <td style={{padding: '0 5px', textAlign: column.Align, minWidth: column.Width || 100}} className={'action-column ' + className}> |
| | | <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/> |
| | | </td> |
| | | ) |
| | |
| | | return !is(fromJS(this.state), fromJS(nextState)) || |
| | | !is(fromJS(config.wrap), fromJS(nextProps.config.wrap)) || |
| | | !is(fromJS(config.search), fromJS(nextProps.config.search)) || |
| | | !is(fromJS(config.action), fromJS(nextProps.config.action)) || |
| | | config.setting.laypage !== nextProps.config.setting.laypage |
| | | } |
| | | |
| | |
| | | }) |
| | | } |
| | | |
| | | updateCol = (col) => { |
| | | updateCol = (col, action) => { |
| | | let _columns = fromJS(this.state.columns).toJS() |
| | | |
| | | if (col.isSub) { |
| | |
| | | this.setState({ |
| | | columns: _columns, |
| | | }, () => { |
| | | this.props.updatecolumn({...this.props.config, cols: _columns}) |
| | | if (action) { |
| | | this.props.updatecolumn({...this.props.config, cols: _columns, action}) |
| | | } else { |
| | | this.props.updatecolumn({...this.props.config, cols: _columns}) |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | cell: EditableCell |
| | | } |
| | | } |
| | | |
| | | |
| | | const columns = this.state.columns.map((col, index) => { |
| | | return { |
| | | title: col.label, |
| | |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | .action-column { |
| | | .card-detail-row:empty { |
| | | min-height: 40px; |
| | | } |
| | | } |
| | | tr:hover td { |
| | | background: #ffffff!important; |
| | | } |
| | |
| | | this.props.updateConfig(_card) |
| | | } |
| | | |
| | | addCard = () => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | | // let newcard = { |
| | | // uuid: Utils.getuuid(), |
| | | // setting: { width: 6, type: 'simple'}, |
| | | // style: { |
| | | // paddingTop: '5px', paddingBottom: '5px', paddingLeft: '15px', paddingRight: '15px', |
| | | // }, |
| | | // elements: [] |
| | | // } |
| | | |
| | | this.setState({card}) |
| | | this.props.updateConfig(card) |
| | | } |
| | | |
| | | addColumns = () => { |
| | | let card = fromJS(this.state.card).toJS() |
| | | |
| | |
| | | padding: 5px; |
| | | background: rgba(255, 255, 255, 0.55); |
| | | } |
| | | .model-table-search-list.length0 + .model-menu-action-list { |
| | | min-height: 60px; |
| | | } |
| | | .model-menu-action-list { |
| | | line-height: 40px; |
| | | padding: 10px 0px; |
| | | } |
| | | .model-menu-action-list.length0 { |
| | | display: none; |
| | | min-height: 50px; |
| | | >.ant-row { |
| | | min-height: 30px; |
| | | } |
| | | } |
| | | .card-add-button { |
| | | text-align: right; |
| | |
| | | */ |
| | | handleForm = (_card) => { |
| | | const { componentConfig } = this.props |
| | | let card = fromJS(_card).toJS() |
| | | |
| | | const { config } = this.state |
| | | let card = fromJS(_card).toJS() |
| | | let _inputfields = [] |
| | | let _tabfields = [] |
| | | let _linkableFields = [] |
| | | let _linksupFields = [{ |
| | | value: '', |
| | |
| | | // 设置下拉菜单可关联字段(上级与下级) |
| | | if (config.groups.length > 0) { |
| | | config.groups.forEach(group => { |
| | | let sublist = group.sublist.filter(item => item.type === 'text' || item.type === 'number') |
| | | _inputfields = [..._inputfields, ...sublist] |
| | | |
| | | let suplist = group.sublist.filter(item => item.type === 'select' || item.type === 'link') |
| | | _formfields = [..._formfields, ...suplist] |
| | | _formfields = [..._formfields, ...group.sublist] |
| | | }) |
| | | } else { |
| | | _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number') |
| | | |
| | | _formfields = config.fields.filter(item => item.type === 'select' || item.type === 'link') |
| | | _formfields = config.fields |
| | | } |
| | | |
| | | _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number') |
| | | _tabfields = _formfields.filter(item => card.field !== item.field && ['text', 'number', 'select', 'link'].includes(item.type)) |
| | | _tabfields.unshift({field: '', text: '原表单'}) |
| | | |
| | | let uniq = new Map() |
| | | uniq.set(card.field, true) |
| | | _formfields.forEach(item => { |
| | | if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return |
| | | if (item.field && !uniq.has(item.field)) { |
| | | uniq.set(item.field, true) |
| | | |
| | |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | |
| | | if (card.linkSubField && card.linkSubField.length > 0) { |
| | | let fields = _inputfields.map(item => item.field) |
| | |
| | | this.setState({ |
| | | visible: true, |
| | | card: card, |
| | | formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, !!this.props.editTab) |
| | | formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, !!this.props.editTab) |
| | | }) |
| | | } |
| | | |
| | |
| | | {content && _href ? <a href={_href} target="_blank" rel="noopener noreferrer">{content}</a> : null } |
| | | </div> |
| | | ) |
| | | } else if (col.type === 'custom' || col.type === 'action') { |
| | | } else if (col.type === 'custom') { |
| | | style.padding = '0px' |
| | | resProps.children = ( |
| | | <CardCellComponent data={record} cards={config} elements={col.elements} updateStatus={this.props.updateStatus}/> |
| | | ) |
| | | } else if (col.type === 'action') { |
| | | style.padding = '0px 5px' |
| | | resProps.children = ( |
| | | <CardCellComponent data={record} cards={config} elements={col.elements} updateStatus={this.props.updateStatus}/> |
| | | ) |
| | |
| | | card.elements = card.elements.filter(cell => { |
| | | if (cell.eleType === 'button') { |
| | | cell.logLabel = item.name + '-' + cell.label |
| | | cell.Ot = 'requiredSgl' |
| | | } |
| | | return cell.eleType !== 'button' || permAction[cell.uuid] |
| | | }) |
| | | card.backElements = card.backElements.filter(cell => { |
| | | if (cell.eleType === 'button') { |
| | | cell.logLabel = item.name + '-' + cell.label |
| | | cell.Ot = 'requiredSgl' |
| | | } |
| | | return cell.eleType !== 'button' || permAction[cell.uuid] |
| | | }) |
| | |
| | | card.elements = card.elements.filter(cell => { |
| | | if (cell.eleType === 'button') { |
| | | cell.logLabel = item.name + '-' + cell.label |
| | | cell.Ot = 'requiredSgl' |
| | | } |
| | | return cell.eleType !== 'button' || permAction[cell.uuid] |
| | | }) |
| | |
| | | if (col.type !== 'action') return |
| | | col.elements = col.elements.filter(cell => { |
| | | cell.logLabel = item.name + '-' + cell.label |
| | | cell.Ot = 'requiredSgl' |
| | | return permAction[cell.uuid] |
| | | }) |
| | | }) |
| | |
| | | width: 40px; |
| | | height: 40px; |
| | | } |
| | | .ant-btn-link:hover { |
| | | opacity: 0.8; |
| | | } |
| | | } |
| | | |
| | |
| | | <Button |
| | | type="link" |
| | | loading={loading} |
| | | style={btn.btnstyle} |
| | | icon={show === 'text' ? '' : (btn.icon || '')} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{show === 'icon' && btn.icon ? '' : btn.label}</Button> |
| | |
| | | <Button |
| | | type="link" |
| | | loading={loading} |
| | | style={btn.btnstyle} |
| | | icon={show === 'text' ? '' : (show === 'icon' ? (btn.icon || 'upload') : (btn.icon || ''))} |
| | | onClick={() => {this.actionTrigger()}} |
| | | >{show === 'icon' ? '' : btn.label}</Button> |
| | |
| | | <Button |
| | | type="link" |
| | | loading={loading} |
| | | style={btn.btnstyle} |
| | | icon={show === 'text' ? '' : (show === 'icon' ? (btn.icon || 'download') : (btn.icon || ''))} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{show === 'icon' ? '' : btn.label}</Button> |
| | |
| | | return ( |
| | | <NormalButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | BID={BID} |
| | | Tab={Tab} |
| | | btn={item} |
| | |
| | | return ( |
| | | <ExcelInButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | BID={BID} |
| | | Tab={Tab} |
| | | btn={item} |
| | |
| | | return ( |
| | | <ExcelOutButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | BID={BID} |
| | | Tab={Tab} |
| | | btn={item} |
| | |
| | | return ( |
| | | <PopupButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | BID={BID} |
| | | Tab={Tab} |
| | | btn={item} |
| | |
| | | return ( |
| | | <TabButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | btn={item} |
| | | MenuID={MenuID} |
| | | setting={setting} |
| | |
| | | return ( |
| | | <ChangeUserButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | BID={BID} |
| | | btn={item} |
| | | setting={setting} |
| | |
| | | return ( |
| | | <PrintButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | BID={BID} |
| | | Tab={Tab} |
| | | btn={item} |
| | |
| | | return ( |
| | | <Button |
| | | type="link" |
| | | style={btn.btnstyle} |
| | | icon={show === 'text' ? '' : (btn.icon || '')} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{show === 'icon' && btn.icon ? '' : btn.label}</Button> |
| | |
| | | const { btn, show, style } = this.props |
| | | const { loadingNumber, loading } = this.state |
| | | |
| | | if (show === 'actionList' || show === 'button') { |
| | | if (show === 'actionList') { |
| | | return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}> |
| | | <Button |
| | | style={style} |
| | |
| | | return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}> |
| | | <Button |
| | | type="link" |
| | | style={style} |
| | | loading={loading} |
| | | style={btn.btnstyle || style} |
| | | icon={show === 'text' ? '' : (btn.icon || '')} |
| | | onClick={() => {this.actionTrigger()}} |
| | | >{show === 'icon' && btn.icon ? '' : btn.label}</Button> |
| | |
| | | onClick={() => {this.actionTrigger()}} |
| | | loading={loading} |
| | | >{btn.label}</Button> : null} |
| | | {['icon', 'text', 'all'].includes(show) ? <Button |
| | | {show !== 'actionList' ? <Button |
| | | type="link" |
| | | loading={loading} |
| | | style={btn.btnstyle} |
| | | icon={show === 'text' ? '' : (btn.icon || '')} |
| | | onClick={() => {this.actionTrigger()}} |
| | | >{show === 'icon' && btn.icon ? '' : btn.label}</Button> : null} |
| | |
| | | <Button |
| | | type="link" |
| | | loading={loading} |
| | | style={btn.btnstyle} |
| | | icon={show === 'text' ? '' : (btn.icon || '')} |
| | | onClick={() => {this.actionTrigger()}} |
| | | >{show === 'icon' && btn.icon ? '' : btn.label}</Button> |
| | |
| | | return ( |
| | | <Button |
| | | type="link" |
| | | style={btn.btnstyle} |
| | | icon={show === 'text' ? '' : (btn.icon || '')} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{show === 'icon' && btn.icon ? '' : btn.label}</Button> |
| | |
| | | item.options.unshift({ |
| | | key: Utils.getuuid(), |
| | | Value: '', |
| | | Text: item.emptyText || '空' |
| | | Text: item.emptyText || '空', |
| | | ParentID: '' |
| | | }) |
| | | } |
| | | |
| | |
| | | item.supInitVal = data[item.linkField] |
| | | } |
| | | |
| | | item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal) |
| | | item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal || option.Value === '') |
| | | } |
| | | return item |
| | | }) |
| | |
| | | formlist: formlist |
| | | }, () => { |
| | | if (action.setting && action.setting.focus) { |
| | | try { |
| | | let _form = document.getElementById('main-form-box') |
| | | let _item = _form.getElementsByTagName('input') |
| | | _item = [..._item] |
| | | _item.forEach(input => { |
| | | if (!input || input.id !== action.setting.focus) return |
| | | input.select() |
| | | }) |
| | | } catch { |
| | | console.warn('focus error!') |
| | | } |
| | | this.selectInput(action.setting.focus, 'init') |
| | | } |
| | | // 用来更新state,防止受控表单初始时不显示 |
| | | this.setState({ |
| | |
| | | }) |
| | | this.improveActionForm(deForms) |
| | | }) |
| | | } |
| | | |
| | | selectInput = (selectId, type) => { |
| | | try { |
| | | let _form = document.getElementById('main-form-box') |
| | | let _inputs = _form.getElementsByTagName('input') |
| | | _inputs = [..._inputs] |
| | | _inputs.forEach(input => { |
| | | if (!input || input.id !== selectId) return |
| | | |
| | | if (input.className === 'ant-select-search__field' && type !== 'init') { |
| | | let div = document.getElementById(input.id) |
| | | div && div.click && div.click() |
| | | } else if (input.select) { |
| | | input.select() |
| | | } else if (input.focus) { |
| | | input.focus() |
| | | } |
| | | }) |
| | | } catch { |
| | | console.warn('focus error!') |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | this.setState({ |
| | | formlist: _formlist.map(item => { |
| | | if (item.type === 'link') { |
| | | item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal) |
| | | item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal || option.Value === '') |
| | | } else if (['select', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(item.type)) { |
| | | item.options = item.oriOptions |
| | | } |
| | |
| | | this.setState({ |
| | | formlist: _formlist.map(item => { |
| | | if (item.type === 'link') { |
| | | item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal) |
| | | item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal || option.Value === '') |
| | | } else if (['select', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(item.type)) { |
| | | item.options = item.oriOptions |
| | | } |
| | |
| | | formlist = formlist.map(item => { |
| | | if (item.type === 'link' && item.linkField === supfield.field) { |
| | | |
| | | item.options = item.oriOptions.filter(option => option.ParentID === supfield.initval) |
| | | item.options = item.oriOptions.filter(option => option.ParentID === supfield.initval || option.Value === '') |
| | | item.initval = item.options[0] ? item.options[0].Value : '' |
| | | |
| | | if (this.props.form.getFieldValue(item.field) !== undefined) { |
| | |
| | | selectChange = (_field, value) => { |
| | | const { record } = this.state |
| | | let formlist = fromJS(this.state.formlist).toJS() |
| | | |
| | | let subfields = [] |
| | | let fieldsvalue = {} |
| | | let _record = {} |
| | | |
| | | formlist = formlist.map(item => { |
| | | if (item.type === 'link' && item.linkField === _field.field) { |
| | | item.options = item.oriOptions.filter(option => option.ParentID === value) |
| | | item.options = item.oriOptions.filter(option => option.ParentID === value || option.Value === '') |
| | | item.initval = item.options[0] ? item.options[0].Value : '' |
| | | |
| | | if (this.props.form.getFieldValue(item.field) !== undefined) { |
| | |
| | | |
| | | this.setState(_param) |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | if (!_field.enter || _field.enter === 'false') return |
| | | |
| | | if (_field.enter === 'tab') { |
| | | this.selectInput(_field.tabField) |
| | | } else if (_field.enter === 'sub') { |
| | | this.handleSubmit() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleConfirmPassword = (rule, value, callback, item) => { |
| | |
| | | callback(item.label + '最大值为 ' + item.max) |
| | | } |
| | | } |
| | | |
| | | callback() |
| | | } |
| | | |
| | | handleChange = (e, item) => { |
| | | let val = e.target.value |
| | | |
| | | if (item.enter === 'false') return |
| | | if (!val || !/\n/ig.test(val)) return |
| | | if (item.enter === 'tab') { |
| | | this.selectInput(item.tabField) |
| | | } else { |
| | | this.handleSubmit(e) |
| | | this.selectInput(item.tabField || item.field) |
| | | } |
| | | } |
| | | |
| | | handleInputSubmit = (e, item) => { |
| | | if (item.enter === 'false') return |
| | | if (item.enter === 'tab') { |
| | | this.selectInput(item.tabField) |
| | | } else { |
| | | this.handleSubmit(e) |
| | | this.selectInput(item.tabField || item.field) |
| | | } |
| | | } |
| | | |
| | | getFields() { |
| | |
| | | }, |
| | | ..._rules |
| | | ] |
| | | })(<Input placeholder="" autoComplete="off" disabled={item.readonly === 'true'} onPressEnter={this.handleSubmit} />)} |
| | | })(<Input placeholder="" autoComplete="off" disabled={item.readonly === 'true'} onChange={(e) => this.handleChange(e, item)} onPressEnter={(e) => this.handleInputSubmit(e, item)} />)} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | |
| | | ] |
| | | })( |
| | | precision === null ? |
| | | <InputNumber disabled={item.readonly === 'true'} onPressEnter={this.handleSubmit} /> : |
| | | <InputNumber precision={precision} disabled={item.readonly === 'true'} onPressEnter={this.handleSubmit} /> |
| | | <InputNumber disabled={item.readonly === 'true'} onPressEnter={(e) => this.handleInputSubmit(e, item)} /> : |
| | | <InputNumber precision={precision} disabled={item.readonly === 'true'} onPressEnter={(e) => this.handleInputSubmit(e, item)} /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | |
| | | showSearch |
| | | allowClear={true} |
| | | filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} |
| | | onChange={(value) => {this.selectChange(item, value)}} |
| | | onSelect={(value) => {this.selectChange(item, value)}} |
| | | disabled={item.readonly === 'true'} |
| | | > |
| | | {item.options.map(option => |
| | |
| | | } |
| | | |
| | | handleSubmit = (e) => { |
| | | e.preventDefault() |
| | | e && e.preventDefault() |
| | | this.props.inputSubmit() |
| | | } |
| | | |
| | |
| | | const { menu } = this.props |
| | | const { config } = this.state |
| | | let _inputfields = [] |
| | | let _tabfields = [] |
| | | let _linkableFields = [] |
| | | let _linksupFields = [{ |
| | | value: '', |
| | |
| | | |
| | | // 设置下拉菜单可关联字段 |
| | | config.groups.forEach(group => { |
| | | let sublist = group.sublist.filter(item => item.type === 'text' || item.type === 'number') |
| | | _inputfields = [..._inputfields, ...sublist] |
| | | |
| | | let suplist = group.sublist.filter(item => item.type === 'select' || item.type === 'link') |
| | | _formfields = [..._formfields, ...suplist] |
| | | _formfields = [..._formfields, ...group.sublist] |
| | | }) |
| | | |
| | | _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number') |
| | | _tabfields = _formfields.filter(item => card.field !== item.field && ['text', 'number', 'select', 'link'].includes(item.type)) |
| | | _tabfields.unshift({field: '', text: '原表单'}) |
| | | |
| | | if (card.linkSubField && card.linkSubField.length > 0) { |
| | | let fields = _inputfields.map(item => item.field) |
| | |
| | | uniq.set(card.field, true) |
| | | |
| | | _formfields.forEach(item => { |
| | | if (item.type !== 'select' && item.type !== 'link') return |
| | | if (item.field && !uniq.has(item.field)) { |
| | | uniq.set(item.field, true) |
| | | |
| | |
| | | this.setState({ |
| | | modaltype: 'search', |
| | | card: card, |
| | | formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, false).map(item => { |
| | | formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, false).map(item => { |
| | | if (item.key === 'type') { |
| | | item.options = item.options.filter(option => !['switch', 'checkbox', 'radio', 'checkcard', 'hint'].includes(option.value)) |
| | | } |
| | |
| | | let card = fromJS(_card).toJS() |
| | | const { config } = this.state |
| | | let _inputfields = [] |
| | | let _tabfields = [] |
| | | let _linkableFields = [] |
| | | let _linksupFields = [{ |
| | | value: '', |
| | |
| | | // 设置下拉菜单可关联字段(上级与下级) |
| | | if (config.groups.length > 0) { |
| | | config.groups.forEach(group => { |
| | | let sublist = group.sublist.filter(item => item.type === 'text' || item.type === 'number') |
| | | _inputfields = [..._inputfields, ...sublist] |
| | | |
| | | let suplist = group.sublist.filter(item => item.type === 'select' || item.type === 'link' || item.type === 'radio') |
| | | _formfields = [..._formfields, ...suplist] |
| | | _formfields = [..._formfields, ...group.sublist] |
| | | }) |
| | | } else { |
| | | _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number') |
| | | |
| | | _formfields = config.fields.filter(item => item.type === 'select' || item.type === 'link' || item.type === 'radio') |
| | | _formfields = config.fields |
| | | } |
| | | |
| | | _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number') |
| | | _tabfields = _formfields.filter(item => card.field !== item.field && ['text', 'number', 'select', 'link'].includes(item.type)) |
| | | _tabfields.unshift({field: '', text: '原表单'}) |
| | | |
| | | let uniq = new Map() |
| | | uniq.set(card.field, true) |
| | | _formfields.forEach(item => { |
| | | if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return |
| | | if (item.field && !uniq.has(item.field)) { |
| | | uniq.set(item.field, true) |
| | | |
| | |
| | | this.setState({ |
| | | visible: true, |
| | | card: card, |
| | | formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, !!this.props.editTab) |
| | | formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, !!this.props.editTab) |
| | | }) |
| | | } |
| | | |
| | |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '60%', |
| | | render: (text) => ( |
| | | <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> |
| | | ) |
| | | render: (text) => { |
| | | let title = text.match(/^\s*\/\*.+\*\//) |
| | | title = title && title[0] ? title[0] : '' |
| | | text = title ? text.replace(title, '') : text |
| | | |
| | | return ( |
| | | <div> |
| | | {title ? <span style={{color: '#a50'}}>{title}</span> : null} |
| | | <Paragraph copyable ellipsis={{ rows: 4, expandable: true }}>{text}</Paragraph> |
| | | </div> |
| | | ) |
| | | } |
| | | }, |
| | | { |
| | | title: '执行位置', |
| | |
| | | |
| | | class BodyRow extends React.Component { |
| | | render() { |
| | | const { isOver, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props |
| | | const style = { ...restProps.style, cursor: 'move' } |
| | | const { isOver, moveAble, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props |
| | | |
| | | let { className } = restProps |
| | | if (isOver) { |
| | | if (isOver && moveAble) { |
| | | if (restProps.index > dragingIndex) { |
| | | className += ' drop-over-downward' |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | return connectDragSource( |
| | | connectDropTarget(<tr {...restProps} className={className} style={style} />), |
| | | ) |
| | | if (moveAble) { |
| | | return connectDragSource( |
| | | connectDropTarget(<tr {...restProps} className={className} style={{ ...restProps.style, cursor: 'move' }} />), |
| | | ) |
| | | } else { |
| | | return (<tr {...restProps} className={className} style={restProps.style} />) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | </Radio.Group> |
| | | ) |
| | | } else { |
| | | return <Input onPressEnter={() => this.getValue(form)} /> |
| | | return <Input onPressEnter={() => this.getValue(form)}/> |
| | | } |
| | | } |
| | | |
| | |
| | | const { editingKey } = this.state |
| | | const editable = this.isEditing(record) |
| | | return editable ? ( |
| | | <span style={{textAlign: 'center', display: 'block'}}> |
| | | <div style={{textAlign: 'center', minWidth: '110px'}}> |
| | | <EditableContext.Consumer> |
| | | {form => ( |
| | | <span onClick={() => this.save(form, record.uuid)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}> |
| | |
| | | )} |
| | | </EditableContext.Consumer> |
| | | <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.uuid)}>{eTDict['model.cancel']}</span> |
| | | </span> |
| | | </div> |
| | | ) : ( |
| | | <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')}> |
| | | <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px'}}> |
| | | {!actions || actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><Icon type="edit" /></span> : null} |
| | | {(!actions || actions.includes('del')) && editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | |
| | | |
| | | return ( |
| | | <EditableContext.Provider value={this.props.form}> |
| | | <div className={'modal-edit-table ' + (this.state.editingKey ? 'editing' : '')}> |
| | | <div className="modal-edit-table"> |
| | | <DndProvider> |
| | | <Table |
| | | bordered |
| | |
| | | pagination={false} |
| | | onRow={(record, index) => ({ |
| | | index, |
| | | moveAble: !this.state.editingKey, |
| | | moveRow: this.moveRow, |
| | | })} |
| | | /> |
| | |
| | | .ant-empty { |
| | | margin: 0; |
| | | } |
| | | } |
| | | .modal-edit-table.editing { |
| | | .editable-row { |
| | | cursor: default!important; |
| | | } |
| | | } |
| | | .modal-edit-table:not(.editing) { |
| | | tr.drop-over-downward td { |
| | | border-bottom: 2px dashed #1890ff; |
| | | } |
| | |
| | | border-top: 2px dashed #1890ff; |
| | | } |
| | | } |
| | | |
| | |
| | | * @description 获取表单配置信息 |
| | | * @param {*} card // 表单对象 |
| | | * @param {*} inputfields // 可关联表单 |
| | | * @param {*} tabfields // 可切换表单 |
| | | * @param {*} linkableFields // 可关联表单 |
| | | * @param {*} linksupFields // 上级表单 |
| | | * @param {*} subtable // 是否为子表表单 |
| | | */ |
| | | export function getModalForm (card, inputfields, linkableFields, linksupFields, subtable = false) { |
| | | export function getModalForm (card, inputfields = [], tabfields = [], linkableFields, linksupFields, subtable = false) { |
| | | let roleList = sessionStorage.getItem('sysRoles') |
| | | if (roleList) { |
| | | try { |
| | |
| | | { |
| | | type: 'text', |
| | | key: 'tooltip', |
| | | label: '表单注释', |
| | | tooltip: '鼠标悬浮于提示文字上方时,显示注释。', |
| | | label: '悬浮提示', |
| | | tooltip: '鼠标悬浮于提示文字上方时,显示提示信息。', |
| | | initVal: card.tooltip || '', |
| | | required: false |
| | | }, |
| | |
| | | type: 'text', |
| | | key: 'emptyText', |
| | | label: '空值文本', |
| | | tooltip: '空值的提示文本,默认为《空》。', |
| | | tooltip: '空值的提示文本,选择设置空值时有效,默认值为《空》。', |
| | | initVal: card.emptyText || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'enter', |
| | | label: '回车事件', |
| | | initVal: (card.type === 'text' || card.type === 'number') ? (card.enter || 'sub') : (card.enter || 'false'), |
| | | tooltip: '点击Enter键,或文本类表单输入回车符。', |
| | | options: [{ |
| | | value: 'sub', |
| | | text: '提交' |
| | | }, { |
| | | value: 'tab', |
| | | text: '切换' |
| | | }, { |
| | | value: 'false', |
| | | text: '无动作' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'tabField', |
| | | label: '切换字段', |
| | | initVal: card.tabField || '', |
| | | options: tabfields, |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'multiselect', |
| | | key: 'blacklist', |
| | | label: Formdict['header.form.blacklist'], |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { DndProvider, DragSource, DropTarget } from 'react-dnd' |
| | | import { Table, Input, Popconfirm, Form, Icon, notification } from 'antd' |
| | | |
| | | import Utils from '@/utils/utils.js' |
| | |
| | | import './index.scss' |
| | | |
| | | const EditableContext = React.createContext() |
| | | let dragingIndex = -1 |
| | | |
| | | class BodyRow extends React.Component { |
| | | render() { |
| | | const { isOver, moveAble, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props |
| | | let { className } = restProps |
| | | |
| | | if (isOver && moveAble) { |
| | | if (restProps.index > dragingIndex) { |
| | | className += ' drop-over-downward' |
| | | } |
| | | if (restProps.index < dragingIndex) { |
| | | className += ' drop-over-upward' |
| | | } |
| | | } |
| | | |
| | | if (moveAble) { |
| | | return connectDragSource( |
| | | connectDropTarget(<tr {...restProps} className={className} style={{...restProps.style, cursor: 'move'}} />), |
| | | ) |
| | | } else { |
| | | return (<tr {...restProps} className={className} style={restProps.style} />) |
| | | } |
| | | } |
| | | } |
| | | |
| | | const rowSource = { |
| | | beginDrag(props) { |
| | | dragingIndex = props.index |
| | | return { |
| | | index: props.index, |
| | | } |
| | | } |
| | | } |
| | | |
| | | const rowTarget = { |
| | | drop(props, monitor) { |
| | | const dragIndex = monitor.getItem().index |
| | | const hoverIndex = props.index |
| | | |
| | | if (dragIndex === hoverIndex) { |
| | | return |
| | | } |
| | | |
| | | props.moveRow(dragIndex, hoverIndex) |
| | | |
| | | monitor.getItem().index = hoverIndex |
| | | }, |
| | | } |
| | | |
| | | const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({ |
| | | connectDropTarget: connect.dropTarget(), |
| | | isOver: monitor.isOver(), |
| | | }))( |
| | | DragSource('row', rowSource, connect => ({ |
| | | connectDragSource: connect.dragSource(), |
| | | }))(BodyRow), |
| | | ) |
| | | |
| | | class EditableCell extends Component { |
| | | getInput = (form) => { |
| | |
| | | }) |
| | | |
| | | columns.push({ |
| | | title: 'operation', |
| | | title: '操作', |
| | | dataIndex: 'operation', |
| | | align: 'center', |
| | | width: '18%', |
| | | render: (text, record) => { |
| | | const { editingKey } = this.state |
| | |
| | | ) : ( |
| | | <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span> |
| | | <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span> |
| | | {editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | |
| | | handleDelete = (key) => { |
| | | const { data } = this.state |
| | | let _data = data.filter(item => key !== item.key) |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | handleUpDown = (key, direction) => { |
| | | let _data = fromJS(this.state.data).toJS() |
| | | const index = _data.findIndex(item => key === item.key) |
| | | |
| | | if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | _data.splice(index - 1, 0, ..._data.splice(index, 1)) |
| | | } else { |
| | | _data.splice(index + 1, 0, ..._data.splice(index, 1)) |
| | | } |
| | | |
| | | this.setState({ |
| | | data: _data |
| | |
| | | |
| | | handleAdd = () => { |
| | | const { fields, type } = this.props |
| | | if (this.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请保存编辑中的元素!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (this.state.data.length >= 20) { |
| | | if (this.state.data.length >= 20) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '最多可添加20项!', |
| | |
| | | |
| | | let data = [...this.state.data, item] |
| | | |
| | | this.setState({ data }, () => { |
| | | this.setState({ data, editingKey: '' }, () => { |
| | | this.props.onChange(data) |
| | | }) |
| | | } |
| | |
| | | this.setState({ editingKey: key }) |
| | | } |
| | | |
| | | moveRow = (dragIndex, hoverIndex) => { |
| | | const { editingKey } = this.state |
| | | let _data = fromJS(this.state.data).toJS() |
| | | |
| | | if (editingKey) return |
| | | |
| | | _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1)) |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const components = { |
| | | body: { |
| | | cell: EditableCell, |
| | | }, |
| | | row: DragableBodyRow, |
| | | cell: EditableCell |
| | | } |
| | | } |
| | | |
| | | const columns = this.state.columns.map(col => { |
| | |
| | | <EditableContext.Provider value={this.props.form}> |
| | | <div className="modal-card-data-table"> |
| | | {addable ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null} |
| | | <Table |
| | | components={components} |
| | | bordered |
| | | dataSource={this.state.data} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | pagination={false} |
| | | /> |
| | | <DndProvider> |
| | | <Table |
| | | components={components} |
| | | bordered |
| | | rowKey="key" |
| | | dataSource={this.state.data} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | onRow={(record, index) => ({ |
| | | index, |
| | | moveAble: !this.state.editingKey, |
| | | moveRow: this.moveRow, |
| | | })} |
| | | pagination={false} |
| | | /> |
| | | </DndProvider> |
| | | </div> |
| | | </EditableContext.Provider> |
| | | ) |
| | |
| | | } |
| | | } |
| | | .operation-btn { |
| | | font-size: 16px; |
| | | text-align: center; |
| | | span { |
| | | margin-right: 7px; |
| | | margin-right: 15px; |
| | | cursor: pointer; |
| | | } |
| | | .primary { |
| | |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | } |
| | | tr.drop-over-downward td { |
| | | border-bottom: 2px dashed #1890ff; |
| | | } |
| | | tr.drop-over-upward td { |
| | | border-top: 2px dashed #1890ff; |
| | | } |
| | | } |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Table, Input, InputNumber, Popconfirm, Form, Icon, notification, Select } from 'antd' |
| | | import { Icon, notification } from 'antd' |
| | | |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import Utils from '@/utils/utils.js' |
| | | import './index.scss' |
| | | |
| | | const EditableContext = React.createContext() |
| | | |
| | | class EditableCell extends Component { |
| | | getInput = (form) => { |
| | | const { inputType } = this.props |
| | | if (inputType === 'number') { |
| | | return <InputNumber min={12} max={50} precision={0} onPressEnter={() => this.getValue(form)} /> |
| | | } else if (inputType === 'color') { |
| | | return <ColorSketch /> |
| | | } else if (inputType === 'select') { |
| | | return <Select> |
| | | <Select.Option key="left" value="left"> left </Select.Option> |
| | | <Select.Option key="center" value="center"> center </Select.Option> |
| | | <Select.Option key="right" value="right"> right </Select.Option> |
| | | <Select.Option key="justify" value="justify"> justify </Select.Option> |
| | | </Select> |
| | | } else { |
| | | return <Input onPressEnter={() => this.getValue(form)} /> |
| | | } |
| | | } |
| | | |
| | | getValue = (form) => { |
| | | const { record } = this.props |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return |
| | | } |
| | | this.props.onSave({...record, ...row}) |
| | | }) |
| | | } |
| | | |
| | | renderCell = (form) => { |
| | | const { getFieldDecorator } = form |
| | | const { editing, dataIndex, title, record, children, className } = this.props |
| | | |
| | | return ( |
| | | <td className={className}> |
| | | {editing ? ( |
| | | <Form.Item style={{ margin: 0 }}> |
| | | {getFieldDecorator(dataIndex, { |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: `Please Input ${title}!`, |
| | | }, |
| | | ], |
| | | initialValue: record[dataIndex], |
| | | })(this.getInput(form))} |
| | | </Form.Item> |
| | | ) : ( |
| | | children |
| | | )} |
| | | </td> |
| | | ) |
| | | } |
| | | |
| | | render() { |
| | | return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer> |
| | | } |
| | | } |
| | | const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) |
| | | |
| | | class EdiFieldsTable extends Component { |
| | | static propTpyes = { |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let data = this.props['data-__meta'].initialValue |
| | | let data = this.props['data-__meta'].initialValue || [] |
| | | |
| | | this.setState({ |
| | | data: data |
| | | data: data.map(item => { |
| | | item.uuid = item.uuid || item.key |
| | | return item |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | state = { |
| | | data: [], |
| | | editingKey: '', |
| | | columns: [ |
| | | { |
| | | title: '字段名', |
| | | dataIndex: 'field', |
| | | inputType: 'input', |
| | | editable: true, |
| | | width: '20%', |
| | | }, |
| | | { |
| | | title: '字体颜色', |
| | | dataIndex: 'color', |
| | | inputType: 'color', |
| | | editable: true, |
| | | width: '20%', |
| | | render: (text, record) => { |
| | | return <span style={{color: text}}>示例</span> |
| | | } |
| | |
| | | title: '字体大小', |
| | | dataIndex: 'fontSize', |
| | | inputType: 'number', |
| | | min: 12, |
| | | max: 50, |
| | | editable: true, |
| | | width: '20%', |
| | | }, |
| | | { |
| | | title: '对齐方式', |
| | | dataIndex: 'align', |
| | | inputType: 'select', |
| | | editable: true, |
| | | }, |
| | | { |
| | | title: 'operation', |
| | | dataIndex: 'operation', |
| | | width: '18%', |
| | | render: (text, record) => { |
| | | const { editingKey } = this.state |
| | | const editable = this.isEditing(record) |
| | | return editable ? ( |
| | | <span> |
| | | <EditableContext.Consumer> |
| | | {form => ( |
| | | <span onClick={() => this.save(form, record.key)} style={{ marginRight: 8 , color: '#1890ff', cursor: 'pointer'}}> |
| | | 保存 |
| | | </span> |
| | | )} |
| | | </EditableContext.Consumer> |
| | | <span style={{ color: '#1890ff', cursor: 'pointer'}} onClick={() => this.cancel(record.key)}>取消</span> |
| | | </span> |
| | | ) : ( |
| | | <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span> |
| | | <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span> |
| | | <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span> |
| | | {editingKey === '' ? <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={this.props.dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record.key) |
| | | }> |
| | | <span className="danger"><Icon type="delete" /></span> |
| | | </Popconfirm> : null} |
| | | {editingKey !== '' ? <span className="danger"><Icon type="delete" /></span> : null} |
| | | </div> |
| | | ) |
| | | }, |
| | | }, |
| | | width: '20%', |
| | | options: [ |
| | | {value: 'left', text: 'left'}, |
| | | {value: 'center', text: 'center'}, |
| | | {value: 'right', text: 'right'}, |
| | | {value: 'justify', text: 'justify'} |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | | |
| | | isEditing = record => record.key === this.state.editingKey |
| | | |
| | | cancel = () => { |
| | | this.setState({ editingKey: '' }) |
| | | } |
| | | |
| | | onSave = (record) => { |
| | | const newData = [...this.state.data] |
| | | const index = newData.findIndex(item => record.key === item.key) |
| | | if (index > -1) { |
| | | newData.splice(index, 1, record) |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | handleDelete = (key) => { |
| | | const { data } = this.state |
| | | let _data = data.filter(item => key !== item.key) |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | handleUpDown = (key, direction) => { |
| | | let _data = fromJS(this.state.data).toJS() |
| | | const index = _data.findIndex(item => key === item.key) |
| | | |
| | | if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) { |
| | | return |
| | | } |
| | | |
| | | if (direction === 'up') { |
| | | _data.splice(index - 1, 0, ..._data.splice(index, 1)) |
| | | } else { |
| | | _data.splice(index + 1, 0, ..._data.splice(index, 1)) |
| | | } |
| | | |
| | | this.setState({ |
| | | data: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | save(form, key) { |
| | | form.validateFields((error, row) => { |
| | | if (error) { |
| | | return; |
| | | } |
| | | const newData = [...this.state.data] |
| | | const index = newData.findIndex(item => key === item.key) |
| | | if (index > -1) { |
| | | const item = newData[index] |
| | | newData.splice(index, 1, { |
| | | ...item, |
| | | ...row, |
| | | }) |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } else { |
| | | newData.push(row); |
| | | this.setState({ data: newData, editingKey: '' }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | handleAdd = () => { |
| | | if (this.state.editingKey) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请保存编辑中的元素!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _index = this.state.data.length + 1 |
| | | let item = { |
| | | key: Utils.getuuid(), |
| | | field: `field${this.state.data.length + 1}`, |
| | | field: `field${_index}`, |
| | | color: 'rgba(0, 0, 0, 0.85)', |
| | | align: 'left', |
| | | fontSize: 14, |
| | | } |
| | | |
| | | item.uuid = item.key |
| | | |
| | | while (this.state.data.filter(cell => cell.field === item.field).length > 0) { |
| | | _index++ |
| | | item.field = `field${_index}` |
| | | } |
| | | |
| | | let data = [...this.state.data, item] |
| | |
| | | }) |
| | | } |
| | | |
| | | edit(key) { |
| | | this.setState({ editingKey: key }) |
| | | changeData = (data) => { |
| | | let fields = data.map(cell => cell.field) |
| | | fields = Array.from(new Set(fields)) |
| | | if (data.length > 1 && data.length > fields.length) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段名不可重复!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | Array.from(new Set(fields)) |
| | | this.setState({ data }, () => { |
| | | this.props.onChange(data) |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const components = { |
| | | body: { |
| | | cell: EditableCell, |
| | | }, |
| | | } |
| | | |
| | | const columns = this.state.columns.map(col => { |
| | | if (!col.editable) { |
| | | return col |
| | | } |
| | | return { |
| | | ...col, |
| | | onCell: record => ({ |
| | | record, |
| | | inputType: col.inputType, |
| | | dataIndex: col.dataIndex, |
| | | title: col.title, |
| | | editing: this.isEditing(record), |
| | | onSave: this.onSave, |
| | | }), |
| | | } |
| | | }) |
| | | const { data, columns } = this.state |
| | | |
| | | return ( |
| | | <EditableContext.Provider value={this.props.form}> |
| | | <div className="modal-card-field-table"> |
| | | {this.state.data.length < 3 ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null} |
| | | <Table |
| | | components={components} |
| | | bordered |
| | | dataSource={this.state.data} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | pagination={false} |
| | | /> |
| | | </div> |
| | | </EditableContext.Provider> |
| | | <div className="modal-card-field-table"> |
| | | {data.length < 3 ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null} |
| | | <EditTable data={data} columns={columns} onChange={this.changeData}/> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(EdiFieldsTable) |
| | | export default EdiFieldsTable |
| | |
| | | font-size: 18px; |
| | | color: #26C281; |
| | | } |
| | | .editable-row { |
| | | .ant-form-explain { |
| | | position: absolute; |
| | | font-size: 12px; |
| | | margin-top: -4px; |
| | | } |
| | | .color-sketch-block { |
| | | width: 200px; |
| | | position: relative; |
| | | top: 8px; |
| | | } |
| | | .ant-select { |
| | | width: 80px; |
| | | } |
| | | > td { |
| | | padding: 16px 10px; |
| | | } |
| | | } |
| | | .operation-btn { |
| | | span { |
| | | margin-right: 10px; |
| | | cursor: pointer; |
| | | } |
| | | .primary { |
| | | color: #1890ff; |
| | | } |
| | | .danger { |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | .operation-btn.disabled { |
| | | span { |
| | | cursor: default; |
| | | } |
| | | .primary { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | .danger { |
| | | color: rgba(0, 0, 0, .25); |
| | | } |
| | | } |
| | | .ant-empty { |
| | | margin: 0; |
| | | } |
| | |
| | | const { TextArea } = Input |
| | | |
| | | const modalTypeOptions = { |
| | | text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine', 'tooltip'], |
| | | number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine', 'tooltip'], |
| | | select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine', 'tooltip', 'emptyText'], |
| | | text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine', 'tooltip', 'enter'], |
| | | number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine', 'tooltip', 'enter'], |
| | | select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine', 'tooltip', 'emptyText', 'enter'], |
| | | checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'entireLine', 'tooltip'], |
| | | radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine', 'tooltip', 'setAll', 'emptyText'], |
| | | checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'fieldlength', 'display', 'tooltip', 'width', 'multiple'], |
| | | multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine', 'tooltip'], |
| | | link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine', 'tooltip', 'emptyText'], |
| | | link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine', 'tooltip', 'emptyText', 'enter'], |
| | | fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine', 'tooltip'], |
| | | switch: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'entireLine', 'tooltip'], |
| | | date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine', 'tooltip'], |
| | |
| | | resourceType: null, |
| | | supField: '', |
| | | display: 'text', |
| | | enter: '', |
| | | cFields: [], |
| | | formlist: null, |
| | | linkSubFields: null |
| | |
| | | let resourceType = '' |
| | | let supField = '' |
| | | let display = '' |
| | | let enter = '' |
| | | let cFields = [] |
| | | let linkSubFields = [] |
| | | |
| | |
| | | type = cell.initVal |
| | | } else if (cell.key === 'display') { |
| | | display = cell.initVal |
| | | } else if (cell.key === 'enter') { |
| | | enter = cell.initVal |
| | | } else if (cell.key === 'fields') { |
| | | cFields = cell.initVal |
| | | } else if (cell.key === 'resourceType') { |
| | |
| | | } |
| | | }) |
| | | |
| | | let _options = this.getOptions(type, resourceType, supField, display) |
| | | let _options = this.getOptions(type, resourceType, supField, display, enter) |
| | | |
| | | this.setState({ |
| | | enter: enter, |
| | | openType: type, |
| | | supField: supField, |
| | | display: display, |
| | |
| | | } |
| | | } |
| | | |
| | | getOptions = (type, resourceType, supField, display) => { |
| | | getOptions = (type, resourceType, supField, display, enter) => { |
| | | let _options = ['label', 'field', 'type', 'blacklist', 'writein', ...fromJS(modalTypeOptions[type]).toJS()] |
| | | |
| | | if (type === 'hint') { |
| | |
| | | } |
| | | } |
| | | |
| | | if (type === 'text' || type === 'number' || type === 'select' || type === 'link') { |
| | | if (enter === 'tab' || enter === 'sub') { |
| | | _options.push('tabField') |
| | | } |
| | | } |
| | | |
| | | if (type !== 'funcvar' && type !== 'linkMain') { |
| | | if (supField) { |
| | | _options.push('supField', 'supvalue') |
| | |
| | | |
| | | openTypeChange = (key, value) => { |
| | | if (key === 'type') { |
| | | let _options = this.getOptions(value, this.state.resourceType, this.state.supField, this.state.display) |
| | | let _options = this.getOptions(value, this.state.resourceType, this.state.supField, this.state.display, this.state.enter) |
| | | let fieldValue = {} |
| | | |
| | | this.setState({ |
| | |
| | | if (form.show) { |
| | | fieldValue.resourceType = form.initVal |
| | | } |
| | | } else if (form.key === 'enter') { |
| | | form.initVal = this.state.enter |
| | | } else if (form.key === 'linkSubField') { |
| | | form.initVal = this.state.linkSubFields.map(_field => _field.field) |
| | | |
| | |
| | | const { openType } = this.state |
| | | let value = e.target.value |
| | | if (key === 'resourceType') { |
| | | let _options = this.getOptions(openType, value, this.state.supField, this.state.display) |
| | | let _options = this.getOptions(openType, value, this.state.supField, this.state.display, this.state.enter) |
| | | |
| | | this.setState({ |
| | | resourceType: value, |
| | |
| | | }) |
| | | }) |
| | | } else if (key === 'display') { |
| | | let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, value) |
| | | let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, value, this.state.enter) |
| | | |
| | | this.setState({ |
| | | display: value, |
| | | formlist: this.state.formlist.map(form => { |
| | | form.show = _options.includes(form.key) |
| | | return form |
| | | }) |
| | | }) |
| | | } else if (key === 'enter') { |
| | | let _options = this.getOptions(openType, this.state.resourceType, this.state.supField, this.state.display, value) |
| | | |
| | | this.setState({ |
| | | enter: value, |
| | | formlist: this.state.formlist.map(form => { |
| | | form.show = _options.includes(form.key) |
| | | return form |
| | |
| | | onChange={(value) => {this.openTypeChange(item.key, value)}} |
| | | getPopupContainer={() => document.getElementById('modal-fields-form-box')} |
| | | > |
| | | {item.options.map(option => |
| | | <Select.Option id={option.value} title={option.text} key={option.value} value={option.value}> |
| | | {item.key === 'icon' && <Icon type={option.text} />} {option.text} |
| | | {item.options.map((option, i) => |
| | | <Select.Option key={`${i}`} value={option.value || option.field}> |
| | | {item.key === 'icon' && <Icon type={option.text} />} {option.text || option.label} |
| | | </Select.Option> |
| | | )} |
| | | </Select> |
| | |
| | | systemScripts: [], |
| | | columnsFields: [], |
| | | unionFields: [], |
| | | uniqueFields: [], // 唯一性验证,表单字段 |
| | | uniqueColumns: [ |
| | | { |
| | | title: '名称', |
| | |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '45%', |
| | | render: (text) => ( |
| | | <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> |
| | | ) |
| | | render: (text) => { |
| | | let title = text.match(/^\s*\/\*.+\*\//) |
| | | title = title && title[0] ? title[0] : '' |
| | | text = title ? text.replace(title, '') : text |
| | | |
| | | return ( |
| | | <div> |
| | | {title ? <span style={{color: '#a50'}}>{title}</span> : null} |
| | | <Paragraph copyable ellipsis={{ rows: 4, expandable: true }}>{text}</Paragraph> |
| | | </div> |
| | | ) |
| | | } |
| | | }, |
| | | { |
| | | title: '结果处理', |
| | |
| | | title: 'SQL', |
| | | dataIndex: 'sql', |
| | | width: '60%', |
| | | render: (text) => ( |
| | | <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> |
| | | ) |
| | | render: (text) => { |
| | | let title = text.match(/^\s*\/\*.+\*\//) |
| | | title = title && title[0] ? title[0] : '' |
| | | text = title ? text.replace(title, '') : text |
| | | |
| | | return ( |
| | | <div> |
| | | {title ? <span style={{color: '#a50'}}>{title}</span> : null} |
| | | <Paragraph copyable ellipsis={{ rows: 4, expandable: true }}>{text}</Paragraph> |
| | | </div> |
| | | ) |
| | | } |
| | | }, |
| | | { |
| | | title: '执行位置', |
| | |
| | | } |
| | | }) |
| | | |
| | | let uniqueFields = fromJS(_fields).toJS() |
| | | |
| | | if (!hasBid) { // 唯一性验证添加BID |
| | | uniqueFields.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' }) |
| | | } |
| | | |
| | | if (!hasBid && (card.sqlType === 'insert' || card.sqlType === 'insertOrUpdate')) { // 表单中增加BID |
| | | _fields.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' }) |
| | | fieldArr.push('bid') |
| | |
| | | } |
| | | |
| | | let unionFields = fromJS(_fields).toJS() |
| | | let formArr = _fields.map(_f => _f.field.toLowerCase()) |
| | | |
| | | if (hasColumn) { |
| | | columns.forEach(_f => { |
| | | if (_f.field && !formArr.includes(_f.field.toLowerCase())) { |
| | | formArr.push(_f.field.toLowerCase()) |
| | | unionFields.push(_f) |
| | | } |
| | | if (!_f.field || fieldArr.includes(_f.field.toLowerCase())) return |
| | | |
| | | fieldArr.push(_f.field.toLowerCase()) |
| | | |
| | | unionFields.push(_f) |
| | | _usefulfields.push(_f.field) |
| | | |
| | | if (_f.datatype) { // 自定义字段 |
| | |
| | | usefulfields: _usefulfields.join(', '), |
| | | uniqueColumns: this.state.uniqueColumns.map(col => { |
| | | if (col.dataIndex === 'field') { |
| | | col.options = _fields |
| | | col.options = uniqueFields |
| | | } |
| | | return col |
| | | }), |
| | |
| | | } |
| | | return col |
| | | }), |
| | | unionFields |
| | | unionFields, |
| | | uniqueFields |
| | | }) |
| | | }) |
| | | } |
| | |
| | | |
| | | render() { |
| | | const { card } = this.props |
| | | const { verify, fields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes } = this.state |
| | | const { verify, fields, uniqueFields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | } key="2"> |
| | | <UniqueForm |
| | | btn={card} |
| | | fields={card.Ot !== 'requiredOnce' ? fields : columnsFields} |
| | | fields={card.Ot !== 'requiredOnce' ? uniqueFields : columnsFields} |
| | | dict={this.props.dict} |
| | | uniqueChange={this.uniqueChange} |
| | | /> |
| | |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.action && item.action.forEach(btn => { |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | |
| | | |
| | | if (config.MenuType !== 'billPrint') { |
| | | btnParam.LText = this.getMenuMessage() |
| | | |
| | | btnParam.LText = btnParam.LText.join(' union all ') |
| | | btnParam.LText = Utils.formatOptions(btnParam.LText) |
| | | btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | Api.getSystemConfig(param).then(response => { |
| | | if (response.status) { |
| | | this.setState({ |
| | | oriConfig: fromJS(_config).toJS(), |
| | | openEdition: response.open_edition || '', |
| | | menuloading: false |
| | | }) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功', |
| | | duration: 2 |
| | | }) |
| | | return Api.getSystemConfig(param) |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | if (res.status) { |
| | | this.setState({ |
| | | oriConfig: fromJS(_config).toJS(), |
| | | openEdition: res.open_edition || '' |
| | | }) |
| | | |
| | | if (btnParam.LText) { |
| | | return Api.getSystemConfig(btnParam) |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: response.message, |
| | | duration: 5 |
| | | }) |
| | | return { |
| | | status: true |
| | | } |
| | | } |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | return false |
| | | } |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | if (res.status) { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功', |
| | | duration: 2 |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | } |