| | |
| | | import { Icon, Popover, Button } from 'antd' |
| | | import './index.scss' |
| | | |
| | | const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, profileCard, changeStyle, doubleClickCard }) => { |
| | | const Card = ({ id, card, moveCard, findCard, editCard, delCard, profileCard, changeStyle, doubleClickCard }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'action', id, originalIndex }, |
| | |
| | | accept: 'action', |
| | | canDrop: () => true, |
| | | drop({ id: draggedId }) { |
| | | if (!draggedId) return |
| | | if (!cardIds.includes(draggedId)) return |
| | | if (!draggedId || draggedId === id) return |
| | | |
| | | if (draggedId !== id) { |
| | | const { index: originIndex } = findCard(draggedId) |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | }, |
| | | }) |
| | | |
| | |
| | | const QrCode = asyncComponent(() => import('@/components/qrcode')) |
| | | const MarkColumn = asyncIconComponent(() => import('@/menu/components/table/normal-table/columns/markcolumn')) |
| | | |
| | | const Card = ({ id, cardIds, fields, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle, updateMarks }) => { |
| | | const Card = ({ id, fields, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle, updateMarks }) => { |
| | | const originalIndex = findCard(id).index |
| | | const [{ isDragging }, drag] = useDrag({ |
| | | item: { type: 'action', id, originalIndex }, |
| | |
| | | accept: 'action', |
| | | canDrop: () => true, |
| | | drop({ id: draggedId }) { |
| | | if (!draggedId) return |
| | | if (!cardIds.includes(draggedId)) return |
| | | if (!draggedId || draggedId === id) return |
| | | |
| | | if (draggedId !== id) { |
| | | const { index: originIndex } = findCard(draggedId) |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | }, |
| | | }) |
| | | |
| | |
| | | deleteMenu(card) |
| | | } |
| | | |
| | | let cardIds = cards.map(card => card.uuid) |
| | | |
| | | const [, drop] = useDrop({ |
| | | accept: 'action', |
| | | drop(item) { |
| | |
| | | <Action |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | cardIds={cardIds} |
| | | card={card} |
| | | moveCard={moveCard} |
| | | editCard={editCard} |
| | |
| | | <Card |
| | | id={card.uuid} |
| | | key={card.uuid} |
| | | cardIds={cardIds} |
| | | card={card} |
| | | fields={fields} |
| | | moveCard={moveCard} |
| | |
| | | onOk() { |
| | | let _elements = elements.filter(item => item.uuid !== card.uuid) |
| | | |
| | | if (card.eleType === 'button') { |
| | | MKEmitter.emit('delButtons', [card.uuid]) |
| | | } |
| | | |
| | | _this.setState({ |
| | | elements: _elements |
| | | }, () => { |
| | |
| | | class CardBoxComponent extends Component { |
| | | static propTpyes = { |
| | | offset: PropTypes.any, // 偏移量 |
| | | MenuType: PropTypes.any, // 菜单类型 |
| | | cards: PropTypes.object, // 卡片行配置信息 |
| | | card: PropTypes.object, // 卡片配置信息 |
| | | deleteElement: PropTypes.func, // 卡片删除 |
| | |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | const { cards, MenuType } = this.props |
| | | const { cards } = this.props |
| | | |
| | | return !is(fromJS(cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState)) || MenuType !== nextProps.MenuType |
| | | return !is(fromJS(cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { cards, MenuType, offset } = this.props |
| | | const { cards, offset } = this.props |
| | | const { card, elements, side, settingVisible, dict } = this.state |
| | | |
| | | let _style = {...card.style} |
| | |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="添加元素" onClick={this.addElement} type="plus" /> |
| | | {MenuType !== 'billPrint' ? <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> : null} |
| | | <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> |
| | | <Icon className="edit" type="edit" onClick={() => this.setState({settingVisible: true})} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | {cards.subtype === 'propcard' ? <Icon className="close" title="删除卡片" type="delete" onClick={() => this.props.deleteElement(card)} /> : null} |
| | | {MenuType !== 'billPrint' && card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null} |
| | | {card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null} |
| | | </div> |
| | | } trigger="hover"> |
| | | <Icon type="tool" /> |
| | |
| | | <SettingForm |
| | | dict={dict} |
| | | cards={cards} |
| | | MenuType={MenuType} |
| | | setting={card.setting} |
| | | inputSubmit={this.settingSubmit} |
| | | wrappedComponentRef={(inst) => this.settingRef = inst} |
| | |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | MenuType: PropTypes.any, // 菜单类型 |
| | | dict: PropTypes.object, // 字典项 |
| | | cards: PropTypes.object, // 卡片集 |
| | | setting: PropTypes.object, // 数据源配置 |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { setting, cards, MenuType } = this.props |
| | | const { setting, cards } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | |
| | | const formItemLayout = { |
| | |
| | | })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit}/>)} |
| | | </Form.Item> |
| | | </Col> |
| | | {MenuType !== 'billPrint' ? <Col span={12}> |
| | | <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="选择复式卡时,可配置鼠标悬浮时的显示信息。"> |
| | | <Icon type="question-circle" /> |
| | |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {MenuType !== 'billPrint' && this.state.type === 'multi' ? <Col span={12}> |
| | | </Col> |
| | | {this.state.type === 'multi' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="复式卡片鼠标悬浮信息的动画效果。"> |
| | | <Icon type="question-circle" /> |
| | |
| | | columns: [], |
| | | scripts: [], |
| | | action: [], |
| | | btnlog: [], |
| | | subcards: subcards |
| | | } |
| | | this.setState({ |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menu } = this.props |
| | | const { card } = this.state |
| | | |
| | | let offset = 0 |
| | |
| | | <NormalHeader defaultshow="hidden" config={card} updateComponent={this.updateComponent}/> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> : null} |
| | | {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> : null} |
| | | {menu ? <WrapComponent MenuType={menu.MenuType} config={card} updateConfig={this.updateComponent} /> : null} |
| | | <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> |
| | | <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> |
| | | <WrapComponent config={card} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent} /> |
| | |
| | | <Icon type="tool" /> |
| | | </Popover> |
| | | <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/> |
| | | {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} offset={!index ? offset : 0} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))} |
| | | {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} offset={!index ? offset : 0} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))} |
| | | <div style={{clear: 'both'}}></div> |
| | | {card.wrap.pagestyle !== 'switch' && card.setting.laypage === 'true' ? <Pagination total={85} size="small" showTotal={total => `共 ${total} 条`} pageSize={20} defaultCurrent={1}/> : null} |
| | | </div> |
| | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | MenuType: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { config, MenuType } = this.props |
| | | const { config } = this.props |
| | | const { visible, dict, wrap } = this.state |
| | | |
| | | return ( |
| | |
| | | dict={dict} |
| | | wrap={wrap} |
| | | config={config} |
| | | MenuType={MenuType} |
| | | inputSubmit={this.verifySubmit} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | MenuType: PropTypes.any, // 菜单类型 |
| | | dict: PropTypes.object, // 字典项 |
| | | config: PropTypes.object, // 卡片行信息 |
| | | wrap: PropTypes.object, // 数据源配置 |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { wrap, config, MenuType } = this.props |
| | | const { wrap, config } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { roleList } = this.state |
| | | |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {MenuType !== 'billPrint' && config.subtype === 'datacard' ? <Col span={12}> |
| | | {config.subtype === 'datacard' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="数据源中选择分页时有效。"> |
| | | <Icon type="question-circle" /> |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {MenuType !== 'billPrint' && config.subtype !== 'tablecard' ? <Col span={12}> |
| | | {config.subtype !== 'tablecard' ? <Col span={12}> |
| | | <Form.Item label="卡片属性"> |
| | | {getFieldDecorator('cardType', { |
| | | initialValue: wrap.cardType || '' |
| | |
| | | })(<InputNumber min={100} max={2000} precision={0} onPressEnter={this.handleSubmit} />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {MenuType === 'billPrint' && config.subtype === 'propcard' ? <Col span={12}> |
| | | {config.subtype === 'propcard' ? <Col span={12}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="选择类型为《页眉/页脚》时,打印的每页里都会带有该组件。"> |
| | | <Icon type="question-circle" /> |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {MenuType !== 'billPrint' ? <Col span={12}> |
| | | <Col span={12}> |
| | | <Form.Item label="黑名单"> |
| | | {getFieldDecorator('blacklist', { |
| | | initialValue: wrap.blacklist || [] |
| | |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | |
| | | columns: [], |
| | | scripts: [], |
| | | subcards: subcards, |
| | | btnlog: [], |
| | | } |
| | | this.setState({ |
| | | card: _card |
| | |
| | | headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, |
| | | columns: [], |
| | | scripts: [], |
| | | subcards: subcards |
| | | subcards: subcards, |
| | | btnlog: [], |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | /** |
| | | * @description 获取图表视图配置表单 |
| | | * @param {object} card // 图表对象 |
| | | * @param {Array} MenuType // 菜单类型 |
| | | */ |
| | | export function getBaseForm (card, MenuType) { |
| | | export function getBaseForm (card) { |
| | | let menulist = sessionStorage.getItem('fstMenuList') |
| | | if (menulist) { |
| | | try { |
| | |
| | | initVal: card.blacklist || [], |
| | | multi: true, |
| | | required: false, |
| | | forbid: MenuType === 'billPrint', |
| | | options: roleList |
| | | }, |
| | | { |
| | |
| | | initVal: card.linkmenu || [], |
| | | tooltip: '在使用柱形图且未启用自定义设置时有效。', |
| | | required: false, |
| | | forbid: MenuType === 'billPrint', |
| | | options: menulist |
| | | } |
| | | ] |
| | |
| | | * @param {object} card // 图表对象 |
| | | * @param {Array} columns // 显示列 |
| | | */ |
| | | export function getOptionForm (card, columns, MenuType) { |
| | | export function getOptionForm (card, columns) { |
| | | let shapes = [] |
| | | |
| | | if (card.chartType === 'line') { |
| | |
| | | |
| | | class LineChartDrawerForm extends Component { |
| | | static propTpyes = { |
| | | MenuType: PropTypes.any, |
| | | dict: PropTypes.object, |
| | | plot: PropTypes.object, |
| | | config: PropTypes.object, |
| | |
| | | } |
| | | |
| | | showDrawer = () => { |
| | | const { config, MenuType } = this.props |
| | | const { config } = this.props |
| | | |
| | | let fieldName = {} |
| | | config.columns.forEach(col => { |
| | |
| | | datatype: config.plot.datatype || 'query', |
| | | fieldName: fieldName, |
| | | plot: fromJS(config.plot).toJS(), |
| | | baseFormlist: getBaseForm(config.plot, MenuType), |
| | | formlist: getOptionForm(config.plot, config.columns, MenuType) |
| | | baseFormlist: getBaseForm(config.plot), |
| | | formlist: getOptionForm(config.plot, config.columns) |
| | | }) |
| | | } |
| | | |
| | |
| | | scripts: [], |
| | | search: [], |
| | | action: [], |
| | | plot: _plot |
| | | plot: _plot, |
| | | btnlog: [], |
| | | } |
| | | this.setState({ |
| | | card: _card |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menu } = this.props |
| | | const { card } = this.state |
| | | |
| | | return ( |
| | |
| | | <NormalHeader config={card} updateComponent={this.updateComponent}/> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> : null} |
| | | {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> : null} |
| | | {menu ? <ChartCompileForm config={card} MenuType={menu.MenuType} dict={this.state.dict} plotchange={this.updateComponent}/> : null} |
| | | <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}/> |
| | |
| | | } trigger="hover"> |
| | | <Icon type="tool" /> |
| | | </Popover> |
| | | {menu && menu.MenuType !== 'billPrint' ? <ActionComponent |
| | | <ActionComponent |
| | | type="chart" |
| | | config={card} |
| | | updateaction={this.updateComponent} |
| | | /> : null} |
| | | /> |
| | | <div className="canvas" id={card.uuid}></div> |
| | | </div> |
| | | ) |
| | |
| | | /** |
| | | * @description 获取图表视图配置表单 |
| | | * @param {object} card // 图表对象 |
| | | * @param {Array} MenuType // 菜单类型 |
| | | */ |
| | | export function getBaseForm (card, MenuType) { |
| | | export function getBaseForm (card) { |
| | | let menulist = sessionStorage.getItem('fstMenuList') |
| | | if (menulist) { |
| | | try { |
| | |
| | | initVal: card.blacklist || [], |
| | | multi: true, |
| | | required: false, |
| | | forbid: MenuType === 'billPrint', |
| | | options: roleList |
| | | }, |
| | | { |
| | |
| | | initVal: card.linkmenu || [], |
| | | tooltip: '双击饼图,会打开关联的菜单。', |
| | | required: false, |
| | | forbid: MenuType === 'billPrint', |
| | | options: menulist |
| | | } |
| | | ] |
| | |
| | | |
| | | class LineChartDrawerForm extends Component { |
| | | static propTpyes = { |
| | | MenuType: PropTypes.any, |
| | | dict: PropTypes.object, |
| | | plot: PropTypes.object, |
| | | config: PropTypes.object, |
| | |
| | | } |
| | | |
| | | showDrawer = () => { |
| | | const { config, MenuType } = this.props |
| | | const { config } = this.props |
| | | |
| | | this.setState({ |
| | | visible: true, |
| | | view: 'normal', |
| | | plot: fromJS(config.plot).toJS(), |
| | | baseFormlist: getBaseForm(config.plot, MenuType), |
| | | baseFormlist: getBaseForm(config.plot), |
| | | formlist: getOptionForm(config.plot, config.columns) |
| | | }) |
| | | } |
| | |
| | | scripts: [], |
| | | search: [], |
| | | action: [], |
| | | plot: _plot |
| | | plot: _plot, |
| | | btnlog: [], |
| | | } |
| | | this.props.updateConfig(_card) |
| | | this.setState({ |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menu } = this.props |
| | | const { card } = this.state |
| | | |
| | | return ( |
| | |
| | | <NormalHeader config={card} updateComponent={this.updateComponent}/> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> : null} |
| | | {menu ? <ChartCompileForm config={card} MenuType={menu.MenuType} dict={this.state.dict} plotchange={this.updateComponent}/> : null} |
| | | <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> |
| | | <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}/> |
| | |
| | | accept: 'search', |
| | | canDrop: () => true, |
| | | drop: ({ id: draggedId }) => { |
| | | if (!draggedId) return |
| | | if (draggedId !== id) { |
| | | if (!draggedId || draggedId === id) return |
| | | const { index: originIndex } = findCard(draggedId) |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | | moveCard(draggedId, overIndex) |
| | | } |
| | | }, |
| | | }) |
| | | const opacity = isDragging ? 0 : 1 |
| | |
| | | const [, drop] = useDrop({ |
| | | accept: 'action', |
| | | canDrop: () => true, |
| | | drop: () => {}, |
| | | hover({ id: draggedId }) { |
| | | drop: ({ id: draggedId }) => { |
| | | if (!draggedId || draggedId === id) return |
| | | |
| | | const { index: originIndex } = findCard(id) |
| | | const { index: originIndex } = findCard(draggedId) |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | |
| | | |
| | | _actionlist = _actionlist.filter(item => item.uuid !== card.uuid) |
| | | |
| | | let delButtons = sessionStorage.getItem('delButtons') |
| | | try { |
| | | delButtons = JSON.parse(delButtons) |
| | | delButtons.push(card.uuid) |
| | | } catch { |
| | | delButtons = [card.uuid] |
| | | if (!card.origin) { |
| | | MKEmitter.emit('delButtons', [card.uuid]) |
| | | } |
| | | sessionStorage.setItem('delButtons', JSON.stringify(delButtons)) |
| | | |
| | | _this.setState({ |
| | | actionlist: _actionlist |
| | |
| | | if (!draggedId || draggedId === id) return |
| | | |
| | | const { index: originIndex } = findCard(draggedId) |
| | | |
| | | if (originIndex === -1) return |
| | | |
| | | const { index: overIndex } = findCard(id) |
| | |
| | | }, { |
| | | value: 'custom', |
| | | text: '自定义列' |
| | | }, { |
| | | value: 'colspan', |
| | | text: '合并列' |
| | | }] |
| | | |
| | | if (!card.isSub) { |
| | | options.push({ |
| | | value: 'colspan', |
| | | text: '合并列' |
| | | }, { |
| | | value: 'action', |
| | | text: '操作' |
| | | }) |
| | |
| | | label: Formdict['model.sort'], |
| | | initVal: card.IsSort || 'true', |
| | | required: true, |
| | | forbidden: card.isSub, |
| | | options: [{ |
| | | value: 'true', |
| | | text: Formdict['model.true'] |
| | |
| | | }) |
| | | } else if (key === 'field') { |
| | | this.props.form.setFieldsValue({label: option.props.children}) |
| | | if (this.state.type === 'number') { |
| | | let decimal = 0 |
| | | if (/Decimal/ig.test(option.props.datatype)) { |
| | | decimal = +option.props.datatype.replace(/Decimal\(18,/ig, '').replace(')', '') |
| | | } |
| | | this.props.form.setFieldsValue({decimal}) |
| | | } |
| | | } else if (key === 'format' && value === 'percent') { |
| | | this.props.form.setFieldsValue({postfix: '%'}) |
| | | } |
| | |
| | | if (!formlist) return null |
| | | |
| | | formlist.forEach((item, index) => { |
| | | if (item.hidden) return |
| | | if (item.hidden || item.forbidden) return |
| | | |
| | | if (item.type === 'text') { // 文本搜索 |
| | | let rules = [] |
| | |
| | | getPopupContainer={() => document.getElementById('columnwinter')} |
| | | > |
| | | {item.options.map((option, index) => |
| | | <Select.Option key={`${option.value || option.field}${index}`} value={option.value || option.field}> |
| | | <Select.Option key={`${option.value || option.field}${index}`} datatype={option.datatype || ''} value={option.value || option.field}> |
| | | {option.text || option.label} |
| | | </Select.Option> |
| | | )} |
| | |
| | | |
| | | return !is(fromJS(this.props.column), fromJS(nextProps.column)) || |
| | | !is(fromJS(this.props.fields), fromJS(nextProps.fields)) || |
| | | this.props.index !== nextProps.index |
| | | this.props.index !== nextProps.index || |
| | | this.props.rowSpan !== nextProps.rowSpan || |
| | | this.props.colSpan !== nextProps.colSpan |
| | | } |
| | | |
| | | render() { |
| | |
| | | ) |
| | | } else if (column) { |
| | | return ( |
| | | <th {...restProps}> |
| | | <th {...restProps} key={column.uuid}> |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | {column && column.type === 'custom' ? |
| | | {column && ['custom', 'colspan'].includes(column.type) ? |
| | | <Icon className="plus" title="添加" type="plus" onClick={() => this.props.addElement(column)} /> : null |
| | | } |
| | | <Icon className="edit" title="编辑" type="edit" onClick={() => this.props.editColumn(column)} /> |
| | |
| | | return ( |
| | | <td style={{...style, minWidth: column.Width || 100}} className={className}> |
| | | {column.field} |
| | | {column.marks && column.marks.length > 0 ? <Icon className="profile" type="ant-design"/> : null} |
| | | {column.marks && column.marks.length ? <Icon className="profile" type="ant-design"/> : null} |
| | | </td> |
| | | ) |
| | | } else { |
| | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | data: [{uuid: Utils.getuuid()}], |
| | | refresh: false, // 强制刷新 |
| | | columns: [], |
| | | fields: [], |
| | | lineMarks: [] |
| | |
| | | }) |
| | | } |
| | | |
| | | updateCol = (col, action) => { |
| | | let _columns = fromJS(this.state.columns).toJS() |
| | | |
| | | if (col.isSub) { |
| | | _columns = _columns.map(column => { |
| | | loopCol = (columns, col) => { |
| | | return columns.map(column => { |
| | | if (column.type === 'colspan') { |
| | | column.subcols = column.subcols.map(item => { |
| | | if (item.uuid === col.uuid) { |
| | | return col |
| | | column.subcols = this.loopCol(column.subcols, col) |
| | | } |
| | | return item |
| | | }) |
| | | } |
| | | return column |
| | | }) |
| | | } else { |
| | | _columns = _columns.map(column => { |
| | | if (column.uuid === col.uuid) { |
| | | return col |
| | | } |
| | | return column |
| | | }) |
| | | } |
| | | |
| | | updateCol = (col, action) => { |
| | | let _columns = fromJS(this.state.columns).toJS() |
| | | _columns = this.loopCol(_columns, col) |
| | | |
| | | this.setState({ |
| | | columns: _columns, |
| | |
| | | this.setState({card: null}) |
| | | } |
| | | |
| | | loopDelCol = (columns, col) => { |
| | | return columns.filter(column => { |
| | | if (column.type === 'colspan') { |
| | | column.subcols = this.loopDelCol(column.subcols, col) |
| | | } |
| | | return column.uuid !== col.uuid |
| | | }) |
| | | } |
| | | |
| | | deleteCol = (col) => { |
| | | let _columns = fromJS(this.state.columns).toJS() |
| | | |
| | | if (col.isSub) { |
| | | _columns = _columns.map(column => { |
| | | if (column.type !== 'colspan') return column |
| | | if (column.subcols && column.subcols.length > 0) { |
| | | column.subcols = column.subcols.filter(item => item.uuid !== col.uuid) |
| | | } |
| | | return column |
| | | }) |
| | | } else { |
| | | _columns = _columns.filter(column => column.uuid !== col.uuid) |
| | | } |
| | | _columns = this.loopDelCol(_columns, col) |
| | | |
| | | this.setState({ |
| | | columns: _columns |
| | |
| | | document.body.removeChild(oInput) |
| | | } |
| | | |
| | | handlecolumns = (columns, fields, config, isSub) => { |
| | | return columns.map((col, index) => { |
| | | return { |
| | | title: col.label, |
| | | dataIndex: col.uuid, |
| | | align: col.Align, |
| | | sorter: !isSub && col.IsSort === 'true', |
| | | onCell: () => ({ |
| | | column: col, |
| | | width: col.Width, |
| | | config: config, |
| | | upComponent: this.updateCol |
| | | }), |
| | | onHeaderCell: () => ({ |
| | | index: isSub ? undefined : index, |
| | | column: col, |
| | | fields: fields, |
| | | align: col.Align, |
| | | moveCol: this.moveCol, |
| | | updateCol: this.updateCol, |
| | | addElement: this.addElement, |
| | | editColumn: this.editColumn, |
| | | deleteCol: this.deleteCol, |
| | | }), |
| | | children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, true) : null, |
| | | } |
| | | }) |
| | | } |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { fields, card, lineMarks, dict } = this.state |
| | |
| | | } |
| | | } |
| | | |
| | | const columns = this.state.columns.map((col, index) => { |
| | | return { |
| | | title: col.label, |
| | | dataIndex: col.field, |
| | | align: col.Align, |
| | | sorter: col.IsSort === 'true', |
| | | onCell: () => ({ |
| | | column: col, |
| | | width: col.Width, |
| | | config: config, |
| | | upComponent: this.updateCol |
| | | }), |
| | | children: col.subcols && col.subcols.length > 0 ? col.subcols.map(cell => ({ |
| | | align: col.Align, |
| | | title: cell.label, |
| | | key: cell.uuid, |
| | | onCell: () => ({ |
| | | column: cell, |
| | | width: cell.Width, |
| | | config: config, |
| | | upComponent: this.updateCol |
| | | }), |
| | | onHeaderCell: () => ({ |
| | | column: cell, |
| | | fields: fields, |
| | | align: cell.Align, |
| | | updateCol: this.updateCol, |
| | | addElement: this.addElement, |
| | | editColumn: this.editColumn, |
| | | deleteCol: this.deleteCol, |
| | | }) |
| | | })) : null, |
| | | onHeaderCell: () => ({ |
| | | index, |
| | | column: col, |
| | | fields: fields, |
| | | align: col.Align, |
| | | moveCol: this.moveCol, |
| | | updateCol: this.updateCol, |
| | | addElement: this.addElement, |
| | | editColumn: this.editColumn, |
| | | deleteCol: this.deleteCol, |
| | | }) |
| | | } |
| | | }) |
| | | const columns = this.handlecolumns(this.state.columns, fields, config) |
| | | |
| | | return ( |
| | | <div className={`normal-table-columns ${config.setting.laypage} ${config.wrap.tableType}`}> |
| | |
| | | <DndProvider> |
| | | <Table |
| | | rowKey="uuid" |
| | | rowClassName="editable-row" |
| | | bordered={config.wrap.bordered !== 'false'} |
| | | components={components} |
| | | dataSource={this.state.data} |
| | | rowSelection={config.wrap.tableType ? { type: 'radio' } : null} |
| | | columns={columns} |
| | | rowClassName="editable-row" |
| | | pagination={{ |
| | | current: 1, |
| | | pageSize: 10, |
| | |
| | | { origin: true, uuid: Utils.getuuid(), Align: 'left', label: 'label2', field: '', Hide: 'false', IsSort: 'true', type: 'text', Width: 120 }, |
| | | { origin: true, uuid: Utils.getuuid(), Align: 'left', label: 'label3', field: '', Hide: 'false', IsSort: 'true', type: 'text', Width: 120 }, |
| | | ], |
| | | scripts: [] |
| | | scripts: [], |
| | | btnlog: [], |
| | | } |
| | | |
| | | this.setState({ |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { menu } = this.props |
| | | const { card } = this.state |
| | | |
| | | return ( |
| | |
| | | <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ |
| | | <div className="mk-popover-control"> |
| | | <Icon className="plus" title="添加列" onClick={this.addColumns} type="plus" /> |
| | | {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> : null} |
| | | {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> : null} |
| | | {menu ? <WrapComponent config={card} MenuType={menu.MenuType} updateConfig={this.updateComponent} /> : null} |
| | | <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> |
| | | <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> |
| | | <WrapComponent config={card} updateConfig={this.updateComponent} /> |
| | | <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" /> |
| | | <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> |
| | | <SettingComponent config={card} updateConfig={this.updateComponent} /> |
| | |
| | | class DataSource extends Component { |
| | | static propTpyes = { |
| | | config: PropTypes.any, |
| | | MenuType: PropTypes.any, |
| | | updateConfig: PropTypes.func |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { config, MenuType } = this.props |
| | | const { config } = this.props |
| | | const { visible, dict, wrap } = this.state |
| | | |
| | | return ( |
| | |
| | | dict={dict} |
| | | wrap={wrap} |
| | | config={config} |
| | | MenuType={MenuType} |
| | | inputSubmit={this.verifySubmit} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | |
| | | |
| | | class SettingForm extends Component { |
| | | static propTpyes = { |
| | | MenuType: PropTypes.any, // 菜单类型 |
| | | dict: PropTypes.object, // 字典项 |
| | | config: PropTypes.object, // 卡片行信息 |
| | | wrap: PropTypes.object, // 数据源配置 |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { wrap, MenuType, config } = this.props |
| | | const { wrap, config } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { roleList } = this.state |
| | | |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> |
| | | {MenuType !== 'billPrint' ? <Col span={12}> |
| | | <Col span={12}> |
| | | <Form.Item label="黑名单"> |
| | | {getFieldDecorator('blacklist', { |
| | | initialValue: wrap.blacklist || [] |
| | |
| | | </Select> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { setting, menu, columns, config } = this.props |
| | | const { setting, columns, config } = this.props |
| | | const { getFieldDecorator } = this.props.form |
| | | const { interType, modules, useMSearch, laypage, supModule, usefulFields } = this.state |
| | | |
| | |
| | | </Radio.Group>)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {menu.MenuType !== 'billPrint' ? <Col span={8}> |
| | | <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'该组件如果受其他组件控制,请选项相应的组件,没有时选“无”。'}> |
| | | <Icon type="question-circle" /> |
| | |
| | | <Cascader options={modules} onChange={this.changeSupModule} expandTrigger="hover" placeholder="" /> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {menu.MenuType !== 'billPrint' && config.pageable ? <Col span={8}> |
| | | </Col> |
| | | {config.pageable ? <Col span={8}> |
| | | <Form.Item label="分页"> |
| | | {getFieldDecorator('laypage', { |
| | | initialValue: setting.laypage || 'true' |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {menu.MenuType !== 'billPrint' && config.pageable && laypage !== 'false' ? <Col span={8}> |
| | | {config.pageable && laypage !== 'false' ? <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title="选择分页时有效。"> |
| | | <Icon type="question-circle" /> |
| | |
| | | })(<InputNumber min={1} max={500} precision={0} />)} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {/* 1、不分页且不存在上级模块 2、打印时 */} |
| | | {((!config.pageable || (config.pageable && laypage === 'false')) && (!supModule || supModule.length === 0 || supModule[0] === 'empty')) || menu.MenuType === 'billPrint' ? <Col span={8}> |
| | | {/* 1、不分页且不存在上级模块 */} |
| | | {(!config.pageable || (config.pageable && laypage === 'false')) && (!supModule || supModule.length === 0 || supModule[0] === 'empty') ? <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'初始化加载时,是否与其他组件一同加载数据,注:仅在使用系统函数,且初始化加载数据时有效,分页请求时无效。'}> |
| | | <Icon type="question-circle" /> |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {menu.MenuType !== 'billPrint' ? <Col span={8}> |
| | | <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'优先使用同级的搜索条件组件,同级搜索不存在时,依次向上选取,与当前组件的搜索条件一同用作数据过滤(当前组件的搜索条件优先)。'}> |
| | | <Icon type="question-circle" /> |
| | |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {menu.MenuType !== 'billPrint' && useMSearch === 'true' ? <Col span={8}> |
| | | </Col> |
| | | {useMSearch === 'true' ? <Col span={8}> |
| | | <Form.Item label={ |
| | | <Tooltip placement="topLeft" title={'外层搜索条件改变时,是否刷新当前组件数据。'}> |
| | | <Icon type="question-circle" /> |
| | |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | {menu.MenuType !== 'billPrint' ? <Col span={8}> |
| | | <Col span={8}> |
| | | <Form.Item label="初始化数据"> |
| | | {getFieldDecorator('onload', { |
| | | initialValue: setting.onload || 'true' |
| | |
| | | </Radio.Group> |
| | | )} |
| | | </Form.Item> |
| | | </Col> : null} |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </div> |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import { is, fromJS } from 'immutable' |
| | | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import PopConfig from '@/menu/popview' |
| | | |
| | | class PopviewController extends Component { |
| | | state = { |
| | | btn: null, |
| | | config: null, |
| | | visible: false |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('changePopview', this.initConfig) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新,清除快捷键设置 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('changePopview', this.initConfig) |
| | | } |
| | | |
| | | initConfig = (config, btn) => { |
| | | this.setState({ |
| | | visible: true, |
| | | config: fromJS(config).toJS(), |
| | | btn: fromJS(btn).toJS() |
| | | }) |
| | | } |
| | | |
| | | handleBack = () => { |
| | | this.setState({ |
| | | visible: false, |
| | | config: null, |
| | | btn: null |
| | | }) |
| | | } |
| | | |
| | | handleSave = (modal) => { |
| | | const { config, btn } = this.state |
| | | MKEmitter.emit('submitModal', config, btn, modal) |
| | | |
| | | this.setState({ |
| | | visible: false, |
| | | config: null, |
| | | btn: null |
| | | }) |
| | | } |
| | | |
| | | render () { |
| | | const { config, btn, visible } = this.state |
| | | |
| | | if (!visible) return null |
| | | |
| | | return ( |
| | | <PopConfig btn={btn} componentConfig={config} handleBack={this.handleBack} handleSave={this.handleSave}/> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default PopviewController |
New file |
| | |
| | | import React, { Component } from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { connect } from 'react-redux' |
| | | import { DndProvider } from 'react-dnd' |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { notification, Modal, Collapse, Card, Switch, Button } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import zhCN from '@/locales/zh-CN/mob.js' |
| | | import enUS from '@/locales/en-US/mob.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { modifyCustomMenu } from '@/store/action' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { Panel } = Collapse |
| | | const { confirm } = Modal |
| | | |
| | | const Header = asyncComponent(() => import('@/menu/header')) |
| | | const SourceWrap = asyncComponent(() => import('@/menu/modelsource')) |
| | | const MenuShell = asyncComponent(() => import('@/menu/menushell')) |
| | | const BgController = asyncComponent(() => import('@/menu/bgcontroller')) |
| | | const PaddingController = asyncComponent(() => import('@/menu/padcontroller')) |
| | | const StyleController = asyncComponent(() => import('@/menu/stylecontroller')) |
| | | const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller')) |
| | | const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent')) |
| | | |
| | | sessionStorage.setItem('isEditState', 'true') |
| | | |
| | | class MenuDesign extends Component { |
| | | static propTpyes = { |
| | | btn: PropTypes.object, |
| | | handleSave: PropTypes.func, |
| | | handleBack: PropTypes.func |
| | | } |
| | | |
| | | state = { |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | MenuType: '', |
| | | MenuId: '', |
| | | MenuNo: '', |
| | | tableFields: [], |
| | | delButtons: [], |
| | | activeKey: 'basedata', |
| | | menuloading: false, |
| | | oriConfig: null, |
| | | openEdition: '', |
| | | config: null, |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { btn } = this.props |
| | | |
| | | this.setState({ |
| | | MenuId: btn.uuid, |
| | | }, () => { |
| | | this.getMenuParam() |
| | | }) |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | } |
| | | |
| | | closeView = () => { |
| | | const { oriConfig, config } = this.state |
| | | |
| | | if (!config) { |
| | | window.close() |
| | | return |
| | | } |
| | | |
| | | let _config = fromJS(config).toJS() |
| | | delete _config.tableFields |
| | | |
| | | if (!is(fromJS(oriConfig), fromJS(_config))) { |
| | | confirm({ |
| | | title: '配置已修改,放弃保存吗?', |
| | | content: '', |
| | | onOk() { |
| | | window.close() |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | window.close() |
| | | } |
| | | } |
| | | |
| | | getMenuParam = () => { |
| | | const { MenuId, MenuType } = this.state |
| | | |
| | | let param = { |
| | | func: 'sPC_Get_LongParam', |
| | | MenuID: MenuId |
| | | } |
| | | |
| | | Api.getSystemConfig(param).then(result => { |
| | | if (result.status) { |
| | | let config = null |
| | | |
| | | try { |
| | | config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) |
| | | } catch (e) { |
| | | console.warn('Parse Failure') |
| | | config = null |
| | | } |
| | | |
| | | if (!config) { |
| | | config = { |
| | | version: 1.0, |
| | | uuid: MenuId, |
| | | MenuID: MenuId, |
| | | Template: 'CustomPage', |
| | | enabled: false, |
| | | tables: [], |
| | | components: [], |
| | | style: { |
| | | backgroundColor: '#ffffff', backgroundImage: '', |
| | | paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px' |
| | | }, |
| | | MenuType: MenuType |
| | | } |
| | | } else { |
| | | config.uuid = MenuId |
| | | config.MenuID = MenuId |
| | | config.MenuType = config.MenuType || MenuType |
| | | } |
| | | |
| | | this.setState({ |
| | | oriConfig: config, |
| | | config: fromJS(config).toJS(), |
| | | openEdition: result.open_edition || '', |
| | | }) |
| | | |
| | | this.getRoleFields() |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | getMenuMessage = () => { |
| | | const { config } = this.state |
| | | let buttons = [] |
| | | let _sort = 1 |
| | | |
| | | let traversal = (components) => { |
| | | components.forEach(item => { |
| | | if (item.type === 'tabs') { |
| | | item.subtabs.forEach(tab => { |
| | | traversal(tab.components) |
| | | }) |
| | | } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { |
| | | item.action && item.action.forEach(btn => { |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | item.subcards.forEach(card => { |
| | | card.elements && card.elements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | card.backElements && card.backElements.forEach(cell => { |
| | | if (cell.eleType !== 'button') return |
| | | |
| | | buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | }) |
| | | } else if (item.type === 'line' || item.type === 'bar') { |
| | | item.action && item.action.forEach(btn => { |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.origin) return |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | item.cols && item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | col.elements.forEach(btn => { |
| | | buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) |
| | | _sort++ |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | traversal(config.components) |
| | | |
| | | return buttons |
| | | } |
| | | |
| | | filterConfig = (components) => { |
| | | return components.map(item => { |
| | | if (item.type === 'tabs') { |
| | | item.subtabs.forEach(tab => { |
| | | tab.components = this.filterConfig(tab.components) |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.search = item.search.filter(a => !a.origin) |
| | | item.action = item.action.filter(a => !a.origin) |
| | | item.cols = item.cols.filter(a => !a.origin) |
| | | } |
| | | return item |
| | | }) |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { openEdition } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if (config.cacheUseful === 'true' && !config.cacheTime) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善菜单基本信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | config.components = this.filterConfig(config.components) |
| | | |
| | | if (config.enabled && this.verifyConfig()) { |
| | | config.enabled = false |
| | | } |
| | | |
| | | let _config = fromJS(config).toJS() |
| | | delete _config.tableFields |
| | | |
| | | let param = { |
| | | func: 'sPC_TrdMenu_AddUpt', |
| | | FstID: _config.fstMenuId || '', |
| | | SndID: _config.parentId, |
| | | ParentID: _config.parentId, |
| | | MenuID: _config.uuid, |
| | | MenuNo: _config.MenuNo || '', |
| | | EasyCode: _config.easyCode || '', |
| | | Template: 'CustomPage', |
| | | MenuName: _config.MenuName || '', |
| | | PageParam: JSON.stringify({Template: 'CustomPage', OpenType: 'newtab'}), |
| | | LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_config))), |
| | | LText: '', |
| | | LTexttb: '' |
| | | } |
| | | |
| | | 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 (openEdition) { // 版本管理 |
| | | param.open_edition = openEdition |
| | | } |
| | | |
| | | let btnParam = { // 添加菜单按钮 |
| | | func: 'sPC_Button_AddUpt', |
| | | Type: 40, // 添加菜单下的按钮type为40,按钮下的按钮type为60 |
| | | ParentID: _config.uuid, |
| | | MenuNo: _config.MenuNo, |
| | | Template: 'CustomPage', |
| | | PageParam: '', |
| | | LongParam: '', |
| | | LText: [] |
| | | } |
| | | |
| | | btnParam.LText = this.getMenuMessage() |
| | | btnParam.LText = btnParam.LText.join(' union all ') |
| | | btnParam.LText = Utils.formatOptions(btnParam.LText) |
| | | btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | btnParam.secretkey = Utils.encrypt(btnParam.LText, btnParam.timestamp) |
| | | |
| | | this.setState({ |
| | | menuloading: true |
| | | }, () => { |
| | | new Promise(resolve => { |
| | | resolve(true) |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | return Api.getSystemConfig(param) |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | if (res.status) { |
| | | this.setState({ |
| | | oriConfig: fromJS(_config).toJS(), |
| | | openEdition: res.open_edition || '' |
| | | }) |
| | | |
| | | if (btnParam.LText) { |
| | | return Api.getSystemConfig(btnParam) |
| | | } else { |
| | | return { |
| | | status: true |
| | | } |
| | | } |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | return false |
| | | } |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | if (res.status) { |
| | | this.setState({ |
| | | menuloading: false, |
| | | config: {...config, components: []} |
| | | }, () => { |
| | | this.setState({ |
| | | config: {...this.state.config, components: this.state.oriConfig.components} |
| | | }) |
| | | }) |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功', |
| | | duration: 2 |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | getRoleFields = () => { |
| | | Api.getSystemConfig({func: 'sPC_Get_Roles_sModular'}).then(res => { |
| | | if (res.status) { |
| | | let _permFuncField = [] |
| | | let _sysRoles = [] |
| | | |
| | | if (res.Roles && res.Roles.length > 0) { |
| | | _sysRoles = res.Roles.map(role => { |
| | | return { |
| | | uuid: Utils.getuuid(), |
| | | value: role.RoleID, |
| | | text: role.RoleName |
| | | } |
| | | }) |
| | | } |
| | | |
| | | if (res.sModular && res.sModular.length > 0) { |
| | | res.sModular.forEach(field => { |
| | | if (field.ModularNo) { |
| | | _permFuncField.push(field.ModularNo) |
| | | } |
| | | }) |
| | | _permFuncField = _permFuncField.sort() |
| | | } |
| | | |
| | | sessionStorage.setItem('sysRoles', JSON.stringify(_sysRoles)) |
| | | sessionStorage.setItem('permFuncField', JSON.stringify(_permFuncField)) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | onEnabledChange = () => { |
| | | const { config } = this.state |
| | | |
| | | if (!config.enabled && this.verifyConfig(true)) { |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | config: {...config, enabled: !config.enabled} |
| | | }) |
| | | } |
| | | |
| | | verifyConfig = (show) => { |
| | | const { config } = this.state |
| | | let error = '' |
| | | |
| | | config.components.forEach(item => { |
| | | if (error) return |
| | | if (item.subtype === 'propcard' && item.wrap.datatype === 'static') return |
| | | |
| | | if (item.setting) { |
| | | if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) { |
| | | error = `组件《${item.name}》未设置数据源!` |
| | | } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) { |
| | | error = `组件《${item.name}》未设置数据源!` |
| | | } else if (item.setting.interType && !item.setting.primaryKey) { |
| | | error = `组件《${item.name}》未设置主键!` |
| | | } |
| | | } |
| | | if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') { |
| | | if (!item.plot.Xaxis) { |
| | | error = `组件《${item.name}》图表字段尚未设置!` |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (show && error) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: error, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | |
| | | return error |
| | | } |
| | | |
| | | // 更新配置信息 |
| | | updateConfig = (config) => { |
| | | this.setState({ |
| | | config: config |
| | | }) |
| | | |
| | | this.props.modifyCustomMenu(config) |
| | | } |
| | | |
| | | /** |
| | | * @description 更新常用表信息,快捷添加后更新配置信息 |
| | | */ |
| | | updatetable = (config, fields) => { |
| | | const { tableFields } = this.state |
| | | |
| | | config.tableFields = fields ? fields : tableFields |
| | | |
| | | this.setState({ |
| | | tableFields: fields ? fields : tableFields, |
| | | config |
| | | }) |
| | | |
| | | this.props.modifyCustomMenu(config) |
| | | } |
| | | |
| | | render () { |
| | | const { activeKey, MenuType, dict, config, menuloading } = this.state |
| | | |
| | | return ( |
| | | <div className="pc-menu-view" id="view"> |
| | | <Header /> |
| | | <DndProvider backend={HTML5Backend}> |
| | | <div className="menu-body"> |
| | | <div className="menu-setting"> |
| | | <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}> |
| | | {/* 基本信息 */} |
| | | <Panel header={dict['mob.basemsg']} key="basedata"> |
| | | {/* 表名添加 */} |
| | | {config ? <TableComponent config={config} updatetable={this.updatetable}/> : null} |
| | | </Panel> |
| | | {/* 组件添加 */} |
| | | <Panel header={dict['mob.component']} key="component"> |
| | | <SourceWrap MenuType={MenuType} /> |
| | | </Panel> |
| | | <Panel header={'背景'} key="background"> |
| | | {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null} |
| | | </Panel> |
| | | <Panel header={'内边距'} key="padding"> |
| | | {config ? <PaddingController config={config} updateConfig={this.updateConfig} /> : null} |
| | | </Panel> |
| | | </Collapse> |
| | | </div> |
| | | <div className={'menu-view ' + (menuloading ? 'saving' : '')}> |
| | | <Card title={ |
| | | <div> {config && config.MenuName} </div> |
| | | } bordered={false} extra={ |
| | | <div> |
| | | {config ? <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config.enabled} onChange={this.onEnabledChange} /> : null} |
| | | <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button> |
| | | <Button type="default" onClick={this.closeView}>{dict['mob.return']}</Button> |
| | | </div> |
| | | } style={{ width: '100%' }}> |
| | | {config && config.components ? <MenuShell menu={config} handleList={this.updateConfig} /> : null} |
| | | </Card> |
| | | </div> |
| | | </div> |
| | | </DndProvider> |
| | | <StyleController /> |
| | | <ModalController /> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | const mapDispatchToProps = (dispatch) => { |
| | | return { |
| | | modifyCustomMenu: (customMenu) => dispatch(modifyCustomMenu(customMenu)) |
| | | } |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(MenuDesign) |
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-borderless { |
| | | background-color: #ffffff; |
| | | } |
| | | .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; |
| | | min-height: 50px; |
| | | } |
| | | .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 { |
| | | position: relative; |
| | | .ant-select { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | } |
| | | .ant-calendar-picker { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | } |
| | | .ant-input-number { |
| | | width: 100%; |
| | | margin-top: 4px; |
| | | } |
| | | } |
| | | .ant-form-item-control-wrapper::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | opacity: 0; |
| | | z-index: 1; |
| | | } |
| | | .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: 5px; |
| | | top: 5px; |
| | | padding: 10px; |
| | | cursor: pointer; |
| | | } |
| | | .paste-Icon { |
| | | position: absolute; |
| | | font-size: 16px; |
| | | right: 15px; |
| | | top: 65px; |
| | | } |
| | | } |
| | | } |
| | | .setting { |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { menuType, memberLevel, setting, fields } = this.props |
| | | let columns = fromJS(this.props.columns).toJS() |
| | | let _columns = [] |
| | | const { menuType, memberLevel, setting, fields, columns } = this.props |
| | | let radio = 5 // 虚化比例 |
| | | let _format = false // 是否虚化处理 |
| | | let rowspans = [] |
| | |
| | | } |
| | | } |
| | | |
| | | columns.forEach(item => { |
| | | if (item.hidden === true || item.Hide === 'true') return |
| | | let getColumns = (cols) => { |
| | | return cols.map(item => { |
| | | let cell = null |
| | | |
| | | if (item.type === 'colspan') { |
| | | cell = {title: item.label, children: []} |
| | | |
| | | item.subcols.forEach(col => { |
| | | if (col.rowspan === 'true') { |
| | | rowspans.push(col.field) |
| | | } |
| | | if (_format && !Math.floor(Math.random() * radio)) { |
| | | col.blur = true |
| | | } |
| | | |
| | | if (col.marks && col.marks.length === 0) { |
| | | col.marks = '' |
| | | } |
| | | |
| | | cell.children.push({ |
| | | align: col.Align, |
| | | title: col.label, |
| | | dataIndex: col.field || col.uuid, |
| | | key: col.uuid, |
| | | width: col.Width || 120, |
| | | onCell: record => ({ |
| | | record, |
| | | col, |
| | | config: col.type === 'custom' ? {setting, columns: fields} : null, |
| | | triggerLink: this.triggerLink, |
| | | updateStatus: this.updateStatus |
| | | }) |
| | | }) |
| | | }) |
| | | cell = { title: item.label, align: item.Align } |
| | | cell.children = getColumns(item.subcols) |
| | | } else { |
| | | if (item.rowspan === 'true') { |
| | | rowspans.push(item.field) |
| | |
| | | |
| | | cell = { |
| | | align: item.Align, |
| | | dataIndex: item.field || item.uuid, |
| | | dataIndex: item.uuid, |
| | | title: item.label, |
| | | sorter: item.field && item.IsSort === 'true', |
| | | width: item.Width || 120, |
| | |
| | | } |
| | | } |
| | | |
| | | _columns.push(cell) |
| | | return cell |
| | | }) |
| | | } |
| | | |
| | | let _columns = getColumns(columns) |
| | | |
| | | if (rowspans.length === 0) { |
| | | rowspans = null |
| | |
| | | }) |
| | | } |
| | | if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.cols = item.cols.map(col => { |
| | | if (!col.blacklist || col.blacklist.length === 0) return col |
| | | if (col.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | col.Hide = 'true' |
| | | } |
| | | |
| | | if (col.Hide !== 'true' && col.linkmenu && col.linkmenu.length > 0) { |
| | | let menu_id = col.linkmenu.slice(-1)[0] |
| | | col.linkThdMenu = permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } else { |
| | | col.linkThdMenu = '' |
| | | } |
| | | |
| | | return col |
| | | }) |
| | | item.cols = this.getCols(item.cols, roleId, permMenus) |
| | | } |
| | | |
| | | // 权限过滤 |
| | |
| | | }) |
| | | }) |
| | | } else if (item.type === 'table' && item.subtype === 'normaltable') { |
| | | item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | item.cols = item.cols.filter(col => { |
| | | if (col.type !== 'action') return true |
| | | col.elements = col.elements.filter(cell => { |
| | | cell.logLabel = item.name + '-' + cell.label |
| | | cell.Ot = 'requiredSgl' |
| | | return permAction[cell.uuid] |
| | | }) |
| | | return col.elements.length !== 0 |
| | | }) |
| | | } |
| | | } else { |
| | |
| | | }) |
| | | } |
| | | |
| | | getCols = (cols, roleId, permMenus) => { |
| | | return cols.filter(col => { |
| | | if (col.blacklist && col.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) { |
| | | return false |
| | | } else if (col.Hide === 'true') { |
| | | return false |
| | | } |
| | | if (col.type === 'colspan') { |
| | | col.subcols = this.getCols(col.subcols || [], roleId, permMenus) |
| | | if (col.subcols.length === 0) { |
| | | return false |
| | | } |
| | | } |
| | | |
| | | if (col.linkmenu && col.linkmenu.length > 0) { |
| | | let menu_id = col.linkmenu.slice(-1)[0] |
| | | col.linkThdMenu = permMenus.filter(m => m.MenuID === menu_id)[0] || '' |
| | | } else { |
| | | col.linkThdMenu = '' |
| | | } |
| | | |
| | | return true |
| | | }) |
| | | } |
| | | |
| | | // 格式化默认设置 |
| | | formatSetting = (components, params, mainSearch, inherit) => { |
| | | return components.map(component => { |
| | |
| | | }) |
| | | } |
| | | |
| | | getFuncNames = (data, funcNames, tableNames) => { |
| | | data.forEach(item => { |
| | | // if (item.subfuncs) { |
| | | // this.getFuncNames(item.subfuncs, funcNames, tableNames) |
| | | // return |
| | | // } |
| | | getFuncNames = (data) => { |
| | | let funcNames = [] |
| | | let tableNames = [] |
| | | |
| | | data.forEach(item => { |
| | | if (item.tableName) { |
| | | tableNames.push(item.tableName) |
| | | } |
| | |
| | | funcNames.push({func: item.callbackFunc, label: item.label || ''}) |
| | | } |
| | | }) |
| | | |
| | | tableNames = Array.from(new Set(tableNames)) |
| | | |
| | | return { |
| | | func: funcNames, |
| | |
| | | }) |
| | | } |
| | | |
| | | new Promise(resolve => { |
| | | // let deffers = [] |
| | | // _config.funcs.forEach(item => { |
| | | // if (item.type === 'tab') { |
| | | // let deffer = new Promise(resolve => { |
| | | // Api.getSystemConfig({ |
| | | // func: 'sPC_Get_LongParam', |
| | | // MenuID: item.linkTab |
| | | // }).then(result => { |
| | | // if (result.status && result.LongParam) { |
| | | // let _LongParam = '' |
| | | |
| | | // if (result.LongParam) { |
| | | // try { |
| | | // _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) |
| | | // } catch (e) { |
| | | // console.warn('Parse Failure') |
| | | // _LongParam = '' |
| | | // } |
| | | // } |
| | | |
| | | // if (_LongParam) { |
| | | // item.menuNo = _LongParam.tabNo || '' |
| | | // item.subfuncs = _LongParam.funcs || [] |
| | | // } |
| | | // } |
| | | // resolve() |
| | | // }) |
| | | // }) |
| | | |
| | | // deffers.push(deffer) |
| | | // } |
| | | // }) |
| | | |
| | | // if (deffers.length === 0) { |
| | | // resolve() |
| | | // } else { |
| | | // Promise.all(deffers).then(() => { |
| | | // resolve() |
| | | // }) |
| | | // } |
| | | resolve() |
| | | }).then(() => { |
| | | // 保存时删除配置类型,system 、user |
| | | delete _config.type |
| | | delete _config.isAdd |
| | |
| | | tabParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | tabParam.secretkey = Utils.encrypt(tabParam.LText, tabParam.timestamp) |
| | | |
| | | let _vals = this.getFuncNames(_config.funcs, [], []) |
| | | let _tables = Array.from(new Set(_vals.table)) |
| | | let _vals = this.getFuncNames(_config.funcs) |
| | | |
| | | let param = { |
| | | func: 'sPC_TrdMenu_AddUpt', |
| | |
| | | PageParam: JSON.stringify({...menu.PageParam, Template: _config.Template, OpenType: _config.OpenType}), |
| | | LongParam: _LongParam, |
| | | LText: _vals.func.map(item => `select '${menu.MenuID}' as MenuID,'${item.func}' as ProcName,'${item.label}' as MenuName`), |
| | | LTexttb: _tables.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as tbName`) |
| | | LTexttb: _vals.table.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as tbName`) |
| | | } |
| | | |
| | | if (menu.menuSort) { // 菜单新建时设置排序 |
| | |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | }) |
| | | } |
| | |
| | | _config.enabled = false |
| | | } |
| | | |
| | | // _config.funcs = [] |
| | | |
| | | // _config.funcs.push({ |
| | | // type: 'view', |
| | | // subtype: 'view', |
| | | // uuid: _config.uuid, |
| | | // intertype: _config.setting.interType || 'system', |
| | | // interface: _config.setting.interface || '', |
| | | // tableName: _config.setting.tableName || '', |
| | | // innerFunc: _config.setting.innerFunc || '', |
| | | // outerFunc: _config.setting.outerFunc || '' |
| | | // }) |
| | | |
| | | // _config.action.forEach(item => { |
| | | // let tablename = item.OpenType === 'excelIn' ? (item.sheet || '') : (item.sql || '') |
| | | |
| | | // if (item.OpenType === 'excelOut' && item.intertype === 'system') { |
| | | // tablename = _config.setting.tableName || '' |
| | | // } |
| | | |
| | | // if (item.OpenType === 'popview') { |
| | | // _config.funcs.push({ |
| | | // type: 'tab', |
| | | // subtype: 'btn', |
| | | // uuid: item.uuid, |
| | | // label: item.label, |
| | | // linkTab: item.linkTab |
| | | // }) |
| | | // } else { |
| | | // _config.funcs.push({ |
| | | // type: 'button', |
| | | // subtype: 'btn', |
| | | // uuid: item.uuid, |
| | | // label: item.label, |
| | | // tableName: tablename, |
| | | // intertype: item.intertype, |
| | | // interface: item.interface || '', |
| | | // innerFunc: item.innerFunc || '', |
| | | // outerFunc: item.outerFunc || '', |
| | | // callbackFunc: item.callbackFunc || '' |
| | | // }) |
| | | // } |
| | | // }) |
| | | |
| | | if (this.state.closeVisible) { // 显示关闭对话框时,模态框中保存按钮,显示保存中状态 |
| | | this.setState({ |
| | | menucloseloading: true |
| | |
| | | }) |
| | | } |
| | | |
| | | new Promise(resolve => { |
| | | // let deffers = [] |
| | | // _config.funcs.forEach(item => { |
| | | // if (item.type === 'tab') { |
| | | // let deffer = new Promise(resolve => { |
| | | // Api.getSystemConfig({ |
| | | // func: 'sPC_Get_LongParam', |
| | | // MenuID: item.linkTab |
| | | // }).then(result => { |
| | | // if (result.status && result.LongParam) { |
| | | // let _LongParam = '' |
| | | |
| | | // if (result.LongParam) { |
| | | // try { |
| | | // _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) |
| | | // } catch (e) { |
| | | // console.warn('Parse Failure') |
| | | // _LongParam = '' |
| | | // } |
| | | // } |
| | | |
| | | // if (_LongParam) { |
| | | // item.menuNo = _LongParam.tabNo |
| | | // item.subfuncs = _LongParam.funcs || [] |
| | | // } |
| | | // } |
| | | // resolve() |
| | | // }) |
| | | // }) |
| | | |
| | | // deffers.push(deffer) |
| | | // } |
| | | // }) |
| | | |
| | | // if (deffers.length === 0) { |
| | | // resolve() |
| | | // } else { |
| | | // Promise.all(deffers).then(() => { |
| | | // resolve() |
| | | // }) |
| | | // } |
| | | resolve() |
| | | }).then(() => { |
| | | // 保存时删除配置类型,system 、user |
| | | delete _config.type |
| | | delete _config.isAdd |
| | |
| | | } |
| | | }) |
| | | }) |
| | | }) |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | import enUS from '@/locales/en-US/mob.js' |
| | | import antdEnUS from 'antd/es/locale/en_US' |
| | | import antdZhCN from 'antd/es/locale/zh_CN' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import { modifyCustomMenu } from '@/store/action' |
| | | |
| | |
| | | const PaddingController = asyncComponent(() => import('@/menu/padcontroller')) |
| | | const StyleController = asyncComponent(() => import('@/menu/stylecontroller')) |
| | | const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller')) |
| | | const PopviewController = asyncComponent(() => import('@/menu/popview/controller')) |
| | | const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent')) |
| | | |
| | | sessionStorage.setItem('isEditState', 'true') |
| | | sessionStorage.setItem('delButtons', JSON.stringify([])) |
| | | |
| | | class MenuDesign extends Component { |
| | | state = { |
| | |
| | | MenuName: '', |
| | | MenuNo: '', |
| | | tableFields: [], |
| | | delButtons: [], |
| | | activeKey: 'basedata', |
| | | menuloading: false, |
| | | oriConfig: null, |
| | |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('delButtons', this.delButtons) |
| | | } |
| | | |
| | | /** |
| | | * @description 组件销毁,清除state更新 |
| | | */ |
| | |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('delButtons', this.delButtons) |
| | | } |
| | | |
| | | delButtons = (items) => { |
| | | this.setState({delButtons: [...this.state.delButtons, ...items]}) |
| | | } |
| | | |
| | | closeView = () => { |
| | |
| | | backgroundColor: '#ffffff', backgroundImage: '', |
| | | paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px' |
| | | }, |
| | | MenuType: MenuType |
| | | } |
| | | if (MenuType === 'billPrint') { |
| | | config.style.paddingTop = '50px' |
| | |
| | | } else { |
| | | config.uuid = MenuId |
| | | config.MenuID = MenuId |
| | | config.MenuType = config.MenuType || MenuType |
| | | } |
| | | |
| | | if (MenuType === 'billPrint') { |
| | |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { openEdition } = this.state |
| | | const { openEdition, MenuType, delButtons } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if (config.MenuType === 'billPrint' && (!config.firstCount || !config.everyPCount)) { |
| | | if (MenuType === 'billPrint' && (!config.firstCount || !config.everyPCount)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善基本信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (config.MenuType === 'home' && (config.cacheUseful === 'true' && !config.cacheTime)) { |
| | | } else if (MenuType === 'home' && (config.cacheUseful === 'true' && !config.cacheTime)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善菜单基本信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (config.MenuType === 'custom' && (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId || (config.cacheUseful === 'true' && !config.cacheTime))) { |
| | | } else if (MenuType === 'custom' && (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId || (config.cacheUseful === 'true' && !config.cacheTime))) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请完善菜单基本信息!', |
| | |
| | | LText: [] |
| | | } |
| | | |
| | | if (config.MenuType !== 'billPrint') { |
| | | if (MenuType !== 'billPrint') { |
| | | btnParam.LText = this.getMenuMessage() |
| | | btnParam.LText = btnParam.LText.join(' union all ') |
| | | btnParam.LText = Utils.formatOptions(btnParam.LText) |
| | |
| | | menuloading: true |
| | | }, () => { |
| | | new Promise(resolve => { |
| | | if (config.MenuType === 'billPrint') { |
| | | if (MenuType === 'billPrint') { |
| | | html2canvas(document.getElementById('menu-shell-inner')).then(canvas => { |
| | | let img = canvas.toDataURL('image/png') // 获取生成的图片 |
| | | Api.fileuploadbase64(img, 'cloud').then(result => { |
| | |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | if (delButtons.length === 0) { |
| | | return { |
| | | status: true |
| | | } |
| | | } else { |
| | | let _param = { |
| | | func: 'sPC_MainMenu_Del', |
| | | MenuID: delButtons.join(',') |
| | | } |
| | | return Api.getSystemConfig(_param) |
| | | } |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | | if (res.status) { |
| | | this.setState({ |
| | | delButtons: [] |
| | | }) |
| | | return Api.getSystemConfig(param) |
| | | } else { |
| | | this.setState({ |
| | | menuloading: false |
| | | }) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | return false |
| | | } |
| | | }).then(res => { |
| | | if (!res) return |
| | | |
| | |
| | | } |
| | | |
| | | verifyConfig = (show) => { |
| | | const { config } = this.state |
| | | const { config, MenuType } = this.state |
| | | let error = '' |
| | | |
| | | config.components.forEach(item => { |
| | |
| | | error = `组件《${item.name}》未设置数据源!` |
| | | } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) { |
| | | error = `组件《${item.name}》未设置数据源!` |
| | | } else if (item.setting.interType && !item.setting.primaryKey && config.MenuType !== 'billPrint') { |
| | | } else if (item.setting.interType && !item.setting.primaryKey && MenuType !== 'billPrint') { |
| | | error = `组件《${item.name}》未设置主键!` |
| | | } |
| | | } |
| | |
| | | </DndProvider> |
| | | <StyleController /> |
| | | <ModalController /> |
| | | <PopviewController /> |
| | | </div> |
| | | </ConfigProvider> |
| | | ) |