| | |
| | | } |
| | | |
| | | render () { |
| | | const { menuType } = this.props |
| | | const { tabviews } = this.state |
| | | let view = tabviews.filter(tab => tab.selected)[0] |
| | | this.resetWindow(view) |
| | |
| | | key={view.MenuID} |
| | | > |
| | | {this.selectcomponent(view)} |
| | | {options.sysType !== 'cloud' && !['CommonTable', 'TreePage', 'ManageTable', 'CalendarPage'].includes(view.type) ? |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' && !['CommonTable', 'TreePage', 'ManageTable', 'CalendarPage'].includes(view.type) ? |
| | | <Button |
| | | icon="copy" |
| | | shape="circle" |
| | |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | menuType: state.editLevel, |
| | | tabviews: state.tabviews, |
| | | collapse: state.collapse, |
| | | isiframe: state.isiframe |
| | |
| | | 'header.form.leftPicRightText': '左图右文', |
| | | 'model.form.selectItem.error': '下拉选项设置错误!', |
| | | 'header.form.request.method': '请求方式', |
| | | 'header.form.readonly': '是否只读', |
| | | 'header.form.readonly': '只读', |
| | | 'header.form.queryType': '查询类型', |
| | | 'header.form.query': '查询', |
| | | 'header.form.statistics': '统计', |
| | |
| | | 'header.form.leftPicRightText': '左图右文', |
| | | 'model.form.selectItem.error': '下拉选项设置错误!', |
| | | 'header.form.request.method': '请求方式', |
| | | 'header.form.readonly': '是否只读', |
| | | 'header.form.readonly': '只读', |
| | | 'header.form.queryType': '查询类型', |
| | | 'header.form.query': '查询', |
| | | 'header.form.statistics': '统计', |
| | |
| | | import { Icon, Popover, Button } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, profileCard, changeStyle }) => { |
| | | const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, profileCard, changeStyle, doubleClickCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'action', id, originalIndex }, |
| | |
| | | className={'mk-btn mk-' + card.class} |
| | | icon={card.icon} |
| | | style={card.btnstyle} |
| | | // onDoubleClick={() => doubleClickCard(id)} |
| | | > |
| | | {card.label} |
| | | </Button> |
| | |
| | | {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 ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width} onDoubleClick={() => doubleClickCard(id)}> |
| | | <div style={_style}> |
| | | {btnElement} |
| | | </div> |
| | | </div> |
| | | </Popover> |
| | | ) |
| | |
| | | <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}> |
| | | {getContent()} |
| | | <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width}> |
| | | <div style={_style}> |
| | | {getContent()} |
| | | </div> |
| | | </div> |
| | | </Popover> |
| | | ) |
| | |
| | | import Action from './action' |
| | | import './index.scss' |
| | | |
| | | const Container = ({list, handleList, handleMenu, deleteMenu, profileAction, handleStyle }) => { |
| | | const Container = ({list, handleList, handleMenu, deleteMenu, profileAction, handleStyle, handleSubConfig }) => { |
| | | const [cards, setCards] = useState(list) |
| | | const moveCard = (id, atIndex) => { |
| | | const { card, index } = findCard(id) |
| | |
| | | profileAction(card) |
| | | } |
| | | |
| | | const doubleClickCard = id => { |
| | | const { card } = findCard(id) |
| | | console.log(card) |
| | | if (card.OpenType === 'pop') { |
| | | handleSubConfig(card) |
| | | } |
| | | } |
| | | |
| | | const delCard = id => { |
| | | const { card } = findCard(id) |
| | | deleteMenu(card) |
| | |
| | | editCard={editCard} |
| | | changeStyle={changeStyle} |
| | | profileCard={profileCard} |
| | | doubleClickCard={doubleClickCard} |
| | | delCard={delCard} |
| | | findCard={findCard} |
| | | /> |
| | |
| | | import options from '@/store/options.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { getCardCellForm } from './formconfig' |
| | | import { getActionForm } from '@/menu/actioncomponent/formconfig' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import ElementForm from './elementform' |
| | | 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 |
| | | |
| | | const ActionForm = asyncComponent(() => import('@/menu/actioncomponent/actionform')) |
| | | const CreateFunc = asyncComponent(() => import('@/templates/zshare/createfunc')) |
| | | const VerifyCard = asyncComponent(() => import('@/templates/zshare/verifycard')) |
| | | const VerifyPrint = asyncComponent(() => import('@/menu/actioncomponent/verifyprint')) |
| | | const VerifyExcelIn = asyncComponent(() => import('@/menu/actioncomponent/verifyexcelin')) |
| | | const VerifyExcelOut = asyncComponent(() => import('@/menu/actioncomponent/verifyexcelout')) |
| | | // const ModalConfig = asyncComponent(() => import('@/menu/modalconfig')) |
| | | |
| | | class CardCellComponent extends Component { |
| | | static propTpyes = { |
| | |
| | | }) |
| | | } |
| | | |
| | | handleSubConfig = (item) => { |
| | | console.log(item) |
| | | } |
| | | |
| | | render() { |
| | | const { cards } = this.props |
| | | const { elements, visible, actvisible, profVisible, card, dict } = this.state |
| | |
| | | handleMenu={this.handleElement} |
| | | handleStyle={this.handleStyle} |
| | | profileAction={this.profileAction} |
| | | handleSubConfig={this.handleSubConfig} |
| | | deleteMenu={this.deleteElement} |
| | | /> |
| | | {/* <ModalConfig |
| | | menu={this.state.editMenu} |
| | | editTab={this.state.editTab} |
| | | tabConfig={this.state.tabConfig} |
| | | editSubTab={this.state.editSubTab} |
| | | subTabConfig={this.state.subTabConfig} |
| | | btnTab={this.state.btnTab} |
| | | btnTabConfig={this.state.btnTabConfig} |
| | | editAction={this.state.editAction} |
| | | subConfig={this.state.subConfig} |
| | | handleView={this.handleView} |
| | | /> */} |
| | | {/* 编辑按钮:复制、编辑 */} |
| | | <Modal |
| | | title={'编辑元素'} |
| | |
| | | } |
| | | } |
| | | } |
| | | .card-cell:hover { |
| | | box-shadow: 0px 0px 1px #d8d8d8; |
| | | .card-cell:hover, .card-button-cell:hover { |
| | | box-shadow: 0px 0px 1px #1890ff; |
| | | } |
| | | .ant-slider { |
| | | margin: 0px; |
| | |
| | | initVal: card.correction, |
| | | forbid: !['bar'].includes(card.chartType), |
| | | required: false |
| | | }, { |
| | | type: 'color', |
| | | key: 'color', |
| | | label: '色系', |
| | | initVal: card.color || 'rgba(0, 0, 0, 0.85)', |
| | | tooltip: '坐标轴及示例等提示文字使用的颜色。', |
| | | required: false, |
| | | options: [{ |
| | | value: 'black', |
| | | text: '黑色' |
| | | }, { |
| | | value: 'white', |
| | | text: '白色' |
| | | }] |
| | | } |
| | | ] |
| | | } |
| | |
| | | |
| | | import { getBarOrLineChartOptionForm } from './formconfig' |
| | | import { minkeColorSystem, colorTransform } from '@/utils/option.js' |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } else if (item.type === 'color') { |
| | | fields.push( |
| | | <Col span={12} key={index}> |
| | | <Form.Item label={item.tooltip ? |
| | | <Tooltip placement="topLeft" title={item.tooltip}> |
| | | <Icon type="question-circle" /> |
| | | {item.label} |
| | | </Tooltip> : item.label |
| | | }> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })( |
| | | <ColorSketch /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | ) |
| | | } |
| | | }) |
| | | return fields |
| | |
| | | .ant-tabs-nav-wrap { |
| | | text-align: center; |
| | | } |
| | | .color-sketch-block { |
| | | position: relative; |
| | | top: 5px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | name: _plot.name, |
| | | subtype: card.subtype, |
| | | setting: { interType: 'system' }, |
| | | style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' }, |
| | | style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px', fontSize: '16px' }, |
| | | columns: [], |
| | | scripts: [], |
| | | search: [], |
| | |
| | | componentDidMount () { |
| | | this.viewrender() |
| | | MKEmitter.addListener('tabsChange', this.handleTabsChange) |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | |
| | | return |
| | | } |
| | | MKEmitter.removeListener('tabsChange', this.handleTabsChange) |
| | | MKEmitter.removeListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | handleTabsChange = (parentId) => { |
| | |
| | | |
| | | linerender = () => { |
| | | const { card } = this.state |
| | | let plot = {...card.plot, height: card.plot.height - 70} // 去除title所占空间 |
| | | let plot = {...card.plot, height: card.plot.height - 80} // 去除title所占空间 |
| | | let color = plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | let transfield = {} |
| | | card.columns.forEach(col => { |
| | |
| | | }) |
| | | |
| | | chart.data(dv.rows) |
| | | |
| | | chart.axis(X_axis, { |
| | | label: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | }, |
| | | line: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | chart.axis('value', { |
| | | grid: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | }, |
| | | label: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (plot.coordinate !== 'polar') { |
| | | chart.scale(X_axis, { |
| | |
| | | chart.legend(false) |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend |
| | | position: plot.legend, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | |
| | | customrender = (data, transfield) => { |
| | | const { card } = this.state |
| | | let plot = {...card.plot, height: card.plot.height - 70} // 去除title所占空间 |
| | | let plot = {...card.plot, height: card.plot.height - 80} // 去除title所占空间 |
| | | let color = plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | let barfields = [] |
| | | let fields = [] |
| | |
| | | |
| | | chart.data(dv.rows) |
| | | |
| | | chart.axis(plot.Xaxis, { |
| | | label: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | }, |
| | | line: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | chart.axis('value', { |
| | | grid: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | }, |
| | | label: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (plot.coordinate !== 'polar' && barfields.length === 0) { |
| | | chart.scale(plot.Xaxis, { |
| | | range: [0, 1] |
| | |
| | | custom: true, |
| | | position: plot.legend, |
| | | items: legends, |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | chart.tooltip(false) |
| | | } else { |
| | | chart.tooltip({ |
| | | shared: true |
| | | shared: true, |
| | | }) |
| | | } |
| | | |
| | |
| | | |
| | | barrender = () => { |
| | | const { card } = this.state |
| | | let plot = {...card.plot, height: card.plot.height - 70} |
| | | let plot = {...card.plot, height: card.plot.height - 80} |
| | | let color = plot.color || 'rgba(0, 0, 0, 0.85)' |
| | | |
| | | let transfield = {} |
| | | card.columns.forEach(col => { |
| | |
| | | |
| | | chart.data(dv.rows) |
| | | |
| | | // chart.axis(X_axis, { |
| | | // label: { |
| | | // style: { |
| | | // fill: '#ffffff', |
| | | // } |
| | | // }, |
| | | // line: { |
| | | // style: { |
| | | // fill: '#ffffff', |
| | | // } |
| | | // } |
| | | // }) |
| | | // chart.axis('value', { |
| | | // grid: { |
| | | // style: { |
| | | // fill: '#ffffff', |
| | | // } |
| | | // }, |
| | | // label: { |
| | | // style: { |
| | | // fill: '#ffffff', |
| | | // } |
| | | // } |
| | | // }) |
| | | chart.axis(X_axis, { |
| | | label: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | }, |
| | | line: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | chart.axis('value', { |
| | | grid: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | }, |
| | | label: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | |
| | | chart.scale('value', { |
| | | nice: true |
| | |
| | | } else { |
| | | chart.legend({ |
| | | position: plot.legend, |
| | | // itemName: { |
| | | // style: { |
| | | // fill: '#ffffff', |
| | | // } |
| | | // } |
| | | itemName: { |
| | | style: { |
| | | fill: color, |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | MKEmitter.emit('addButton', card.uuid, newcard) |
| | | } |
| | | |
| | | changeStyle = () => { |
| | | const { card } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'border', 'padding', 'margin'], card.style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { card } = this.state |
| | | |
| | | if (comIds.length !== 1 || comIds[0] !== card.uuid) return |
| | | |
| | | let _card = {...card, style} |
| | | |
| | | this.setState({ |
| | | card: _card |
| | | }) |
| | | |
| | | this.props.updateConfig(_card) |
| | | } |
| | | |
| | | render() { |
| | | const { card } = this.state |
| | | |
| | |
| | | <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> |
| | | <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> |
| | | <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent}/> |
| | | </div> |
| | |
| | | updateaction={this.updateComponent} |
| | | /> |
| | | <div className="canvas" id={card.uuid}></div> |
| | | |
| | | </div> |
| | | ) |
| | | } |
| | |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | |
| | | .canvas { |
| | | margin: 0px; |
| | | padding: 10px 15px; |
| | | padding: 15px; |
| | | letter-spacing: 0px; |
| | | } |
| | | |
| | | .chart-header { |
| | |
| | | height: 45px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | overflow: hidden; |
| | | padding-right: 40px; |
| | | padding-right: 35px; |
| | | text-decoration: inherit; |
| | | font-weight: inherit; |
| | | font-style: inherit; |
| | | |
| | | >.anticon-tool { |
| | | position: absolute; |
| | | right: 0px; |
| | | top: 0px; |
| | | right: 1px; |
| | | top: 1px; |
| | | font-size: 16px; |
| | | padding: 10px; |
| | | padding: 5px; |
| | | cursor: pointer; |
| | | color: rgba(0, 0, 0, 0.85); |
| | | background: #ffffff; |
| | | } |
| | | |
| | | .chart-title { |
| | | font-size: 16px; |
| | | text-decoration: inherit; |
| | | font-weight: inherit; |
| | | font-style: inherit; |
| | | float: left; |
| | | line-height: 45px; |
| | | margin-left: 10px; |
| | |
| | | right: 0px; |
| | | z-index: 4; |
| | | padding-top: 10px; |
| | | font-size: 16px; |
| | | |
| | | .ant-row .anticon-plus { |
| | | float: right; |
| | |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('tabsChange', this.handleTabsChange) |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | /** |
| | |
| | | return |
| | | } |
| | | MKEmitter.removeListener('tabsChange', this.handleTabsChange) |
| | | MKEmitter.addListener('submitStyle', this.getStyle) |
| | | } |
| | | |
| | | changeStyle = () => { |
| | | const { tabs } = this.state |
| | | |
| | | MKEmitter.emit('changeStyle', [tabs.uuid], ['background', 'border', 'padding', 'margin'], tabs.style) |
| | | } |
| | | |
| | | getStyle = (comIds, style) => { |
| | | const { tabs } = this.state |
| | | |
| | | if (comIds.length !== 1 || comIds[0] !== tabs.uuid) return |
| | | |
| | | let _card = {...tabs, style} |
| | | |
| | | this.setState({ |
| | | tabs: _card |
| | | }) |
| | | |
| | | this.props.updateConfig(_card) |
| | | } |
| | | |
| | | handleTabsChange = (parentId) => { |
| | |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="添加标签" type="plus" onClick={this.tabAdd} /> |
| | | <SettingComponent config={tabs} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(tabs.uuid)} /> |
| | | </div> |
| | | } trigger="hover"> |
| | |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | |
| | | .ant-tabs-tabpane-active { |
| | | min-height: 200px; |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { DndProvider } from 'react-dnd' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import moment from 'moment' |
| | | import { Button, Card, Modal, Collapse, notification, Select, List, Icon, Empty, Popover } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/model.js' |
| | | import enUS from '@/locales/en-US/model.js' |
| | | import { getModalForm } from '@/templates/zshare/formconfig' |
| | | import { queryTableSql } from '@/utils/option.js' |
| | | |
| | | import ModalForm from '@/templates/zshare/modalform' |
| | | import DragElement from '@/templates/modalconfig/dragelement' |
| | | import SourceElement from '@/templates/modalconfig/dragelement/source' |
| | | import SettingForm from '@/templates/modalconfig/settingform' |
| | | import GroupForm from '@/templates/modalconfig/groupform' |
| | | import EditCard from '@/templates/modalconfig/editcard' |
| | | import MenuForm from '@/templates/modalconfig/menuform' |
| | | import EditComponent from '@/templates/zshare/editcomponent' |
| | | import { BaseConfig, SearchItems } from '@/templates/modalconfig/source' |
| | | import './index.scss' |
| | | |
| | | const { Panel } = Collapse |
| | | const { Option } = Select |
| | | const { confirm } = Modal |
| | | const CommonDict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS |
| | | |
| | | class ComModalConfig extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.any, |
| | | editTab: PropTypes.any, |
| | | editSubTab: PropTypes.any, |
| | | tabConfig: PropTypes.any, |
| | | subTabConfig: PropTypes.any, |
| | | btnTab: PropTypes.any, |
| | | btnTabConfig: PropTypes.any, |
| | | editAction: PropTypes.object, |
| | | subConfig: PropTypes.any, |
| | | handleView: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | menu: null, // 上级菜单,三级菜单或标签 |
| | | dict: CommonDict, // 字典 |
| | | config: null, // 页面配置,包括模板类型、模态框设置、添加表名、表单列表 |
| | | visible: false, // 表单编辑模态框,显示控制 |
| | | modalType: null, // 表单编辑类型,编辑或复制 |
| | | tableVisible: false, // 数据表字段列表模态框,显示控制 |
| | | tableColumns: [], // 表格字段名列表 |
| | | fields: null, // 表单,可选字段(去重后) |
| | | modalformlist: null, // 基本信息表单字段 |
| | | formlist: null, // 表单编辑模态框,可编辑字段 |
| | | card: null, // 编辑元素 |
| | | menuloading: false, // 菜单保存中 |
| | | closeloading: false, // 菜单保存中 |
| | | settingVisible: false, // 全局配置模态框 |
| | | closeVisible: false, // 关闭模态框 |
| | | tables: [], // 可用表名 |
| | | selectedTables: [], // 已选表名 |
| | | originConfig: null, // 原始菜单 |
| | | groupVisible: false, // 全局配置模态框 |
| | | curgroup: null, // 当前组,新建或编辑 |
| | | sources: null, // 表单类型 |
| | | sqlVerifing: false, // sql验证 |
| | | openEdition: '' // 编辑版本标记,防止多人操作 |
| | | } |
| | | |
| | | /** |
| | | * @description 数据预处理 |
| | | * 1、按钮配置存在时使用按钮配置,不存在时使用默认配置(示例) |
| | | * 2、模态框标题不存在时,使用按钮标题 |
| | | * 3、设置已选表 |
| | | * 4、设置按钮基本信息 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const {menu, editAction, tabConfig, subTabConfig, subConfig} = this.props |
| | | |
| | | let _config = '' |
| | | let _tab = subTabConfig ? subTabConfig : tabConfig |
| | | |
| | | let _menu = { // 上级菜单是三级菜单或标签页 |
| | | type: _tab ? _tab.Template : menu.type, |
| | | tables: _tab ? _tab.tables : menu.LongParam.tables, |
| | | MenuID: _tab ? _tab.uuid : menu.MenuID, |
| | | MenuNo: _tab ? _tab.tabNo : menu.MenuNo, |
| | | MenuName: _tab ? _tab.tabName : menu.MenuName |
| | | } |
| | | |
| | | if (subConfig) { |
| | | _config = subConfig |
| | | } else { |
| | | _config = JSON.parse(JSON.stringify(BaseConfig)) |
| | | } |
| | | |
| | | if (!_config.setting.title) { |
| | | _config.setting.title = editAction.label |
| | | } |
| | | |
| | | // 主菜单已有选择的表名,模态框没有表名时,复制主菜单表名 |
| | | _config.tables = _config.tables.length === 0 ? _menu.tables : _config.tables |
| | | |
| | | let _source = JSON.parse(JSON.stringify(SearchItems)) |
| | | if (!!this.props.editTab) { |
| | | _source.push({ |
| | | type: 'form', |
| | | label: this.state.dict['header.form.linkMain'], |
| | | subType: 'linkMain', |
| | | url: '' |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | openEdition: editAction.open_edition || '', |
| | | menu: _menu, |
| | | source: _source, |
| | | config: _config, |
| | | selectedTables: _config.tables || [], |
| | | originConfig: JSON.parse(JSON.stringify(_config)), |
| | | modalformlist: [ |
| | | { |
| | | type: 'text', |
| | | key: 'supMenu', |
| | | label: this.state.dict['model.super'] + this.state.dict['model.menu'], |
| | | initVal: _menu.MenuName, |
| | | required: true, |
| | | readonly: true |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'btnName', |
| | | label: '按钮名称', |
| | | initVal: editAction.label, |
| | | required: true, |
| | | readonly: true |
| | | } |
| | | ] |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 获取数据表信息 |
| | | * 1、获取系统中全部表名 |
| | | * 2、根据已选表名,获取表格字段列表 |
| | | */ |
| | | componentDidMount () { |
| | | let param = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: queryTableSql, |
| | | obj_name: 'data', |
| | | arr_field: 'TbName,Remark' |
| | | } |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp) // 云端数据验证 |
| | | |
| | | Api.getSystemConfig(param).then(res => { |
| | | if (res.status) { |
| | | this.setState({ |
| | | tables: res.data |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | let deffers = this.state.selectedTables.map(item => { |
| | | return new Promise(resolve => { |
| | | Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: item.TbName}).then(res => { |
| | | res.TBName = item.TbName |
| | | resolve(res) |
| | | }) |
| | | }) |
| | | }) |
| | | |
| | | // 获取字段后数据处理,根据类型分为text、number、datetime、date |
| | | Promise.all(deffers).then(response => { |
| | | let _columns = [] |
| | | response.forEach(res => { |
| | | if (res.status) { |
| | | let tabmsg = { |
| | | tableName: res.TBName, |
| | | columns: res.FDName.map(item => { |
| | | let _type = item.FieldType.toLowerCase() |
| | | let _decimal = 0 |
| | | if (/^nvarchar/.test(_type)) { |
| | | _type = 'text' |
| | | } else if (/^int/.test(_type)) { |
| | | _type = 'number' |
| | | } else if (/^decimal/.test(_type)) { |
| | | _decimal = _type.split(',')[1] |
| | | _decimal = parseInt(_decimal) |
| | | _type = 'number' |
| | | } else if (/^datetime/.test(_type)) { |
| | | _type = 'datetime' |
| | | } else if (/^date/.test(_type)) { |
| | | _type = 'date' |
| | | } else { |
| | | _type = 'text' |
| | | } |
| | | |
| | | return { |
| | | field: item.FieldName, |
| | | label: item.FieldDec, |
| | | type: _type, |
| | | decimal: _decimal |
| | | } |
| | | }) |
| | | } |
| | | _columns.push(tabmsg) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | tableColumns: _columns |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 页面返回 |
| | | handleViewBack = () => { |
| | | const {menu, editTab, editSubTab, tabConfig, subTabConfig, btnTab, btnTabConfig} = this.props |
| | | |
| | | let _view = (subTabConfig && subTabConfig.Template) || (tabConfig && tabConfig.Template) || menu.LongParam.Template |
| | | |
| | | let param = { |
| | | editMenu: menu, |
| | | editTab: editTab, |
| | | tabConfig: tabConfig, |
| | | editSubTab: editSubTab, |
| | | subTabConfig: subTabConfig, |
| | | btnTab: btnTab, |
| | | btnTabConfig: btnTabConfig, |
| | | editAction: null, |
| | | subConfig: subTabConfig || tabConfig || null, |
| | | tabview: _view |
| | | } |
| | | |
| | | this.props.handleView(param) |
| | | } |
| | | |
| | | /** |
| | | * @description 表单变化 |
| | | * 1、表单拖拽添加时,检查是否存在示例表单,如存在则去除示例 |
| | | * 2、表单移动后,保存移动后的顺序 |
| | | * 3、新增表单时,直接打开编辑框 |
| | | */ |
| | | handleList = (list, group, elementId, newcard) => { |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | |
| | | if (!group && !elementId) { |
| | | // 没有分组时(拖拽添加) |
| | | if (list.length > _config.fields.length) { |
| | | _config.fields = list.filter(item => !item.origin) |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }, () => { |
| | | this.handleForm(newcard) |
| | | }) |
| | | } else { |
| | | _config.fields = list |
| | | this.setState({config: _config}) |
| | | } |
| | | } else if (group && !elementId) { |
| | | // 存在分组时,拖拽添加 |
| | | if (list.length > group.sublist.length) { |
| | | group.sublist = list |
| | | _config.groups = _config.groups.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }, () => { |
| | | this.handleForm(newcard) |
| | | }) |
| | | } else { |
| | | group.sublist = list |
| | | _config.groups = _config.groups.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | this.setState({config: _config}) |
| | | } |
| | | } else if (group && elementId) { |
| | | // 修改已有元素的分组 |
| | | let element = null |
| | | _config.groups.forEach(item => { |
| | | item.sublist = item.sublist.filter(cell => { |
| | | if (cell.uuid !== elementId) { |
| | | return true |
| | | } else { |
| | | element = cell |
| | | return false |
| | | } |
| | | }) |
| | | }) |
| | | |
| | | group.sublist.push(element) |
| | | |
| | | _config.groups = _config.groups.map(item => { |
| | | if (item.uuid === group.uuid) { |
| | | return group |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 表单编辑 |
| | | * 1、显示编辑弹窗-visible |
| | | * 2、保存编辑项-card |
| | | * 3、设置编辑参数项-formlist |
| | | */ |
| | | handleForm = (_card, type) => { |
| | | const {menu, tabConfig, subTabConfig} = this.props |
| | | let card = JSON.parse(JSON.stringify(_card)) |
| | | |
| | | if (type === 'copy') { |
| | | card.originUuid = card.uuid |
| | | card.uuid = Utils.getuuid() |
| | | card.focus = true |
| | | |
| | | // 复制到剪切板 |
| | | let oInput = document.createElement('input') |
| | | let val = JSON.parse(JSON.stringify(card)) |
| | | val.copyType = 'form' |
| | | val.uuid = Utils.getuuid() |
| | | |
| | | delete val.originUuid |
| | | |
| | | oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val))) |
| | | document.body.appendChild(oInput) |
| | | oInput.select() |
| | | document.execCommand('Copy') |
| | | oInput.className = 'oInput' |
| | | oInput.style.display = 'none' |
| | | document.body.removeChild(oInput) |
| | | } |
| | | |
| | | const { config } = this.state |
| | | let _inputfields = [] |
| | | let _linkableFields = [] |
| | | let _linksupFields = [{ |
| | | value: '', |
| | | text: '空' |
| | | }] |
| | | let _formfields = [] |
| | | |
| | | // 设置下拉菜单可关联字段(上级与下级) |
| | | 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] |
| | | }) |
| | | } else { |
| | | _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number') |
| | | |
| | | _formfields = config.fields.filter(item => item.type === 'select' || item.type === 'link') |
| | | } |
| | | |
| | | let uniq = new Map() |
| | | uniq.set(card.field, true) |
| | | _formfields.forEach(item => { |
| | | if (item.field && !uniq.has(item.field)) { |
| | | uniq.set(item.field, true) |
| | | |
| | | _linkableFields.push({ |
| | | value: item.field, |
| | | text: item.label + ' (表单)' |
| | | }) |
| | | _linksupFields.push({ |
| | | value: item.field, |
| | | text: item.label |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | if (subTabConfig) { |
| | | subTabConfig.columns.forEach(col => { |
| | | if (col.field && !uniq.has(col.field)) { |
| | | uniq.set(col.field, true) |
| | | |
| | | _linkableFields.push({ |
| | | value: col.field, |
| | | text: col.label + ' (显示列)' |
| | | }) |
| | | } |
| | | }) |
| | | } else if (tabConfig) { |
| | | tabConfig.columns.forEach(col => { |
| | | if (col.field && !uniq.has(col.field)) { |
| | | uniq.set(col.field, true) |
| | | |
| | | _linkableFields.push({ |
| | | value: col.field, |
| | | text: col.label + ' (显示列)' |
| | | }) |
| | | } |
| | | }) |
| | | } else if (menu.LongParam) { |
| | | menu.LongParam.columns.forEach(col => { |
| | | if (col.field && !uniq.has(col.field)) { |
| | | uniq.set(col.field, true) |
| | | |
| | | _linkableFields.push({ |
| | | value: col.field, |
| | | text: col.label + ' (显示列)' |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (card.linkSubField && card.linkSubField.length > 0) { |
| | | let fields = _inputfields.map(item => item.field) |
| | | card.linkSubField = card.linkSubField.filter(item => fields.includes(item)) |
| | | } |
| | | |
| | | let roleList = [] |
| | | if (this.props.sysRoles && this.props.sysRoles.length > 0) { |
| | | roleList = this.props.sysRoles.map(role => { |
| | | return { |
| | | uuid: role.uuid, |
| | | field: role.value, |
| | | label: role.text |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | modalType: type, |
| | | card: card, |
| | | formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, !!this.props.editTab, roleList) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 编辑后提交 |
| | | * 1、获取编辑后的表单信息 |
| | | * 2、去除可能存在的示例表单 |
| | | * 3、通过loading刷新 |
| | | */ |
| | | handleSubmit = () => { |
| | | const { card, modalType } = this.state |
| | | |
| | | this.formRef.handleConfirm().then(res => { |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | let fieldrepet = false // 字段重复 |
| | | let labelrepet = false // 提示文字重复 |
| | | |
| | | if (modalType === 'copy' && card.originUuid) { |
| | | if (_config.groups.length > 0) { |
| | | _config.groups = _config.groups.map(group => { |
| | | let _index = null |
| | | group.sublist.forEach((item, index) => { |
| | | if (item.uuid === card.originUuid) { |
| | | _index = index |
| | | } |
| | | |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | }) |
| | | |
| | | if (_index !== null) { |
| | | group.sublist.splice(_index + 1, 0, res) |
| | | } |
| | | |
| | | return group |
| | | }) |
| | | } else { |
| | | let _index = null |
| | | _config.fields.forEach((item, index) => { |
| | | if (item.uuid === card.originUuid) { |
| | | _index = index |
| | | } |
| | | |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | }) |
| | | |
| | | _config.fields.splice(_index + 1, 0, res) |
| | | } |
| | | } else { |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist = group.sublist.map(item => { |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | _config.fields = _config.fields.map(item => { |
| | | if (item.uuid !== res.uuid && item.field === res.field) { |
| | | fieldrepet = true |
| | | } else if (item.uuid !== res.uuid && item.label === res.label) { |
| | | labelrepet = true |
| | | } |
| | | |
| | | if (item.uuid === res.uuid) { |
| | | return res |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | if (fieldrepet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '字段已存在!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } else if (labelrepet) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '名称已存在!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | _config.fields = _config.fields.filter(item => !item.origin) |
| | | |
| | | if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) { |
| | | this.setState({ |
| | | sqlVerifing: true |
| | | }) |
| | | |
| | | let param = { |
| | | func: 's_debug_sql', |
| | | LText: res.dataSource |
| | | } |
| | | |
| | | param.LText = param.LText.replace(/@\$|\$@/ig, '') |
| | | |
| | | param.LText = Utils.formatOptions(param.LText) |
| | | param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | param.secretkey = Utils.encrypt(param.LText, param.timestamp) |
| | | |
| | | if (window.GLOB.mainSystemApi && res.database === 'sso') { |
| | | param.rduri = window.GLOB.mainSystemApi |
| | | } |
| | | |
| | | Api.getLocalConfig(param).then(result => { |
| | | if (result.status) { |
| | | this.setState({ |
| | | sqlVerifing: false, |
| | | config: _config, |
| | | modalType: null, |
| | | card: null, |
| | | visible: false |
| | | }) |
| | | } else { |
| | | this.setState({sqlVerifing: false}) |
| | | |
| | | Modal.error({ |
| | | title: result.message |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | config: _config, |
| | | modalType: null, |
| | | card: null, |
| | | visible: false |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 表单删除并刷新 |
| | | */ |
| | | closeForm = (card) => { |
| | | let _this = this |
| | | |
| | | confirm({ |
| | | content: `确定删除<<${card.label}>>吗?`, |
| | | onOk() { |
| | | let _config = JSON.parse(JSON.stringify(_this.state.config)) |
| | | |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist = group.sublist.filter(item => !(item.uuid === card.uuid)) |
| | | }) |
| | | } else { |
| | | _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid)) |
| | | } |
| | | |
| | | _this.setState({ |
| | | config: _config, |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { editAction } = this.props |
| | | const { config, menu, openEdition } = this.state |
| | | |
| | | if ((!config.groups[0] && !config.fields[0]) || (config.fields[0] && config.fields[0].origin)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请添加表单', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let _LongParam = '' |
| | | let _config = {...config, tables: this.state.selectedTables} |
| | | |
| | | try { |
| | | _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_config))) |
| | | } catch (e) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '编译错误', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let param = { |
| | | func: 'sPC_ButtonParam_AddUpt', |
| | | ParentID: menu.MenuID, |
| | | MenuID: editAction.uuid, |
| | | MenuNo: menu.MenuNo, |
| | | Template: 'Modal', |
| | | MenuName: editAction.label, |
| | | PageParam: JSON.stringify({Template: 'Modal'}), |
| | | LongParam: _LongParam |
| | | } |
| | | |
| | | if (openEdition) { |
| | | param.open_edition = openEdition |
| | | } |
| | | |
| | | if (this.state.closeVisible) { |
| | | this.setState({ |
| | | closeloading: true |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | menuloading: true |
| | | }) |
| | | } |
| | | |
| | | Api.getSystemConfig(param).then(response => { |
| | | if (response.status) { |
| | | this.setState({ |
| | | openEdition: response.open_edition || '', |
| | | menuloading: false, |
| | | closeloading: false, |
| | | closeVisible: false, |
| | | originConfig: _config, |
| | | config: _config |
| | | }) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功', |
| | | duration: 2 |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | closeloading: false, |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: response.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | cancelConfig = () => { |
| | | const { config, originConfig } = this.state |
| | | let _this = this |
| | | |
| | | let isOrigin = config.fields.filter(item => item.origin).length > 0 |
| | | if (isOrigin) { |
| | | confirm({ |
| | | content: '尚未提交,确定放弃保存吗?', |
| | | onOk() { |
| | | _this.handleViewBack() |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | |
| | | if (!is(fromJS(config), fromJS(originConfig))) { |
| | | this.setState({ |
| | | closeVisible: true |
| | | }) |
| | | } else { |
| | | this.handleViewBack() |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 通过表字段添加表单 |
| | | * 1、检查是否已选表名,为选时警告提示 |
| | | * 2、表字段名通过map去重 |
| | | * 3、检查表单中的已选字段,并标记已选 |
| | | */ |
| | | queryField = () => { |
| | | const {selectedTables, tableColumns, config} = this.state |
| | | if (selectedTables.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请选择表名!', |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let columns = new Map() |
| | | tableColumns.forEach(table => { |
| | | table.columns.forEach(column => { |
| | | columns.set(column.field, column) |
| | | }) |
| | | }) |
| | | |
| | | if (config.groups.length > 1) { |
| | | config.groups.forEach(group => { |
| | | group.sublist.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | columns.set(item.field, {...item, selected: true}) |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | config.fields.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | columns.set(item.field, {...item, selected: true}) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.setState({ |
| | | tableVisible: true, |
| | | fields: [...columns.values()] |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 选择字段后提交 |
| | | * 1、没有可选字段时,直接关闭 |
| | | * 2、获取已选字段 |
| | | * 3、与已有字段对比 |
| | | * 4、添加新增字段 |
| | | */ |
| | | addFieldSubmit = () => { |
| | | if (!this.state.fields || this.state.fields.length === 0) { |
| | | this.setState({ |
| | | tableVisible: false |
| | | }) |
| | | } |
| | | |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | |
| | | let cards = this.refs.searchcard.state.selectCards |
| | | let columns = new Map() |
| | | cards.forEach(card => { |
| | | columns.set(card.field, card) |
| | | }) |
| | | |
| | | if (_config.groups.length > 1) { |
| | | _config.groups.forEach(group => { |
| | | let items = [] |
| | | group.sublist.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | let cell = columns.get(item.field) |
| | | |
| | | if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加 |
| | | items.push(item) |
| | | } else if (cell.selected) { // 数据类型修改时,重置类型及初始值 |
| | | item.type = cell.type |
| | | item.initval = '' |
| | | items.push(item) |
| | | } |
| | | columns.delete(item.field) |
| | | } else if (!item.origin) { // 过滤示例项 |
| | | items.push(item) |
| | | } |
| | | }) |
| | | group.sublist = items |
| | | }) |
| | | |
| | | let _columns = [...columns.values()] |
| | | |
| | | let _additems = _columns.map(item => { // 循环添加新增字段 |
| | | return { |
| | | uuid: Utils.getuuid(), |
| | | label: item.label, |
| | | field: item.field, |
| | | initval: '', |
| | | type: item.type, |
| | | resourceType: '0', |
| | | setAll: 'false', |
| | | options: [], |
| | | dataSource: '', |
| | | linkField: '', |
| | | valueField: '', |
| | | valueText: '', |
| | | orderBy: '', |
| | | orderType: 'asc', |
| | | decimal: 0, |
| | | min: '', |
| | | max: '', |
| | | readonly: 'false', |
| | | required: 'true' |
| | | } |
| | | }) |
| | | _config.groups[_config.groups.length - 1].sublist = [..._config.groups[_config.groups.length - 1].sublist, ..._additems] |
| | | |
| | | } else { |
| | | let items = [] |
| | | _config.fields.forEach(item => { |
| | | if (columns.has(item.field)) { |
| | | let cell = columns.get(item.field) |
| | | |
| | | if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加 |
| | | items.push(item) |
| | | } else if (cell.selected) { // 数据类型修改时,重置类型及初始值 |
| | | item.type = cell.type |
| | | item.initval = '' |
| | | items.push(item) |
| | | } |
| | | columns.delete(item.field) |
| | | } else if (!item.origin) { // 过滤示例项 |
| | | items.push(item) |
| | | } |
| | | }) |
| | | |
| | | let _columns = [...columns.values()] |
| | | |
| | | _columns.forEach(item => { // 循环添加新增字段 |
| | | if (item.selected) { |
| | | let newcard = { |
| | | uuid: Utils.getuuid(), |
| | | label: item.label, |
| | | field: item.field, |
| | | initval: '', |
| | | type: item.type, |
| | | resourceType: '0', |
| | | setAll: 'false', |
| | | options: [], |
| | | dataSource: '', |
| | | linkField: '', |
| | | valueField: '', |
| | | valueText: '', |
| | | orderBy: '', |
| | | orderType: 'asc', |
| | | readonly: 'false', |
| | | required: 'true' |
| | | } |
| | | |
| | | items.push(newcard) |
| | | } |
| | | }) |
| | | |
| | | _config.fields = items |
| | | } |
| | | |
| | | this.setState({ |
| | | config: _config |
| | | }) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '添加成功', |
| | | duration: 2 |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 添加表名 |
| | | * 1、获取表信息 |
| | | * 2、检验是否已经添加,已添加时跳过 |
| | | * 3、通过表名获取字段集,并设置数据类型 |
| | | */ |
| | | onTableChange = (value) => { |
| | | const {tables, selectedTables, tableColumns} = this.state |
| | | |
| | | let _table = tables.filter(item => item.TbName === value)[0] |
| | | let isSelected = !!selectedTables.filter(cell => cell.TbName === value)[0] |
| | | |
| | | if (isSelected) return |
| | | |
| | | this.setState({ |
| | | selectedTables: [...selectedTables, _table] |
| | | }) |
| | | Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: value}).then(res => { |
| | | if (res.status) { |
| | | let tabmsg = { |
| | | tableName: _table.name, |
| | | columns: res.FDName.map(item => { |
| | | let _type = item.FieldType.toLowerCase() |
| | | let _decimal = 0 |
| | | if (/^nvarchar/.test(_type)) { |
| | | _type = 'text' |
| | | } else if (/^int/.test(_type)) { |
| | | _type = 'number' |
| | | } else if (/^decimal/.test(_type)) { |
| | | _decimal = _type.split(',')[1] |
| | | _decimal = parseInt(_decimal) |
| | | _type = 'number' |
| | | } else if (/^datetime/.test(_type)) { |
| | | _type = 'datetime' |
| | | } else if (/^date/.test(_type)) { |
| | | _type = 'date' |
| | | } else { |
| | | _type = 'text' |
| | | } |
| | | |
| | | return { |
| | | field: item.FieldName, |
| | | label: item.FieldDec, |
| | | type: _type, |
| | | decimal: _decimal |
| | | } |
| | | }) |
| | | } |
| | | this.setState({ |
| | | tableColumns: [...tableColumns, tabmsg] |
| | | }) |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 删除表名,删除对应字段集 |
| | | */ |
| | | deleteTable = (table) => { |
| | | const {selectedTables, tableColumns} = this.state |
| | | |
| | | this.setState({ |
| | | selectedTables: selectedTables.filter(item => item.TbName !== table.TbName), |
| | | tableColumns: tableColumns.filter(item => item.tableName !== table.TbName) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 全局设置模态框 |
| | | */ |
| | | changeSetting = () => { |
| | | this.setState({ |
| | | settingVisible: true |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 保存全局设置 |
| | | */ |
| | | settingSave = () => { |
| | | const {config} = this.state |
| | | this.settingRef.handleConfirm().then(res => { |
| | | this.setState({ |
| | | config: {...config, setting: res}, |
| | | settingVisible: false |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | handleGroup = (group) => { |
| | | let curgroup = '' |
| | | |
| | | if (group) { |
| | | curgroup = group |
| | | } else { |
| | | curgroup = { |
| | | isnew: true, |
| | | label: '', |
| | | default: false, |
| | | uuid: Utils.getuuid(), |
| | | sublist: [] |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | | groupVisible: true, |
| | | curgroup: curgroup |
| | | }) |
| | | } |
| | | |
| | | closeGroup = (group) => { |
| | | let _this = this |
| | | |
| | | confirm({ |
| | | content: `确定删除分组<<${group.label}>>吗?`, |
| | | onOk() { |
| | | let _config = JSON.parse(JSON.stringify(_this.state.config)) |
| | | _config.groups = _config.groups.filter(item => !(item.uuid === group.uuid)) |
| | | let _length = _config.groups.length |
| | | |
| | | if (_length === 1) { |
| | | _config.fields = [...group.sublist, ..._config.groups[0].sublist] |
| | | _config.groups = [] |
| | | } else { |
| | | _config.groups[_length - 1].sublist = [...group.sublist, ..._config.groups[_length - 1].sublist] |
| | | } |
| | | |
| | | _this.setState({ |
| | | config: _config |
| | | }) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | handleGroupSave = () => { |
| | | let _group = JSON.parse(JSON.stringify(this.state.curgroup)) |
| | | let config = JSON.parse(JSON.stringify(this.state.config)) |
| | | |
| | | this.groupRef.handleConfirm().then(res => { |
| | | _group = {..._group, ...res.target} |
| | | |
| | | if (_group.isnew) { |
| | | delete _group.isnew |
| | | config.groups.unshift(_group) |
| | | |
| | | if (config.groups.length > 1) { |
| | | config.groups = config.groups.map(item => { |
| | | if (item.default) { |
| | | return res.default |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } else { |
| | | config.groups.push(res.default) |
| | | } |
| | | } else { |
| | | config.groups = config.groups.map(item => { |
| | | if (item.uuid === _group.uuid) { |
| | | return _group |
| | | } else if (item.default) { |
| | | return res.default |
| | | } else { |
| | | return item |
| | | } |
| | | }) |
| | | } |
| | | |
| | | config.fields = [] |
| | | |
| | | config.groups = config.groups.sort((a, b) => { |
| | | return a.sort - b.sort |
| | | }) |
| | | |
| | | this.setState({ |
| | | groupVisible: false, |
| | | curgroup: '', |
| | | config: config |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | editModalCancel = () => { |
| | | const { config, card } = this.state |
| | | |
| | | if (card.focus) { |
| | | let _config = null |
| | | if (config.groups.length > 0) { |
| | | let _groups = config.groups.map(group => { |
| | | group.sublist = group.sublist.filter(item => item.uuid !== card.uuid) |
| | | return group |
| | | }) |
| | | _config = {...config, groups: _groups} |
| | | } else { |
| | | let _fields = config.fields.filter(item => item.uuid !== card.uuid) |
| | | _config = {...config, fields: _fields} |
| | | } |
| | | |
| | | this.setState({ |
| | | card: null, |
| | | config: _config, |
| | | visible: false |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | card: null, |
| | | visible: false |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 编辑功能完成更新,包括解冻按钮、粘贴、替换等 |
| | | */ |
| | | updateConfig = (res) => { |
| | | if (res.type === 'paste') { |
| | | this.setState({ |
| | | config: res.content |
| | | }) |
| | | } |
| | | } |
| | | |
| | | render () { |
| | | const { config, source } = this.state |
| | | |
| | | return ( |
| | | <div className="modal-form-board"> |
| | | <DndProvider backend={HTML5Backend}> |
| | | <div className="tools"> |
| | | <Collapse accordion defaultActiveKey="1" bordered={false}> |
| | | <Panel header={this.state.dict['header.menu.basedata']} key="0" id="modal-basedata"> |
| | | <MenuForm |
| | | dict={this.state.dict} |
| | | formlist={this.state.modalformlist} |
| | | /> |
| | | <div className="ant-col ant-form-item-label"> |
| | | <label title={this.state.dict['header.menu.table.add']}> |
| | | {this.state.dict['header.menu.table.add']} |
| | | </label> |
| | | </div> |
| | | <Select |
| | | showSearch |
| | | showArrow={false} |
| | | className="tables" |
| | | style={{ width: '100%' }} |
| | | optionFilterProp="children" |
| | | value={this.state.dict['header.menu.table.placeholder']} |
| | | onChange={this.onTableChange} |
| | | getPopupContainer={() => document.getElementById('modal-basedata')} |
| | | filterOption={(input, option) => { |
| | | return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 |
| | | }} |
| | | > |
| | | {this.state.tables.map((table, index) => ( |
| | | <Option key={index} title={table.TbName} value={table.TbName}>{table.Remark}</Option> |
| | | ))} |
| | | </Select> |
| | | {this.state.selectedTables.length > 0 && <List |
| | | size="small" |
| | | bordered |
| | | dataSource={this.state.selectedTables} |
| | | renderItem={(item, index) => <List.Item key={index} title={item.Remark + ' (' + item.TbName + ')'}> |
| | | {item.Remark + ' (' + item.TbName + ')'} |
| | | <Icon type="close" onClick={() => this.deleteTable(item)}/> |
| | | <div className="bottom-mask"></div> |
| | | </List.Item>} |
| | | />} |
| | | </Panel> |
| | | <Panel header={this.state.dict['header.menu.form']} key="1"> |
| | | <div className="search-element"> |
| | | {source.map((item, index) => { |
| | | return (<SourceElement key={index} content={item}/>) |
| | | })} |
| | | </div> |
| | | <Button type="primary" block onClick={() => this.queryField()}>{this.state.dict['header.menu.form.add']}</Button> |
| | | <Button type="primary" block onClick={() => this.handleGroup()}>{this.state.dict['header.menu.group.add']}</Button> |
| | | </Panel> |
| | | </Collapse> |
| | | </div> |
| | | <div className="setting"> |
| | | <Card title={this.state.dict['header.menu.form.configurable']} bordered={false} extra={ |
| | | <div> |
| | | <EditComponent dict={this.state.dict} type="form" config={this.state.config} refresh={this.updateConfig}/> |
| | | <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button> |
| | | <Button onClick={this.cancelConfig}>{this.state.dict['model.back']}</Button> |
| | | </div> |
| | | } style={{ width: '100%' }}> |
| | | <Icon type="setting" onClick={this.changeSetting} /> |
| | | <div className="ant-modal-content" style={{width: config.setting.width + '%'}}> |
| | | <button type="button" className="ant-modal-close"> |
| | | <span className="ant-modal-close-x"><Icon type="close"/></span> |
| | | </button> |
| | | <div className="ant-modal-header"> |
| | | <div className="ant-modal-title">{config.setting.title}</div> |
| | | </div> |
| | | <div className="ant-modal-body"> |
| | | <div className="modal-form"> |
| | | {config.groups.length > 0 && |
| | | config.groups.map(group => { |
| | | return ( |
| | | <div key={group.uuid}> |
| | | <div className="group-title"> |
| | | {!group.default ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="edit" type="edit" onClick={() => {this.handleGroup(group)}} /> |
| | | <Icon className="edit close" type="close" onClick={() => {this.closeGroup(group)}} /> |
| | | </div> |
| | | } trigger="hover"> |
| | | <span>{group.label}</span> |
| | | </Popover> : null} |
| | | {group.default ? <span style={{color: '#bcbcbc'}}>{group.label}</span> : null} |
| | | </div> |
| | | <DragElement |
| | | group={group} |
| | | list={group.sublist} |
| | | setting={config.setting} |
| | | placeholder={this.state.dict['header.form.modal.placeholder']} |
| | | handleList={this.handleList} |
| | | handleForm={this.handleForm} |
| | | closeForm={this.closeForm} |
| | | /> |
| | | </div> |
| | | ) |
| | | }) |
| | | } |
| | | {config.groups.length === 0 ? |
| | | <DragElement |
| | | list={config.fields} |
| | | setting={config.setting} |
| | | placeholder={this.state.dict['header.form.modal.placeholder']} |
| | | handleList={this.handleList} |
| | | handleForm={this.handleForm} |
| | | closeForm={this.closeForm} |
| | | /> : null |
| | | } |
| | | </div> |
| | | </div> |
| | | <div className="ant-modal-footer"> |
| | | <div> |
| | | <button type="button" className="ant-btn"> |
| | | <span>{this.state.dict['model.cancel']}</span> |
| | | </button> |
| | | <button type="button" className="ant-btn ant-btn-primary"> |
| | | <span>{this.state.dict['model.confirm']}</span> |
| | | </button> |
| | | </div> |
| | | <div className="action-mask"></div> |
| | | </div> |
| | | </div> |
| | | </Card> |
| | | </div> |
| | | </DndProvider> |
| | | <Modal |
| | | title={this.state.modalType !== 'copy' ? this.state.dict['model.edit'] : this.state.dict['header.modal.form.copy']} |
| | | visible={this.state.visible} |
| | | width={700} |
| | | onCancel={this.editModalCancel} |
| | | onOk={this.handleSubmit} |
| | | confirmLoading={this.state.sqlVerifing} |
| | | destroyOnClose |
| | | > |
| | | {<ModalForm |
| | | dict={this.state.dict} |
| | | card={this.state.card} |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | wrappedComponentRef={(inst) => this.formRef = inst} |
| | | />} |
| | | </Modal> |
| | | <Modal |
| | | wrapClassName="modal-fields" |
| | | title={this.state.dict['model.edit']} |
| | | visible={this.state.tableVisible} |
| | | width={'65vw'} |
| | | maskClosable={false} |
| | | style={{minWidth: '900px', maxWidth: '1200px'}} |
| | | onOk={this.addFieldSubmit} |
| | | cancelText={this.state.dict['model.close']} |
| | | onCancel={() => { this.setState({ tableVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | {this.state.fields && this.state.fields.length > 0 ? |
| | | <EditCard data={this.state.fields} ref="searchcard" type="search" /> : null |
| | | } |
| | | {(!this.state.fields || this.state.fields.length === 0) && |
| | | <Empty /> |
| | | } |
| | | </Modal> |
| | | <Modal |
| | | title={this.state.dict['model.edit']} |
| | | visible={this.state.settingVisible} |
| | | width={700} |
| | | maskClosable={false} |
| | | onOk={this.settingSave} |
| | | onCancel={() => { this.setState({ settingVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <SettingForm |
| | | config={config} |
| | | dict={this.state.dict} |
| | | isSubTab={!!this.props.editTab} |
| | | inputSubmit={this.settingSave} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | | /> |
| | | </Modal> |
| | | <Modal |
| | | bodyStyle={{textAlign: 'center', color: '#000000', fontSize: '16px'}} |
| | | closable={false} |
| | | maskClosable={false} |
| | | visible={this.state.closeVisible} |
| | | onCancel={() => { this.setState({closeVisible: false}) }} |
| | | footer={[ |
| | | <Button key="save" className="mk-btn mk-green" loading={this.state.closeloading} onClick={this.submitConfig}>{this.state.dict['model.save']}</Button>, |
| | | <Button key="confirm" className="mk-btn mk-yellow" onClick={this.handleViewBack}>{this.state.dict['model.notsave']}</Button>, |
| | | <Button key="cancel" onClick={() => { this.setState({closeVisible: false}) }}>{this.state.dict['model.cancel']}</Button> |
| | | ]} |
| | | destroyOnClose |
| | | > |
| | | {this.state.dict['header.menu.config.placeholder']} |
| | | </Modal> |
| | | <Modal |
| | | title={this.state.dict['header.menu.group.manage']} |
| | | visible={this.state.groupVisible} |
| | | width={700} |
| | | maskClosable={false} |
| | | onOk={this.handleGroupSave} |
| | | onCancel={() => { this.setState({ groupVisible: false }) }} |
| | | destroyOnClose |
| | | > |
| | | <GroupForm |
| | | config={config} |
| | | dict={this.state.dict} |
| | | group={this.state.curgroup} |
| | | inputSubmit={this.handleGroupSave} |
| | | wrappedComponentRef={(inst) => this.groupRef = inst} |
| | | /> |
| | | </Modal> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | sysRoles: state.sysRoles |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(ComModalConfig) |
New file |
| | |
| | | .modal-form-board { |
| | | position: fixed; |
| | | z-index: 1070; |
| | | padding-top: 48px; |
| | | top: 0px; |
| | | left: 0px; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | background: rgba(0, 0, 0, 0.35); |
| | | display: flex; |
| | | .tools { |
| | | flex: 1; |
| | | background: #ffffff; |
| | | border-right: 1px solid #d9d9d9; |
| | | height: 100%; |
| | | overflow-y: auto; |
| | | padding-bottom: 30px; |
| | | .ant-collapse-item { |
| | | border: 0; |
| | | } |
| | | .ant-input-search { |
| | | margin-top: 10px; |
| | | } |
| | | .ant-collapse-item.ant-collapse-item-active { |
| | | border-bottom: 1px solid #d9d9d9; |
| | | } |
| | | .ant-collapse .ant-collapse-header { |
| | | padding: 11px 16px 10px 40px; |
| | | border-bottom: 1px solid #d9d9d9; |
| | | background: #1890ff; |
| | | color: #ffffff; |
| | | } |
| | | .ant-collapse-content-box { |
| | | .ant-form-item { |
| | | margin-bottom: 10px; |
| | | .ant-form-item-label { |
| | | text-align: left; |
| | | height: 25px; |
| | | line-height: 25px; |
| | | } |
| | | } |
| | | .ant-btn { |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | .search-element { |
| | | padding-top: 10px; |
| | | li { |
| | | padding: 0px 16px 10px; |
| | | div { |
| | | cursor: move; |
| | | } |
| | | } |
| | | } |
| | | .tables { |
| | | .ant-select-selection-selected-value { |
| | | opacity: 0.4!important; |
| | | } |
| | | } |
| | | .ant-list { |
| | | margin-top: 20px; |
| | | .ant-list-item { |
| | | display: -webkit-box; |
| | | padding-right: 20px; |
| | | position: relative; |
| | | padding-left: 5px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | -webkit-line-clamp: 2; |
| | | -webkit-box-orient: vertical; |
| | | width: 100%; |
| | | .anticon { |
| | | position: absolute; |
| | | top: 0px; |
| | | right: 0px; |
| | | padding: 3px 3px 10px 10px; |
| | | cursor: pointer; |
| | | } |
| | | .bottom-mask { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 8px; |
| | | bottom: 0; |
| | | left: 0; |
| | | background: #ffffff; |
| | | border-radius: 8px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .tools::-webkit-scrollbar { |
| | | width: 4px; |
| | | } |
| | | .tools::-webkit-scrollbar-thumb { |
| | | border-radius: 5px; |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08); |
| | | background: rgba(0, 0, 0, 0.08); |
| | | } |
| | | .tools::-webkit-scrollbar-track { |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); |
| | | border-radius: 3px; |
| | | border: 1px solid rgba(0, 0, 0, 0.07); |
| | | background: rgba(0, 0, 0, 0); |
| | | } |
| | | .setting { |
| | | position: relative; |
| | | width: calc(100vw - 235px); |
| | | height: 100%; |
| | | overflow-y: hidden; |
| | | background: #ffffff; |
| | | .ant-card-head { |
| | | min-height: 44px; |
| | | } |
| | | .ant-card-head-title { |
| | | padding: 5px 0; |
| | | color: #1890ff; |
| | | } |
| | | .ant-card-extra { |
| | | padding: 5px 0; |
| | | button { |
| | | margin-left: 20px; |
| | | } |
| | | } |
| | | .ant-card-body { |
| | | position: relative; |
| | | padding: 0; |
| | | .ant-modal-content { |
| | | max-width: 95%; |
| | | margin: 0 auto; |
| | | margin-top: 30px; |
| | | .ant-modal-header { |
| | | position: relative; |
| | | z-index: 10; |
| | | background: transparent; |
| | | } |
| | | .ant-modal-close { |
| | | opacity: 0.3; |
| | | } |
| | | .ant-modal-footer { |
| | | position: relative; |
| | | button { |
| | | opacity: 0.3; |
| | | } |
| | | } |
| | | .action-mask { |
| | | position: absolute; |
| | | top: 0px; |
| | | left: 0px; |
| | | right: 0px; |
| | | bottom: 0px; |
| | | } |
| | | } |
| | | |
| | | .modal-form { |
| | | padding: 0px 24px; |
| | | min-height: 87px; |
| | | .group-title { |
| | | position: relative; |
| | | min-height: 22px; |
| | | margin-bottom: 10px; |
| | | padding-top: 10px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | |
| | | span { |
| | | padding: 0 5px 5px; |
| | | } |
| | | } |
| | | > .ant-row { |
| | | min-height: 120px; |
| | | } |
| | | .ant-row .ant-col-6 { |
| | | padding: 0 12px!important; |
| | | } |
| | | .ant-row.ant-form-item .ant-col { |
| | | padding: 0; |
| | | } |
| | | .textarea2, .textarea4 { |
| | | padding-left: 7px; |
| | | } |
| | | .page-card { |
| | | position: relative; |
| | | background: #ffffff; |
| | | border-radius: 2px; |
| | | margin-bottom: 15px; |
| | | .ant-form-item { |
| | | cursor: move; |
| | | display: flex; |
| | | margin-bottom: 0px; |
| | | .ant-form-item-label { |
| | | overflow: visible; |
| | | position: relative; |
| | | height: 40px; |
| | | label { |
| | | width: 100%; |
| | | cursor: move; |
| | | overflow: hidden; |
| | | display: inline-block; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper { |
| | | .ant-select { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | } |
| | | .ant-calendar-picker { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | } |
| | | .input-mask { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | .ant-col-cuslabel { |
| | | width: 10.5%; |
| | | } |
| | | .ant-col-cuswrap { |
| | | width: 89.5%; |
| | | } |
| | | } |
| | | } |
| | | .ant-calendar-picker { |
| | | min-width: 100px!important; |
| | | } |
| | | } |
| | | > .anticon-setting { |
| | | position: absolute; |
| | | font-size: 16px; |
| | | right: 15px; |
| | | top: 10px; |
| | | } |
| | | .paste-Icon { |
| | | position: absolute; |
| | | font-size: 16px; |
| | | right: 15px; |
| | | top: 65px; |
| | | } |
| | | } |
| | | } |
| | | .setting:hover { |
| | | overflow-y: auto; |
| | | } |
| | | .setting::-webkit-scrollbar { |
| | | width: 7px; |
| | | } |
| | | .setting::-webkit-scrollbar-thumb { |
| | | border-radius: 5px; |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); |
| | | background: rgba(0, 0, 0, 0.13); |
| | | } |
| | | .setting::-webkit-scrollbar-track { |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); |
| | | border-radius: 3px; |
| | | border: 1px solid rgba(0, 0, 0, 0.07); |
| | | background: rgba(0, 0, 0, 0); |
| | | } |
| | | } |
| | | |
| | | .modal-fields { |
| | | .ant-modal { |
| | | top: 50px; |
| | | padding-bottom: 5px; |
| | | .ant-modal-body { |
| | | max-height: calc(100vh - 190px); |
| | | overflow-y: auto; |
| | | .ant-empty { |
| | | margin: 15vh 8px; |
| | | } |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar { |
| | | width: 7px; |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar-thumb { |
| | | border-radius: 5px; |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); |
| | | background: rgba(0, 0, 0, 0.13); |
| | | } |
| | | .ant-modal-body::-webkit-scrollbar-track { |
| | | box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); |
| | | border-radius: 3px; |
| | | border: 1px solid rgba(0, 0, 0, 0.07); |
| | | background: rgba(0, 0, 0, 0); |
| | | } |
| | | } |
| | | } |
| | |
| | | class SearchComponent extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.object, // 配置信息 |
| | | // optionLibs: PropTypes.any, // 下拉字典 |
| | | updatesearch: PropTypes.func // 更新 |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menuType } = this.props |
| | | const { BID, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, pickup, config, triggerBtn, userConfig, tabActive, chartId, search, selectedData } = this.state |
| | | |
| | | return ( |
| | |
| | | </Tabs>) |
| | | ) |
| | | } |
| | | {options.sysType !== 'cloud' ? <Button |
| | | {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button |
| | | icon="copy" |
| | | shape="circle" |
| | | className="common-table-copy" |
| | |
| | | .prev-page.disabled { |
| | | img { |
| | | cursor: not-allowed; |
| | | opacity: 0.4; |
| | | } |
| | | } |
| | | .card-row-list::after { |
| | |
| | | } |
| | | |
| | | let showHeader = false |
| | | if (config.plot.title || _config.plot.datatype === 'statistics') { |
| | | if (config.plot.title || _config.plot.datatype === 'statistics' || config.search.length > 0) { |
| | | showHeader = true |
| | | _config.plot.height = _config.plot.height - 80 |
| | | } else { |
| | | _config.plot.height = _config.plot.height - 30 |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | } |
| | | })} |
| | | </div> |
| | | <div className={'canvas' + (empty ? ' empty' : '')} style={{minHeight: plot.height ? plot.height : 400}} id={this.state.chartId}></div> |
| | | <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div> |
| | | </div> |
| | | {empty ? <Empty description={false}/> : null} |
| | | </div> |
| | |
| | | .custom-line-chart-plot-box { |
| | | background: #ffffff; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | |
| | | > .chart-header { |
| | | height: 45px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | overflow: hidden; |
| | | text-decoration: inherit; |
| | | font-weight: inherit; |
| | | font-style: inherit; |
| | | |
| | | .chart-title { |
| | | font-size: 16px; |
| | | // font-size: 16px; |
| | | float: left; |
| | | line-height: 45px; |
| | | margin-left: 10px; |
| | | text-decoration: inherit; |
| | | font-weight: inherit; |
| | | font-style: inherit; |
| | | } |
| | | } |
| | | |
| | |
| | | .canvas { |
| | | margin: 0; |
| | | // border: 1px solid #e8e8e8; |
| | | padding: 25px 15px; |
| | | padding: 15px; |
| | | letter-spacing: 0px; |
| | | } |
| | | .canvas.empty { |
| | | div { |
| | |
| | | const { tabs } = this.state |
| | | |
| | | return ( |
| | | <div className="menu-antv-tabs-wrap"> |
| | | <div className="menu-antv-tabs-wrap" style={tabs.style}> |
| | | <Tabs defaultActiveKey="1" tabPosition={tabs.setting.position} type={tabs.setting.tabStyle}> |
| | | {tabs.subtabs.map(tab => ( |
| | | <TabPane tab={<span>{tab.icon ? <Icon type={tab.icon} /> : null}{tab.label}</span>} key={tab.uuid}> |
| | |
| | | position: relative; |
| | | box-sizing: border-box; |
| | | background: #ffffff; |
| | | border-style: solid; |
| | | border-width: 0; |
| | | } |
| | |
| | | |
| | | let selects = this.props.data.filter((item, _index) => selectedRowKeys.includes(_index)) |
| | | |
| | | // selectedRowKeys.forEach(item => { |
| | | // selects.push(this.props.data[item]) |
| | | // }) |
| | | |
| | | this.props.chgSelectData(selects) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | let selects = this.props.data.filter((item, _index) => newkeys.includes(_index)) |
| | | // newkeys.forEach(item => { |
| | | // selects.push(this.props.data[item]) |
| | | // }) |
| | | |
| | | this.props.chgSelectData(selects) |
| | | } |
| | |
| | | {offset && <Affix offsetTop={offset} className="fix-header"> |
| | | <Table |
| | | size="middle" |
| | | bordered={true} |
| | | bordered={setting.bordered !== 'false'} |
| | | rowSelection={rowSelection} |
| | | columns={this.state.columns.map(column => { |
| | | return { |
| | |
| | | </Affix>} |
| | | <Table |
| | | size="middle" |
| | | bordered={true} |
| | | bordered={setting.bordered !== 'false'} |
| | | rowSelection={rowSelection} |
| | | columns={this.state.columns} |
| | | dataSource={_data} |
| | |
| | | class SubTableConfig extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.any, |
| | | optionLibs: PropTypes.any, |
| | | reloadmenu: PropTypes.func, |
| | | handleView: PropTypes.func |
| | | } |
| | |
| | | closeVisible: false, // 关闭模态框 |
| | | originConfig: null, // 原配置 |
| | | tabviews: [], // 所有标签页 |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | activeKey: '0', // 默认展开基本信息 |
| | | pasteContent: null, // 粘贴内容 |
| | | openEdition: '', // 编辑版本标记,防止多人操作 |
| | |
| | | * 2、设置操作类型、原始菜单信息(每次保存后重置)、已使用表及基本信息表单 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { menu, optionLibs } = this.props |
| | | const { menu } = this.props |
| | | let _LongParam = menu.LongParam |
| | | let _config = '' |
| | | |
| | |
| | | _config.isAdd = true |
| | | } else { |
| | | _config = _LongParam |
| | | _config.search.forEach(item => { |
| | | if ( |
| | | (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') && |
| | | item.resourceType === '0' && |
| | | item.options && item.options.length > 0 |
| | | ) { |
| | | optionLibs.set(menu.MenuID + item.uuid, { |
| | | uuid: menu.MenuID + item.uuid, |
| | | label: item.label, |
| | | parname: menu.MenuName, |
| | | type: 'search', |
| | | options: item.options |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (_config.type === 'user') { |
| | |
| | | |
| | | this.setState({ |
| | | openEdition: menu.open_edition || '', |
| | | optionLibs: optionLibs, |
| | | activeKey: menu.activeKey || '0', |
| | | config: _config, |
| | | originMenu: fromJS(_config).toJS(), |
| | |
| | | handleViewBack = () => { |
| | | let param = { |
| | | editMenu: null, |
| | | optionLibs: null, |
| | | editTab: null, |
| | | tabConfig: null, |
| | | subTabConfig: null, |
| | |
| | | */ |
| | | setSubConfig = () => { |
| | | const { menu } = this.props |
| | | const { config, originMenu, optionLibs, activeKey, openEdition } = this.state |
| | | const { config, originMenu, activeKey, openEdition } = this.state |
| | | |
| | | if (config.isAdd) { // 新建菜单,提示菜单尚未保存 |
| | | notification.warning({ |
| | |
| | | _Menu.open_edition = openEdition // 更新版本号 |
| | | |
| | | let param = { |
| | | optionLibs: optionLibs, |
| | | editMenu: _Menu, |
| | | editTab: fromJS(config.tab).toJS(), |
| | | tabConfig: null, |
| | |
| | | /** |
| | | * @description 更新搜索条件配置信息 |
| | | */ |
| | | updatesearch = (config, options) => { |
| | | const { optionLibs } = this.state |
| | | updatesearch = (config) => { |
| | | |
| | | this.setState({ |
| | | config: config, |
| | | optionLibs: options || optionLibs |
| | | config: config |
| | | }) |
| | | } |
| | | |
| | |
| | | config={config} |
| | | pasteContent={this.state.pasteContent} |
| | | sysRoles={this.props.sysRoles} |
| | | optionLibs={this.state.optionLibs} |
| | | updatesearch={this.updatesearch} |
| | | /> |
| | | <div className="calendar-wrap"> |
| | |
| | | class ComTableConfig extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.any, |
| | | optionLibs: PropTypes.any, |
| | | reloadmenu: PropTypes.func, |
| | | handleView: PropTypes.func |
| | | } |
| | |
| | | delActions: [], // 删除按钮列表 |
| | | copyActions: [], // 复制按钮组 |
| | | tabviews: [], // 所有标签页 |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | thawButtons: [], // 已选择要解冻的按钮 |
| | | activeKey: '0', // 默认展开基本信息 |
| | | chartview: null, // 当前视图 |
| | |
| | | * 2、设置操作类型、原始菜单信息(每次保存后重置)、已使用表及基本信息表单 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { menu, optionLibs } = this.props |
| | | const { menu } = this.props |
| | | let _LongParam = menu.LongParam |
| | | let _config = '' |
| | | |
| | |
| | | _config.isAdd = true |
| | | } else { |
| | | _config = _LongParam |
| | | _config.search.forEach(item => { |
| | | if ( |
| | | (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') && |
| | | item.resourceType === '0' && |
| | | item.options && item.options.length > 0 |
| | | ) { |
| | | optionLibs.set(menu.MenuID + item.uuid, { |
| | | uuid: menu.MenuID + item.uuid, |
| | | label: item.label, |
| | | parname: menu.MenuName, |
| | | type: 'search', |
| | | options: item.options |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 页面配置中保留菜单信息,只用于数据传递 |
| | |
| | | config: _config, |
| | | openEdition: menu.open_edition || '', |
| | | activeKey: menu.activeKey || '0', |
| | | optionLibs: optionLibs, |
| | | originActions: _oriActions, |
| | | originMenu: fromJS(_config).toJS() |
| | | }) |
| | |
| | | */ |
| | | setSubConfig = (item, type) => { |
| | | const { menu } = this.props |
| | | const { config, originMenu, optionLibs, activeKey, openEdition } = this.state |
| | | const { config, originMenu, activeKey, openEdition } = this.state |
| | | |
| | | if (config.isAdd) { // 新建菜单,提示菜单尚未保存 |
| | | notification.warning({ |
| | |
| | | _Menu.open_edition = openEdition // 更新版本号 |
| | | |
| | | let param = { |
| | | optionLibs: optionLibs, |
| | | editMenu: _Menu, |
| | | editTab: !isbutton ? item : '', |
| | | tabConfig: null, |
| | |
| | | /** |
| | | * @description 更新搜索条件配置信息 |
| | | */ |
| | | updatesearch = (config, options) => { |
| | | const { optionLibs } = this.state |
| | | updatesearch = (config) => { |
| | | |
| | | this.setState({ |
| | | config: config, |
| | | optionLibs: options || optionLibs |
| | | config: config |
| | | }) |
| | | } |
| | | |
| | |
| | | config={config} |
| | | pasteContent={this.state.pasteContent} |
| | | sysRoles={this.props.sysRoles} |
| | | optionLibs={this.state.optionLibs} |
| | | updatesearch={this.updatesearch} |
| | | /> |
| | | <div className="chart-view" style={{position: 'relative'}}> |
| | |
| | | class ComTableConfig extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.any, |
| | | optionLibs: PropTypes.any, |
| | | btnTab: PropTypes.object, |
| | | config: PropTypes.any, |
| | | handleView: PropTypes.func |
| | |
| | | profileVisible: false, // 验证信息模态框 |
| | | editgroup: null, // 当前编辑组 |
| | | groupVisible: false, // 编辑组模态框 |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | activeKey: '0', // 默认展开基本信息 |
| | | pasteVisible: false, // 粘贴模态框 |
| | | sqlVerifing: false, // sql验证 |
| | |
| | | * 2、设置操作类型、原始菜单信息(每次保存后重置)、已使用表及基本信息表单 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { menu, btnTab, config, optionLibs } = this.props |
| | | const { menu, btnTab, config } = this.props |
| | | |
| | | let _config = '' |
| | | let columns = [] |
| | |
| | | if (menu && menu.LongParam && menu.LongParam.setting) { |
| | | _config.setting.primaryKey = menu.LongParam.setting.primaryKey |
| | | } |
| | | |
| | | _config.groups.forEach(group => { |
| | | group.sublist.forEach(item => { |
| | | if ( |
| | | (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') && |
| | | item.resourceType === '0' && |
| | | item.options && item.options.length > 0 |
| | | ) { |
| | | optionLibs.set(btnTab.uuid + item.uuid, { |
| | | uuid: btnTab.uuid + item.uuid, |
| | | label: item.label, |
| | | parname: btnTab.label, |
| | | type: 'Modal', |
| | | options: item.options |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | if (!_config.tabgroups) { |
| | |
| | | config: _config, |
| | | activeKey: btnTab.activeKey || '0', |
| | | openEdition: btnTab.open_edition || '', |
| | | optionLibs: optionLibs, |
| | | columns: columns, |
| | | originMenu: JSON.parse(JSON.stringify(_config)), |
| | | selectedTables: _config.tables, |
| | |
| | | let _tabview = menu ? menu.LongParam.Template : '' |
| | | let param = { |
| | | editMenu: menu, |
| | | optionLibs: this.state.optionLibs, |
| | | editTab: null, |
| | | tabConfig: null, |
| | | editSubTab: null, |
| | |
| | | * 3、添加或编辑列,保存时,如按钮位置设置为表格,则修改操作列显示状态 |
| | | */ |
| | | handleSubmit = () => { |
| | | const { btnTab } = this.props |
| | | const { config, modaltype, optionLibs, card } = this.state |
| | | const { config, modaltype, card } = this.state |
| | | |
| | | if (modaltype === 'search') { |
| | | this.modalFormRef.handleConfirm().then(res => { |
| | |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | if ( // 更新下拉字典 |
| | | (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && |
| | | res.resourceType === '0' && |
| | | res.options && res.options.length > 0 |
| | | ) { |
| | | optionLibs.set(btnTab.uuid + res.uuid, { |
| | | uuid: btnTab.uuid + res.uuid, |
| | | label: res.label, |
| | | parname: btnTab.label, |
| | | type: 'Modal', |
| | | options: res.options |
| | | }) |
| | | } |
| | | |
| | | let _groups = null |
| | |
| | | this.setState({ |
| | | sqlVerifing: false, |
| | | config: {..._config, groups: _groups}, |
| | | optionLibs: optionLibs, |
| | | modaltype: '' |
| | | }) |
| | | } else { |
| | |
| | | } else { |
| | | this.setState({ |
| | | config: {..._config, groups: _groups}, |
| | | optionLibs: optionLibs, |
| | | modaltype: '' |
| | | }) |
| | | } |
| | |
| | | |
| | | let param = { |
| | | editMenu: menu, |
| | | optionLibs: this.state.optionLibs, |
| | | editTab: btn, |
| | | tabConfig: null, |
| | | editSubTab: null, |
| | |
| | | card={this.state.card} |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | optionLibs={this.state.optionLibs} |
| | | wrappedComponentRef={(inst) => this.modalFormRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | btnTabConfig: null, // 打开新标签按钮配置 |
| | | handleMVisible: false, // 添加或修改菜单模态框(角色权限分配等) |
| | | sysMenu: false, // 添加或编辑菜单(角色权限分配等) |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | fstMenuId: null, // 一级菜单Id |
| | | fstMenuList: null // 一级菜单列表 |
| | | } |
| | |
| | | type: 'edit', |
| | | editMenu: _menu, |
| | | loading: false, |
| | | optionLibs: new Map(), // 编辑时,初始化为空 |
| | | tabview: _menu.PageParam.Template |
| | | }, () => { |
| | | document.getElementById('root').style.overflowY = 'hidden' |
| | |
| | | _menu.loadingFstMenuId = true |
| | | this.setState({ |
| | | type: 'edit', |
| | | editMenu: _menu, |
| | | optionLibs: new Map() |
| | | editMenu: _menu |
| | | }) |
| | | } |
| | | } else { |
| | |
| | | this.setState({ |
| | | loading: false, |
| | | tabview: template.type === 'CustomPage' ? '' : template.type, |
| | | optionLibs: new Map(), // 新建时,初始化下拉选项库 |
| | | editMenu: { |
| | | ...editMenu, |
| | | type: template.type, |
| | |
| | | type: 'edit', |
| | | editMenu: _menu, |
| | | loading: false, |
| | | optionLibs: new Map(), // 编辑时,初始化为空 |
| | | tabview: _menu.PageParam.Template |
| | | }, () => { |
| | | document.getElementById('root').style.overflowY = 'hidden' |
| | |
| | | {this.state.tabview === 'TreePage' ? |
| | | <TreePageConfig |
| | | menu={this.state.editMenu} |
| | | optionLibs={this.state.optionLibs} |
| | | reloadmenu={() => {this.props.reload()}} |
| | | handleView={this.handleView} |
| | | /> : null |
| | |
| | | {this.state.tabview === 'CalendarPage' ? |
| | | <CalendarPageConfig |
| | | menu={this.state.editMenu} |
| | | optionLibs={this.state.optionLibs} |
| | | reloadmenu={() => {this.props.reload()}} |
| | | handleView={this.handleView} |
| | | /> : null |
| | |
| | | {this.state.tabview === 'CommonTable' ? |
| | | <ComTableConfig |
| | | menu={this.state.editMenu} |
| | | optionLibs={this.state.optionLibs} |
| | | reloadmenu={() => {this.props.reload()}} |
| | | handleView={this.handleView} |
| | | /> : null |
| | |
| | | {this.state.tabview === 'Modal' ? |
| | | <ModalConfig |
| | | menu={this.state.editMenu} |
| | | optionLibs={this.state.optionLibs} |
| | | editTab={this.state.editTab} |
| | | tabConfig={this.state.tabConfig} |
| | | editSubTab={this.state.editSubTab} |
| | |
| | | {this.state.tabview === 'SubTable' ? |
| | | <SubTable |
| | | menu={this.state.editMenu} |
| | | optionLibs={this.state.optionLibs} |
| | | editTab={this.state.editTab} |
| | | editSubTab={this.state.editSubTab} |
| | | tabConfig={this.state.tabConfig} |
| | |
| | | {this.state.tabview === 'FormTab' ? |
| | | <FormTabConfig |
| | | menu={this.state.editMenu} |
| | | optionLibs={this.state.optionLibs} |
| | | btnTab={this.state.btnTab} |
| | | config={this.state.subConfig} |
| | | handleView={this.handleView} |
| | |
| | | import React from 'react' |
| | | import { useDrag, useDrop } from 'react-dnd' |
| | | import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover } from 'antd' |
| | | import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover, Switch, Radio, Checkbox } from 'antd' |
| | | import moment from 'moment' |
| | | import './index.scss' |
| | | |
| | |
| | | formItem = (<Input style={{marginTop: '4px'}} defaultValue={card.linkfield} />) |
| | | } else if (card.type === 'linkMain') { |
| | | formItem = (<Input style={{marginTop: '4px'}} />) |
| | | } else if (card.type === 'switch') { |
| | | formItem = (<Switch style={{marginTop: '8px'}} checked={card.initval}/>) |
| | | } else if (card.type === 'radio') { |
| | | formItem = (<Radio.Group style={{marginTop: '8px'}} value={1}> |
| | | <Radio value={1}>A</Radio> |
| | | <Radio value={2}>B</Radio> |
| | | <Radio value={3}>C</Radio> |
| | | <Radio value={4}>D</Radio> |
| | | </Radio.Group>) |
| | | } else if (card.type === 'checkbox') { |
| | | formItem = (<Checkbox.Group style={{marginTop: '8px'}} value={['A', 'C']}> |
| | | <Checkbox value="A">A</Checkbox> |
| | | <Checkbox value="B">B</Checkbox> |
| | | <Checkbox value="C">C</Checkbox> |
| | | <Checkbox value="D">D</Checkbox> |
| | | </Checkbox.Group>) |
| | | } |
| | | |
| | | return ( |
| | |
| | | class ComModalConfig extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.any, |
| | | optionLibs: PropTypes.any, |
| | | editTab: PropTypes.any, |
| | | editSubTab: PropTypes.any, |
| | | tabConfig: PropTypes.any, |
| | |
| | | originConfig: null, // 原始菜单 |
| | | groupVisible: false, // 全局配置模态框 |
| | | curgroup: null, // 当前组,新建或编辑 |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | sources: null, // 表单类型 |
| | | sqlVerifing: false, // sql验证 |
| | | openEdition: '' // 编辑版本标记,防止多人操作 |
| | |
| | | * 4、设置按钮基本信息 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const {menu, editAction, tabConfig, subTabConfig, subConfig, optionLibs} = this.props |
| | | const {menu, editAction, tabConfig, subTabConfig, subConfig} = this.props |
| | | |
| | | let _config = '' |
| | | let _tab = subTabConfig ? subTabConfig : tabConfig |
| | |
| | | |
| | | if (subConfig) { |
| | | _config = subConfig |
| | | |
| | | if (_config.groups.length > 0) { |
| | | _config.groups.forEach(group => { |
| | | group.sublist.forEach(item => { |
| | | if ( |
| | | (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') && |
| | | item.resourceType === '0' && |
| | | item.options && item.options.length > 0 |
| | | ) { |
| | | optionLibs.set(editAction.uuid + item.uuid, { |
| | | uuid: editAction.uuid + item.uuid, |
| | | label: item.label, |
| | | parname: editAction.label, |
| | | type: 'Modal', |
| | | options: item.options |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | } else { |
| | | _config.fields.forEach(item => { |
| | | if ( |
| | | (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') && |
| | | item.resourceType === '0' && |
| | | item.options && item.options.length > 0 |
| | | ) { |
| | | optionLibs.set(editAction.uuid + item.uuid, { |
| | | uuid: editAction.uuid + item.uuid, |
| | | label: item.label, |
| | | parname: editAction.label, |
| | | type: 'Modal', |
| | | options: item.options |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | } else { |
| | | _config = JSON.parse(JSON.stringify(BaseConfig)) |
| | | } |
| | |
| | | openEdition: editAction.open_edition || '', |
| | | menu: _menu, |
| | | source: _source, |
| | | optionLibs: optionLibs, |
| | | config: _config, |
| | | selectedTables: _config.tables || [], |
| | | originConfig: JSON.parse(JSON.stringify(_config)), |
| | |
| | | |
| | | let param = { |
| | | editMenu: menu, |
| | | optionLibs: this.state.optionLibs, |
| | | editTab: editTab, |
| | | tabConfig: tabConfig, |
| | | editSubTab: editSubTab, |
| | |
| | | * 3、通过loading刷新 |
| | | */ |
| | | handleSubmit = () => { |
| | | const {editAction, optionLibs} = this.props |
| | | const { card, modalType } = this.state |
| | | |
| | | this.formRef.handleConfirm().then(res => { |
| | | let _config = JSON.parse(JSON.stringify(this.state.config)) |
| | | if ( // 更新下拉字典 |
| | | (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && |
| | | res.resourceType === '0' && |
| | | res.options && res.options.length > 0 |
| | | ) { |
| | | optionLibs.set(editAction.uuid + res.uuid, { |
| | | uuid: editAction.uuid + res.uuid, |
| | | label: res.label, |
| | | parname: editAction.label, |
| | | type: 'Modal', |
| | | options: res.options |
| | | }) |
| | | } |
| | | |
| | | let fieldrepet = false // 字段重复 |
| | | let labelrepet = false // 提示文字重复 |
| | | |
| | |
| | | config: _config, |
| | | modalType: null, |
| | | card: null, |
| | | optionLibs: optionLibs, |
| | | visible: false |
| | | }) |
| | | } else { |
| | |
| | | config: _config, |
| | | modalType: null, |
| | | card: null, |
| | | optionLibs: optionLibs, |
| | | visible: false |
| | | }) |
| | | } |
| | |
| | | <Modal |
| | | title={this.state.modalType !== 'copy' ? this.state.dict['model.edit'] : this.state.dict['header.modal.form.copy']} |
| | | visible={this.state.visible} |
| | | width={700} |
| | | width={800} |
| | | onCancel={this.editModalCancel} |
| | | onOk={this.handleSubmit} |
| | | confirmLoading={this.state.sqlVerifing} |
| | |
| | | card={this.state.card} |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | optionLibs={this.state.optionLibs} |
| | | wrappedComponentRef={(inst) => this.formRef = inst} |
| | | />} |
| | | </Modal> |
| | |
| | | right: 0; |
| | | bottom: 0; |
| | | opacity: 0; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | .ant-col-cuslabel { |
| | |
| | | }, |
| | | { |
| | | type: 'form', |
| | | label: '开关', |
| | | subType: 'switch', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'form', |
| | | label: '多选框', |
| | | subType: 'checkbox', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'form', |
| | | label: '单选框', |
| | | subType: 'radio', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'form', |
| | | label: '选项卡', |
| | | subType: 'checkcard', |
| | | url: '' |
| | | }, |
| | | { |
| | | type: 'form', |
| | | label: CommonDict['header.form.fileupload'], |
| | | subType: 'fileupload', |
| | | url: '' |
| | |
| | | menu: PropTypes.object, // 当前菜单信息 |
| | | config: PropTypes.object, // 配置信息 |
| | | pasteContent: PropTypes.object, // 粘贴配置信息 |
| | | optionLibs: PropTypes.any, // 下拉字典 |
| | | sysRoles: PropTypes.array, // 角色列表,黑名单 |
| | | updatesearch: PropTypes.func // 更新 |
| | | } |
| | |
| | | * 4、下拉菜单数据源语法验证 |
| | | */ |
| | | handleSubmit = () => { |
| | | const { optionLibs, menu, config } = this.props |
| | | const { config } = this.props |
| | | let _searchlist = fromJS(this.state.searchlist).toJS() |
| | | |
| | | this.searchFormRef.handleConfirm().then(res => { |
| | |
| | | return |
| | | } |
| | | |
| | | if ( res.options && res.options.length > 0 ) { // 下拉菜单可选集合 |
| | | optionLibs.set(menu.MenuID + res.uuid, { |
| | | uuid: menu.MenuID + res.uuid, |
| | | label: res.label, |
| | | parname: menu.MenuName, |
| | | type: 'search', |
| | | options: res.options |
| | | }) |
| | | } |
| | | |
| | | if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) { |
| | | this.setState({ |
| | | sqlVerifing: true |
| | |
| | | searchlist: _searchlist, |
| | | visible: false |
| | | }, ()=> { |
| | | this.props.updatesearch({...config, search: _searchlist}, optionLibs) |
| | | this.props.updatesearch({...config, search: _searchlist}) |
| | | }) |
| | | } else { |
| | | this.setState({sqlVerifing: false}) |
| | |
| | | searchlist: _searchlist, |
| | | visible: false |
| | | }, ()=> { |
| | | this.props.updatesearch({...config, search: _searchlist}, optionLibs) |
| | | this.props.updatesearch({...config, search: _searchlist}) |
| | | }) |
| | | } |
| | | }) |
| | |
| | | card={this.state.card} |
| | | formlist={this.state.formlist} |
| | | inputSubmit={this.handleSubmit} |
| | | optionLibs={this.props.optionLibs} |
| | | wrappedComponentRef={(inst) => this.searchFormRef = inst} |
| | | /> |
| | | </Modal> |
| | |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | formlist: PropTypes.any, // 表单 |
| | | optionLibs: PropTypes.any, // 自定义下拉集 |
| | | card: PropTypes.object, // 搜索条件信息 |
| | | inputSubmit: PropTypes.any // 回车提交事件 |
| | | } |
| | |
| | | * 2、下拉选择,根据数据源类型显示相关配置 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { formlist, optionLibs, dict } = this.props |
| | | const { formlist, dict } = this.props |
| | | |
| | | let type = formlist.filter(cell => cell.key === 'type')[0].initVal |
| | | let _items = formlist.filter(cell => cell.key === 'items')[0].initVal |
| | |
| | | let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide'] // 默认显示项 |
| | | |
| | | if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') { // 下拉选择类型、选项为自定义资源 |
| | | _options = [..._options, 'resourceType', 'options', 'display', 'quick'] |
| | | _options = [..._options, 'resourceType', 'options', 'display'] |
| | | } else if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '1') { // 下拉选择类型、选项为后台数据源中获取 |
| | | _options = [..._options, 'resourceType', 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'display', 'database'] |
| | | } else if (type === 'group') { |
| | |
| | | } else if (type === 'dateweek' || type === 'daterange') { |
| | | form.options = matchReg.daterange |
| | | } |
| | | } else if (form.key === 'quick') { |
| | | form.options = [...optionLibs.values()].map(cell => { |
| | | return { |
| | | value: cell.uuid, |
| | | text: cell.label + '(' + cell.parname + ')' |
| | | } |
| | | }) |
| | | } else if (form.key === 'field' && type === 'text') { |
| | | form.tooltip = this.state.textTooltip |
| | | } else if (form.key === 'field' && type === 'group') { |
| | |
| | | let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide'] |
| | | |
| | | if ((value === 'multiselect' || value === 'select' || value === 'link') && resourceType === '0') { // 下拉选择类型、选项为自定义资源 |
| | | _options = [..._options, 'resourceType', 'options', 'display', 'quick'] |
| | | _options = [..._options, 'resourceType', 'options', 'display'] |
| | | } else if ((value === 'multiselect' || value === 'select' || value === 'link') && resourceType === '1') { // 下拉选择类型、选项为后台数据源中获取 |
| | | _options = [..._options, 'resourceType', 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'display', 'database'] |
| | | } else if (value === 'group') { |
| | |
| | | this.props.form.setFieldsValue({match: matchs[0].value}) |
| | | } |
| | | }) |
| | | } else if (key === 'quick') { |
| | | let _option = this.props.optionLibs.get(value) |
| | | |
| | | this.setState({ |
| | | formlist: this.state.formlist.map(form => { |
| | | if (form.key === 'options') { |
| | | form.initVal = _option.options |
| | | } |
| | | |
| | | return form |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display', 'ratio', 'blacklist', 'required', 'Hide'] |
| | | |
| | | if (value === '0') { |
| | | _options = [..._options, 'options', 'quick'] |
| | | _options = [..._options, 'options'] |
| | | } else if (value === '1') { |
| | | _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database'] |
| | | } |
| | |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | <Col span={12}> |
| | | <Form.Item label="边框"> |
| | | {getFieldDecorator('bordered', { |
| | | initialValue: setting.bordered || 'true' |
| | | })( |
| | | <Radio.Group> |
| | | <Radio value="true">有</Radio> |
| | | <Radio value="false">无</Radio> |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | |
| | | class SubTableConfig extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.any, |
| | | optionLibs: PropTypes.any, |
| | | editTab: PropTypes.any, |
| | | tabConfig: PropTypes.any, |
| | | editSubTab: PropTypes.any, |
| | |
| | | delActions: [], // 删除按钮列表 |
| | | copyActions: [], // 复制按钮组 |
| | | tabviews: [], // 所有标签页 |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | thawButtons: [], // 已选择要解冻的按钮 |
| | | activeKey: '0', // 默认展开基本信息 |
| | | chartview: null, // 当前视图 |
| | |
| | | * 2、设置操作类型、原始菜单信息(每次保存后重置)、已使用表及基本信息表单 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { config, editTab, editSubTab, optionLibs } = this.props |
| | | const { config, editTab, editSubTab } = this.props |
| | | |
| | | let _config = null |
| | | |
| | |
| | | _config.isAdd = true |
| | | } else { |
| | | _config = fromJS(config).toJS() |
| | | |
| | | _config.search.forEach(item => { |
| | | if ( |
| | | (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') && |
| | | item.resourceType === '0' && |
| | | item.options && item.options.length > 0 |
| | | ) { |
| | | optionLibs.set(_config.uuid + item.uuid, { |
| | | uuid: _config.uuid + item.uuid, |
| | | label: item.label, |
| | | parname: _config.tabName, |
| | | type: 'search', |
| | | options: item.options |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | let _oriActions = [] |
| | |
| | | openEdition: editSubTab ? (editSubTab.open_edition || '') : (editTab.open_edition || ''), |
| | | chartview: _config.charts[0].uuid, |
| | | originActions: _oriActions, |
| | | optionLibs: optionLibs, |
| | | config: _config, |
| | | activeKey: _activeKey || '0', |
| | | originConfig: fromJS(_config).toJS(), |
| | |
| | | |
| | | let param = { |
| | | editMenu: menu, |
| | | optionLibs: this.state.optionLibs, |
| | | editTab: editSubTab ? editTab : null, |
| | | tabConfig: null, |
| | | editSubTab: null, |
| | |
| | | |
| | | let param = { |
| | | editMenu: menu, |
| | | optionLibs: this.state.optionLibs, |
| | | editTab: editTab, |
| | | tabConfig: editSubTab ? tabConfig : originConfig, |
| | | editSubTab: _subtab, |
| | |
| | | /** |
| | | * @description 更新搜索条件配置信息 |
| | | */ |
| | | updatesearch = (config, options) => { |
| | | const { optionLibs } = this.state |
| | | updatesearch = (config) => { |
| | | |
| | | this.setState({ |
| | | config: config, |
| | | optionLibs: options || optionLibs |
| | | config: config |
| | | }) |
| | | } |
| | | |
| | |
| | | config={config} |
| | | pasteContent={this.state.pasteContent} |
| | | sysRoles={this.props.sysRoles} |
| | | optionLibs={this.state.optionLibs} |
| | | updatesearch={this.updatesearch} |
| | | /> |
| | | <div className="chart-view" style={{position: 'relative'}}> |
| | |
| | | class ComTableConfig extends Component { |
| | | static propTpyes = { |
| | | menu: PropTypes.any, |
| | | optionLibs: PropTypes.any, |
| | | reloadmenu: PropTypes.func, |
| | | handleView: PropTypes.func |
| | | } |
| | |
| | | originMenu: null, // 原始菜单 |
| | | delTabs: [], // 删除标签列表 |
| | | tabviews: [], // 所有标签页 |
| | | optionLibs: null, // 自定义下拉选项库 |
| | | activeKey: '0', // 默认展开基本信息 |
| | | pasteContent: null, // 粘贴配置信息 |
| | | openEdition: '' // 编辑版本标记,防止多人操作 |
| | |
| | | * 2、设置操作类型、原始菜单信息(每次保存后重置)、已使用表及基本信息表单 |
| | | */ |
| | | UNSAFE_componentWillMount () { |
| | | const { menu, optionLibs } = this.props |
| | | const { menu } = this.props |
| | | |
| | | let _LongParam = menu.LongParam |
| | | let _config = '' |
| | |
| | | config: _config, |
| | | openEdition: menu.open_edition || '', |
| | | activeKey: menu.activeKey || '0', |
| | | optionLibs: optionLibs, |
| | | originMenu: fromJS(_config).toJS() |
| | | }) |
| | | } |
| | |
| | | */ |
| | | setSubConfig = (item) => { |
| | | const { menu } = this.props |
| | | const { config, originMenu, optionLibs, activeKey, openEdition } = this.state |
| | | const { config, originMenu, activeKey, openEdition } = this.state |
| | | |
| | | if (config.isAdd) { // menuID不存在时,为新建菜单,提示菜单尚未保存 |
| | | notification.warning({ |
| | |
| | | _Menu.open_edition = openEdition // 更新版本号 |
| | | |
| | | let param = { |
| | | optionLibs: optionLibs, |
| | | editMenu: _Menu, |
| | | editTab: item, |
| | | tabConfig: null, |
| | |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'quick', |
| | | label: Formdict['header.form.quickadd'], |
| | | initVal: '', |
| | | required: false, |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'required', |
| | | label: Formdict['model.required'], |
| | |
| | | value: 'link', |
| | | text: Formdict['model.form.link'] |
| | | }, { |
| | | value: 'switch', |
| | | text: '开关' |
| | | }, { |
| | | value: 'checkbox', |
| | | text: '多选框' |
| | | }, { |
| | | value: 'radio', |
| | | text: '单选框' |
| | | }, { |
| | | value: 'checkcard', |
| | | text: '选项卡' |
| | | }, { |
| | | value: 'fileupload', |
| | | text: Formdict['header.form.fileupload'] |
| | | }, { |
| | |
| | | type: 'text', |
| | | key: 'initval', |
| | | label: Formdict['header.form.initval'], |
| | | tooltip: '下拉多选与多选框,添加多个初始值请使用“,”号分隔。', |
| | | initVal: card.initval || '', |
| | | required: false |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'openVal', |
| | | label: '开启值', |
| | | initVal: card.openVal || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'text', |
| | | key: 'closeVal', |
| | | label: '关闭值', |
| | | initVal: card.closeVal || '', |
| | | required: true |
| | | }, |
| | | { |
| | | type: 'radio', |
| | |
| | | }, { |
| | | value: '1', |
| | | text: Formdict['header.form.datasource'] |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'display', |
| | | label: '显示', |
| | | initVal: card.display || 'text', |
| | | required: true, |
| | | options: [{ |
| | | value: 'text', |
| | | text: '文本' |
| | | }, { |
| | | value: 'picture', |
| | | text: '图片' |
| | | }] |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'quick', |
| | | label: Formdict['header.form.quickadd'], |
| | | initVal: '', |
| | | required: false, |
| | | options: [] |
| | | }, |
| | | { |
| | | type: 'select', |
| | | key: 'fileType', |
| | | label: '显示方式', |
| | | initVal: card.fileType || 'text', |
| | |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'entireLine', |
| | | label: '占据整行', |
| | | initVal: card.entireLine || 'false', |
| | | required: false, |
| | | options: [{ |
| | | value: 'true', |
| | | text: '是' |
| | | }, { |
| | | value: 'false', |
| | | text: '否' |
| | | }] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'encryption', |
| | | label: '加密传输', |
| | | initVal: card.encryption || 'false', |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Row, Col, Input, Select, Icon, Radio, notification, InputNumber, Tooltip } from 'antd' |
| | | import { formRule } from '@/utils/option.js' |
| | | import { dateOptions } from '@/utils/option.js' |
| | |
| | | import './index.scss' |
| | | |
| | | const modalTypeOptions = { |
| | | text: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'fieldlength', 'regular', 'interception', 'writein'], |
| | | number: ['label', 'field', 'initval', 'type', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'blacklist', 'writein'], |
| | | select: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'resourceType', 'setAll', 'linkSubField', 'writein'], |
| | | multiselect: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'resourceType', 'fieldlength', 'writein'], |
| | | link: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'resourceType', 'setAll', 'linkField', 'writein'], |
| | | fileupload: ['label', 'field', 'type', 'readonly', 'required', 'readin', 'fieldlength', 'blacklist', 'maxfile', 'fileType', 'writein'], |
| | | date: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'writein'], |
| | | datemonth: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'writein'], |
| | | datetime: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'writein'], |
| | | textarea: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'fieldlength', 'maxRows', 'encryption', 'interception', 'writein'], |
| | | color: ['label', 'field', 'type', 'blacklist', 'readonly', 'required', 'hidden', 'readin', 'writein'], |
| | | funcvar: ['label', 'field', 'type', 'blacklist', 'hidden', 'writein'], |
| | | linkMain: ['label', 'field', 'type', 'readonly', 'required', 'hidden', 'fieldlength', 'blacklist', 'writein'] |
| | | text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine'], |
| | | number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine'], |
| | | select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine'], |
| | | checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'], |
| | | radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'], |
| | | checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'display'], |
| | | multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine'], |
| | | link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine'], |
| | | fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine'], |
| | | switch: ['initval', 'openVal', 'closeVal', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxRows', 'encryption', 'interception'], |
| | | color: ['readonly', 'required', 'hidden', 'readin', 'entireLine'], |
| | | funcvar: ['hidden'], |
| | | linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'entireLine'] |
| | | } |
| | | |
| | | class MainSearch extends Component { |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | optionLibs: PropTypes.any, // 自定义下拉集 |
| | | formlist: PropTypes.any, |
| | | card: PropTypes.object, |
| | | inputSubmit: PropTypes.any |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { optionLibs } = this.props |
| | | let formlist = JSON.parse(JSON.stringify(this.props.formlist)) |
| | | let formlist = fromJS(this.props.formlist).toJS() |
| | | |
| | | let type = '' |
| | | let resourceType = '' |
| | |
| | | } |
| | | }) |
| | | |
| | | let _options = JSON.parse(JSON.stringify(modalTypeOptions[type])) |
| | | |
| | | if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') { // 选择类型、自定义资源 |
| | | _options = [..._options, 'options', 'quick'] |
| | | } else if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '1') { // 选择类型、数据源 |
| | | _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database'] |
| | | } |
| | | |
| | | if (type !== 'funcvar' && type !== 'linkMain') { |
| | | if (supField) { |
| | | _options.push('supField', 'supvalue') |
| | | } else { |
| | | _options.push('supField') |
| | | } |
| | | } |
| | | let _options = this.getOptions(type, resourceType, supField) |
| | | |
| | | this.setState({ |
| | | openType: type, |
| | |
| | | if (dateOptions.hasOwnProperty(type) && form.key === 'initval') { |
| | | form.options = dateOptions[type] |
| | | form.type = 'select' |
| | | } else if (type === 'switch' && form.key === 'initval') { |
| | | form.initVal = !!form.initVal |
| | | form.options = [ |
| | | {value: true, text: '开'}, |
| | | {value: false, text: '关'} |
| | | ] |
| | | form.type = 'radio' |
| | | } else if (type === 'number' && form.key === 'initval') { |
| | | form.type = 'number' |
| | | form.initVal = form.initVal || 0 |
| | | form.required = true |
| | | } else if (form.key === 'quick') { |
| | | form.options = [...optionLibs.values()].map(cell => { |
| | | return { |
| | | value: cell.uuid, |
| | | text: cell.label + '(' + cell.parname + ')' |
| | | } |
| | | }) |
| | | } |
| | | |
| | | form.show = _options.includes(form.key) |
| | |
| | | } |
| | | } |
| | | |
| | | openTypeChange = (key, value) => { |
| | | if (key === 'type') { |
| | | let _options = JSON.parse(JSON.stringify(modalTypeOptions[value])) |
| | | getOptions = (type, resourceType, supField) => { |
| | | let _options = ['label', 'field', 'type', 'blacklist', 'writein', ...fromJS(modalTypeOptions[type]).toJS()] |
| | | |
| | | if ((value === 'multiselect' || value === 'select' || value === 'link') && this.state.resourceType === '0') { // 选择类型、自定义资源 |
| | | _options = [..._options, 'options', 'quick'] |
| | | } else if ((value === 'multiselect' || value === 'select' || value === 'link') && this.state.resourceType === '1') { // 选择类型、数据源 |
| | | if (['multiselect', 'select', 'link', 'radio', 'checkbox', 'checkcard'].includes(type)) { |
| | | if (resourceType === '0') { // 自定义资源 |
| | | _options = [..._options, 'options'] |
| | | } else if (resourceType === '1') { // 数据源 |
| | | _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database'] |
| | | } |
| | | } |
| | | |
| | | if (value !== 'funcvar' && value !== 'linkMain') { |
| | | if (this.state.supField) { |
| | | _options.push('supField', 'supvalue') |
| | | } else { |
| | | _options.push('supField') |
| | | } |
| | | if (type !== 'funcvar' && type !== 'linkMain') { |
| | | if (supField) { |
| | | _options.push('supField', 'supvalue') |
| | | } else { |
| | | _options.push('supField') |
| | | } |
| | | } |
| | | |
| | | return _options |
| | | } |
| | | |
| | | openTypeChange = (key, value) => { |
| | | if (key === 'type') { |
| | | let _options = this.getOptions(value, this.state.resourceType, this.state.supField) |
| | | let fieldValue = {} |
| | | |
| | | this.setState({ |
| | |
| | | if (dateOptions.hasOwnProperty(value)) { |
| | | form.options = dateOptions[value] |
| | | form.type = 'select' |
| | | } else if (value === 'switch') { |
| | | form.initVal = false |
| | | form.options = [ |
| | | {value: true, text: '开'}, |
| | | {value: false, text: '关'} |
| | | ] |
| | | form.type = 'radio' |
| | | } else if (value === 'number') { |
| | | form.type = 'number' |
| | | form.required = true |
| | |
| | | } |
| | | } else if (form.key === 'fieldlength') { |
| | | form.initVal = 50 |
| | | if (value === 'textarea' || value === 'fileupload' || value === 'multiselect') { |
| | | if (value === 'textarea' || value === 'fileupload' || value === 'multiselect' || value === 'checkbox') { |
| | | form.initVal = 512 |
| | | } |
| | | |
| | |
| | | }) |
| | | }, () => { |
| | | this.props.form.setFieldsValue(fieldValue) |
| | | }) |
| | | } else if (key === 'quick') { |
| | | let option = this.props.optionLibs.get(value) |
| | | |
| | | this.setState({ |
| | | formlist: this.state.formlist.map(form => { |
| | | if (form.key === 'options') { |
| | | form.initVal = option.options |
| | | } |
| | | |
| | | return form |
| | | }) |
| | | }) |
| | | } else if (key === 'supField') { |
| | | this.setState({ |
| | |
| | | const { openType } = this.state |
| | | let value = e.target.value |
| | | if (key === 'resourceType') { |
| | | let _options = JSON.parse(JSON.stringify(modalTypeOptions[openType])) |
| | | |
| | | if (value === '0') { |
| | | _options = [..._options, 'options', 'quick'] |
| | | } else if (value === '1') { |
| | | _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database'] |
| | | } |
| | | |
| | | if (openType !== 'funcvar' && openType !== 'linkMain') { |
| | | if (this.state.supField) { |
| | | _options.push('supField', 'supvalue') |
| | | } else { |
| | | _options.push('supField') |
| | | } |
| | | } |
| | | |
| | | let _options = this.getOptions(openType, value, this.state.supField) |
| | | |
| | | this.setState({ |
| | | resourceType: value, |
| | | formlist: this.state.formlist.map(form => { |
| | |
| | | } else if (item.type === 'options') { |
| | | fields.push( |
| | | <Col span={20} offset={4} key={index}> |
| | | <EditTable data={item.initVal} dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/> |
| | | <Form.Item className="text-area"> |
| | | {getFieldDecorator(item.key, { |
| | | initialValue: item.initVal |
| | | })(<EditTable dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields}/>)} |
| | | </Form.Item> |
| | | {/* <EditTable data={item.initVal} dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/> */} |
| | | </Col> |
| | | ) |
| | | } |
| | |
| | | return new Promise((resolve, reject) => { |
| | | this.props.form.validateFieldsAndScroll((err, values) => { |
| | | if (!err) { |
| | | let isvalid = true |
| | | values.uuid = this.props.card.uuid |
| | | // 下拉菜单或联动菜单 |
| | | if ((values.type === 'multiselect' || values.type === 'select' || values.type === 'link') && values.resourceType === '0') { |
| | | values.options = this.refs.editTable.state.dataSource |
| | | values.dataSource = '' |
| | | let emptys = [] |
| | | if (values.type === 'multiselect' || values.type === 'select') { |
| | | emptys = values.options.filter(op => !((op.Value || op.Value === 0) && (op.Text || op.Text === 0))) |
| | | } else { |
| | | emptys = values.options.filter(op => !((op.Value || op.Value === 0) && (op.Text || op.Text === 0) && (op.ParentID || op.ParentID === 0))) |
| | | } |
| | | if (emptys.length > 0) { |
| | | isvalid = false |
| | | notification.warning({ |
| | | top: 92, |
| | | message: this.props.dict['model.form.selectItem.error'], |
| | | duration: 5 |
| | | if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(values.type)) { |
| | | if (values.resourceType === '0') { |
| | | values.options = values.options || [] |
| | | values.dataSource = '' |
| | | let empty = false |
| | | |
| | | values.options.forEach(op => { |
| | | if (!((op.Value || op.Value === 0) && (op.Text || op.Text === 0))) { |
| | | empty = true |
| | | } else if (values.type === 'link' && !(op.ParentID || op.ParentID === 0)) { |
| | | empty = true |
| | | } |
| | | }) |
| | | |
| | | if (empty) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: this.props.dict['model.form.selectItem.error'], |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | } else { |
| | | values.options = [] |
| | | } |
| | | } else if ((values.type === 'multiselect' || values.type === 'select' || values.type === 'link') && values.resourceType === '1') { |
| | | values.options = [] |
| | | } else if (values.type === 'funcvar') { // 函数变量为只读元素 |
| | | values.readonly = 'true' |
| | | } else if (values.type === 'number' && (values.min || values.min === 0) && (values.max || values.max === 0)) { // 数值型验证最小最大值 |
| | | if (values.min > values.max) { |
| | | isvalid = false |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '最小值不可大于最大值!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | } else if (values.type === 'linkMain') { |
| | | values.initval = '' |
| | |
| | | |
| | | ['linkField', 'valueField', 'valueText', 'orderBy'].forEach(item => { |
| | | if (values[item]) { |
| | | values[item] = values[item].replace(/\s* | \t* | \v* | \r*/ig, '') |
| | | values[item] = values[item].replace(/\s*|\t*|\v*|\r*/ig, '') |
| | | } |
| | | }) |
| | | |
| | |
| | | return |
| | | } |
| | | |
| | | if (isvalid) { |
| | | resolve(values) |
| | | } |
| | | resolve(values) |
| | | } else { |
| | | reject(err) |
| | | } |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Table, Input, Popconfirm, Form, Icon, Radio } from 'antd' |
| | | import { formRule } from '@/utils/option.js' |
| | |
| | | } |
| | | |
| | | class EditTable extends Component { |
| | | constructor(props) { |
| | | super(props) |
| | | static propTpyes = { |
| | | dict: PropTypes.object, // 字典项 |
| | | type: PropTypes.string, // 表单类型 |
| | | linkSubFields: PropTypes.array, // 关联字段 |
| | | onChange: PropTypes.func // 数据变化 |
| | | } |
| | | |
| | | state = { |
| | | columns: [], |
| | | dataSource: [], |
| | | count: 0, |
| | | type: null, |
| | | linkSubFields: [] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { linkSubFields, type, dict } = this.props |
| | | let data = this.props['data-__meta'].initialValue |
| | | |
| | | if (!data) { |
| | | data = [] |
| | | } |
| | | |
| | | let _width = '40%' |
| | | let fields = [] |
| | | let dataItem = props.data ? props.data[0] : '' |
| | | let dataItem = data[0] || '' |
| | | |
| | | if (props.type === 'link') { |
| | | if (type === 'link') { |
| | | _width = '27%' |
| | | } else if (props.type === 'select') { |
| | | _width = Math.floor(80 / (props.linkSubFields.length + 2)) + '%' |
| | | fields = props.linkSubFields.map(field => { |
| | | } else if (type === 'select') { |
| | | _width = Math.floor(80 / (linkSubFields.length + 2)) + '%' |
| | | fields = linkSubFields.map(cell => { |
| | | return { |
| | | title: field.label, |
| | | dataIndex: field.field, |
| | | title: cell.label, |
| | | dataIndex: cell.field, |
| | | width: _width, |
| | | editable: true, |
| | | datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string' |
| | | datatype: dataItem && typeof(dataItem[cell.field]) === 'number' ? 'number' : 'string' |
| | | } |
| | | }) |
| | | } |
| | |
| | | render: (text, record) => |
| | | this.state.dataSource.length >= 1 ? ( |
| | | <div> |
| | | <span className="operation-btn" title={props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <span className="operation-btn" title={dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> |
| | | <span className="operation-btn" title={dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> |
| | | <Popconfirm |
| | | overlayClassName="popover-confirm" |
| | | title={props.dict['model.query.delete']} |
| | | title={dict['model.query.delete']} |
| | | onConfirm={() => this.handleDelete(record.key) |
| | | }> |
| | | <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | <span style={{color: '#ff4d4f', cursor: 'pointer'}}><Icon type="delete" /></span> |
| | | </Popconfirm> |
| | | </div> |
| | | ) : null, |
| | | } |
| | | ] |
| | | |
| | | if (props.type === 'link') { |
| | | if (type === 'link') { |
| | | columns.unshift({ |
| | | title: 'ParentID', |
| | | dataIndex: 'ParentID', |
| | |
| | | }) |
| | | } |
| | | |
| | | this.state = { |
| | | this.setState({ |
| | | columns: columns.map(col => { |
| | | if (col.dataIndex !== 'operation') { |
| | | col = {...col, ...this.getColumnSearchProps(col)} |
| | | } |
| | | return col |
| | | }), |
| | | dataSource: props.data, |
| | | count: props.data.length, |
| | | type: props.type, |
| | | linkSubFields: props.linkSubFields |
| | | } |
| | | dataSource: data, |
| | | count: data.length, |
| | | type: type, |
| | | linkSubFields: linkSubFields |
| | | }) |
| | | } |
| | | |
| | | getColumnSearchProps = column => ({ |
| | |
| | | <div style={{ padding: 8 }}> |
| | | <Radio.Group onChange={(e) => this.changeDatatype(column, e)} value={column.datatype}> |
| | | <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="string"> |
| | | String |
| | | 字符串 |
| | | </Radio> |
| | | <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="number"> |
| | | Number |
| | | 数字 |
| | | </Radio> |
| | | </Radio.Group> |
| | | </div> |
| | |
| | | changeDatatype = (column, e) => { |
| | | const { columns, dataSource } = this.state |
| | | let value = e.target.value |
| | | |
| | | this.setState({ |
| | | dataSource: dataSource.map(item => { |
| | | let val = item[column.dataIndex] |
| | | if (value === 'number') { |
| | | try { |
| | | val = parseFloat(val) |
| | | if (isNaN(val)) { |
| | | val = '' |
| | | } |
| | | } catch { |
| | | let _data = dataSource.map(item => { |
| | | let val = item[column.dataIndex] |
| | | if (value === 'number') { |
| | | try { |
| | | val = parseFloat(val) |
| | | if (isNaN(val)) { |
| | | val = '' |
| | | } |
| | | } else { |
| | | val = '' + val |
| | | } catch { |
| | | val = '' |
| | | } |
| | | } else { |
| | | val = '' + val |
| | | } |
| | | |
| | | item[column.dataIndex] = val |
| | | item[column.dataIndex] = val |
| | | |
| | | return item |
| | | }), |
| | | return item |
| | | }) |
| | | |
| | | this.setState({ |
| | | dataSource: _data, |
| | | columns: columns.map(col => { |
| | | if (col.dataIndex === column.dataIndex) { |
| | | col.datatype = value |
| | |
| | | |
| | | return col |
| | | }) |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | |
| | | |
| | | this.setState({ |
| | | dataSource: _data |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | handleDelete = key => { |
| | | const dataSource = [...this.state.dataSource] |
| | | this.setState({ dataSource: dataSource.filter(item => item.key !== key) }) |
| | | const { dataSource } = this.state |
| | | let _data = dataSource.filter(item => item.key !== key) |
| | | |
| | | this.setState({ dataSource: _data }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | | handleAdd = () => { |
| | |
| | | if (type === 'link') { |
| | | newData.ParentID = `${count}` |
| | | } |
| | | |
| | | let _data = [...dataSource, newData] |
| | | |
| | | this.setState({ |
| | | dataSource: [...dataSource, newData], |
| | | dataSource: _data, |
| | | count: count + 1 |
| | | }, () => { |
| | | this.props.onChange(_data) |
| | | }) |
| | | } |
| | | |
| | |
| | | ...item, |
| | | ...row |
| | | }) |
| | | this.setState({ dataSource: newData }) |
| | | this.setState({ dataSource: newData }, () => { |
| | | this.props.onChange(newData) |
| | | }) |
| | | } |
| | | |
| | | resetColumn = (type, linkSubFields) => { |
| | |
| | | }), |
| | | dataSource: dataSource, |
| | | type: type |
| | | }, () => { |
| | | this.props.onChange(dataSource) |
| | | }) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.type !== nextProps.type) { |
| | | this.resetColumn(nextProps.type, nextProps.linkSubFields) |
| | | } else if (!is(fromJS(this.props.data), fromJS(nextProps.data))) { |
| | | let _data = [] |
| | | nextProps.data.forEach(item => { |
| | | let _item = {key: Utils.getuuid()} |
| | | this.state.columns.forEach(col => { |
| | | _item[col.dataIndex] = item[col.dataIndex] || '' |
| | | if (col.dataIndex !== 'ParentID' && !_item[col.dataIndex]) { |
| | | _item[col.dataIndex] = item.Text |
| | | } |
| | | }) |
| | | _data.push(_item) |
| | | }) |
| | | this.setState({ |
| | | dataSource: _data, |
| | | count: nextProps.data.length |
| | | }) |
| | | } |
| | | } |
| | | |