king
2020-12-23 e9640ccdc9fe57f91919e3f51462c780e44fadb0
2020-12-23
33个文件已修改
3个文件已添加
1539 ■■■■ 已修改文件
src/menu/components/card/cardcellcomponent/dragaction/action.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/card.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/settingform/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/wrapsetting/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/wrapsetting/settingform/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/chartcompile/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/dragsearch/card.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/dragaction/card.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/searchcomponent/dragsearch/card.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/wrapsetting/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/settingform/index.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/controller.jsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/index.jsx 523 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/index.scss 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/action.jsx
@@ -3,7 +3,7 @@
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 },
@@ -15,13 +15,13 @@
    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)
      }
    },
  })
src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -17,7 +17,7 @@
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 },
@@ -29,13 +29,13 @@
    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)
      }
    },
  })
src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -87,8 +87,6 @@
    deleteMenu(card)
  }
  let cardIds = cards.map(card => card.uuid)
  const [, drop] = useDrop({
    accept: 'action',
    drop(item) {
@@ -106,7 +104,6 @@
            <Action
              id={card.uuid}
              key={card.uuid}
              cardIds={cardIds}
              card={card}
              moveCard={moveCard}
              editCard={editCard}
@@ -122,7 +119,6 @@
            <Card
              id={card.uuid}
              key={card.uuid}
              cardIds={cardIds}
              card={card}
              fields={fields}
              moveCard={moveCard}
src/menu/components/card/cardcellcomponent/index.jsx
@@ -467,6 +467,10 @@
      onOk() {
        let _elements = elements.filter(item => item.uuid !== card.uuid)
        if (card.eleType === 'button') {
          MKEmitter.emit('delButtons', [card.uuid])
        }
        _this.setState({
          elements: _elements
        }, () => {
src/menu/components/card/cardcomponent/index.jsx
@@ -17,7 +17,6 @@
class CardBoxComponent extends Component {
  static propTpyes = {
    offset: PropTypes.any,           // 偏移量
    MenuType: PropTypes.any,         // 菜单类型
    cards: PropTypes.object,         // 卡片行配置信息
    card: PropTypes.object,          // 卡片配置信息
    deleteElement: PropTypes.func,   // 卡片删除
@@ -51,9 +50,9 @@
  }
  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))
  }
  /**
@@ -205,7 +204,7 @@
  }
  render() {
    const { cards, MenuType, offset } = this.props
    const { cards, offset } = this.props
    const { card, elements, side, settingVisible, dict } = this.state
    let _style = {...card.style}
@@ -226,11 +225,11 @@
            <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" />
@@ -251,7 +250,6 @@
          <SettingForm
            dict={dict}
            cards={cards}
            MenuType={MenuType}
            setting={card.setting}
            inputSubmit={this.settingSubmit}
            wrappedComponentRef={(inst) => this.settingRef = inst}
src/menu/components/card/cardcomponent/settingform/index.jsx
@@ -6,7 +6,6 @@
class SettingForm extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,     // 菜单类型
    dict: PropTypes.object,      // 字典项
    cards: PropTypes.object,     // 卡片集
    setting: PropTypes.object,   // 数据源配置
@@ -39,7 +38,7 @@
  }
  render() {
    const { setting, cards, MenuType } = this.props
    const { setting, cards } = this.props
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
@@ -75,7 +74,7 @@
                })(<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" />
@@ -91,8 +90,8 @@
                  </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" />
src/menu/components/card/data-card/index.jsx
@@ -89,6 +89,7 @@
        columns: [],
        scripts: [],
        action: [],
        btnlog: [],
        subcards: subcards
      }
      this.setState({
@@ -287,7 +288,6 @@
  }
  render() {
    const { menu } = this.props
    const { card } = this.state
    let offset = 0
@@ -307,9 +307,9 @@
        <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} />
@@ -318,7 +318,7 @@
          <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>
src/menu/components/card/data-card/wrapsetting/index.jsx
@@ -11,7 +11,6 @@
class DataSource extends Component {
  static propTpyes = {
    config: PropTypes.any,
    MenuType: PropTypes.any,
    updateConfig: PropTypes.func
  }
@@ -51,7 +50,7 @@
  }
  render () {
    const { config, MenuType } = this.props
    const { config } = this.props
    const { visible, dict, wrap } = this.state
    return (
@@ -72,7 +71,6 @@
            dict={dict}
            wrap={wrap}
            config={config}
            MenuType={MenuType}
            inputSubmit={this.verifySubmit}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
          />
src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
@@ -6,7 +6,6 @@
class SettingForm extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,     // 菜单类型
    dict: PropTypes.object,      // 字典项
    config: PropTypes.object,    // 卡片行信息
    wrap: PropTypes.object,      // 数据源配置
@@ -54,7 +53,7 @@
  }
  render() {
    const { wrap, config, MenuType } = this.props
    const { wrap, config } = this.props
    const { getFieldDecorator } = this.props.form
    const { roleList } = this.state
@@ -133,7 +132,7 @@
                )}
              </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" />
@@ -150,7 +149,7 @@
                )}
              </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 || ''
@@ -222,7 +221,7 @@
                })(<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" />
@@ -239,7 +238,7 @@
                )}
              </Form.Item>
            </Col> : null}
            {MenuType !== 'billPrint' ? <Col span={12}>
            <Col span={12}>
              <Form.Item label="黑名单">
                {getFieldDecorator('blacklist', {
                  initialValue: wrap.blacklist || []
@@ -255,7 +254,7 @@
                  </Select>
                )}
              </Form.Item>
            </Col> : null}
            </Col>
          </Row>
        </Form>
      </div>
src/menu/components/card/prop-card/index.jsx
@@ -88,6 +88,7 @@
        columns: [],
        scripts: [],
        subcards: subcards,
        btnlog: [],
      }
      this.setState({
        card: _card
src/menu/components/card/table-card/index.jsx
@@ -80,7 +80,8 @@
        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
        columns: [],
        scripts: [],
        subcards: subcards
        subcards: subcards,
        btnlog: [],
      }
      
      this.setState({
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -6,9 +6,8 @@
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
 * @param {Array}  MenuType   // 菜单类型
 */
export function getBaseForm (card, MenuType) {
export function getBaseForm (card) {
  let menulist = sessionStorage.getItem('fstMenuList')
  if (menulist) {
    try {
@@ -75,7 +74,6 @@
      initVal: card.blacklist || [],
      multi: true,
      required: false,
      forbid: MenuType === 'billPrint',
      options: roleList
    },
    {
@@ -85,7 +83,6 @@
      initVal: card.linkmenu || [],
      tooltip: '在使用柱形图且未启用自定义设置时有效。',
      required: false,
      forbid: MenuType === 'billPrint',
      options: menulist
    }
  ]
@@ -96,7 +93,7 @@
 * @param {object} card       // 图表对象
 * @param {Array}  columns    // 显示列
 */
export function getOptionForm (card, columns, MenuType) {
export function getOptionForm (card, columns) {
  let shapes = []
  if (card.chartType === 'line') {
src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -16,7 +16,6 @@
class LineChartDrawerForm extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
@@ -147,7 +146,7 @@
  }
  showDrawer = () => {
    const { config, MenuType } = this.props
    const { config } = this.props
    let fieldName = {}
    config.columns.forEach(col => {
@@ -167,8 +166,8 @@
      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)
    })
  }
src/menu/components/chart/antv-bar/index.jsx
@@ -84,7 +84,8 @@
        scripts: [],
        search: [],
        action: [],
        plot: _plot
        plot: _plot,
        btnlog: [],
      }
      this.setState({
        card: _card
@@ -823,7 +824,6 @@
  }
  render() {
    const { menu } = this.props
    const { card } = this.state
    return (
@@ -831,9 +831,9 @@
        <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}/>
@@ -841,11 +841,11 @@
        } 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>
    )
src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -6,9 +6,8 @@
/**
 * @description 获取图表视图配置表单
 * @param {object} card       // 图表对象
 * @param {Array}  MenuType   // 菜单类型
 */
export function getBaseForm (card, MenuType) {
export function getBaseForm (card) {
  let menulist = sessionStorage.getItem('fstMenuList')
  if (menulist) {
    try {
@@ -75,7 +74,6 @@
      initVal: card.blacklist || [],
      multi: true,
      required: false,
      forbid: MenuType === 'billPrint',
      options: roleList
    },
    {
@@ -85,7 +83,6 @@
      initVal: card.linkmenu || [],
      tooltip: '双击饼图,会打开关联的菜单。',
      required: false,
      forbid: MenuType === 'billPrint',
      options: menulist
    }
  ]
src/menu/components/chart/antv-pie/chartcompile/index.jsx
@@ -16,7 +16,6 @@
class LineChartDrawerForm extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
@@ -51,13 +50,13 @@
  }
  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)
    })
  }
src/menu/components/chart/antv-pie/index.jsx
@@ -71,7 +71,8 @@
        scripts: [],
        search: [],
        action: [],
        plot: _plot
        plot: _plot,
        btnlog: [],
      }
      this.props.updateConfig(_card)
      this.setState({
@@ -395,7 +396,6 @@
  }
  render() {
    const { menu } = this.props
    const { card } = this.state
    return (
@@ -403,8 +403,8 @@
        <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}/>
src/menu/components/search/main-search/dragsearch/card.jsx
@@ -20,14 +20,12 @@
    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
src/menu/components/share/actioncomponent/dragaction/card.jsx
@@ -14,11 +14,10 @@
  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)
src/menu/components/share/actioncomponent/index.jsx
@@ -323,14 +323,9 @@
        _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
src/menu/components/share/searchcomponent/dragsearch/card.jsx
@@ -23,7 +23,6 @@
      if (!draggedId || draggedId === id) return
      const { index: originIndex } = findCard(draggedId)
      if (originIndex === -1) return
      const { index: overIndex } = findCard(id)
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -38,13 +38,13 @@
  }, {
    value: 'custom',
    text: '自定义列'
  }, {
    value: 'colspan',
    text: '合并列'
  }]
  if (!card.isSub) {
    options.push({
      value: 'colspan',
      text: '合并列'
    }, {
      value: 'action',
      text: '操作'
    })
@@ -126,6 +126,7 @@
      label: Formdict['model.sort'],
      initVal: card.IsSort || 'true',
      required: true,
      forbidden: card.isSub,
      options: [{
        value: 'true',
        text: Formdict['model.true']
src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -107,6 +107,13 @@
      })
    } 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: '%'})
    }
@@ -140,7 +147,7 @@
    if (!formlist) return null
    formlist.forEach((item, index) => {
      if (item.hidden) return
      if (item.hidden || item.forbidden) return
      if (item.type === 'text') { // 文本搜索
        let rules = []
@@ -213,7 +220,7 @@
                  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>
                  )}
src/menu/components/table/normal-table/columns/index.jsx
@@ -41,7 +41,9 @@
    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() {
@@ -66,10 +68,10 @@
      )
    } 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)} />
@@ -153,7 +155,7 @@
      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 {
@@ -175,6 +177,7 @@
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    data: [{uuid: Utils.getuuid()}],
    refresh: false,    // 强制刷新
    columns: [],
    fields: [],
    lineMarks: []
@@ -225,29 +228,21 @@
    })
  }
  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,
@@ -333,20 +328,18 @@
    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
@@ -387,6 +380,35 @@
    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
@@ -399,51 +421,7 @@
      }
    }
    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}`}>
@@ -454,12 +432,12 @@
        <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,
src/menu/components/table/normal-table/index.jsx
@@ -73,7 +73,8 @@
          { 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({
@@ -266,7 +267,6 @@
  }
  render() {
    const { menu } = this.props
    const { card } = this.state
    return (
@@ -275,9 +275,9 @@
        <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} />
src/menu/components/table/normal-table/wrapsetting/index.jsx
@@ -11,7 +11,6 @@
class DataSource extends Component {
  static propTpyes = {
    config: PropTypes.any,
    MenuType: PropTypes.any,
    updateConfig: PropTypes.func
  }
@@ -51,7 +50,7 @@
  }
  render () {
    const { config, MenuType } = this.props
    const { config } = this.props
    const { visible, dict, wrap } = this.state
    return (
@@ -72,7 +71,6 @@
            dict={dict}
            wrap={wrap}
            config={config}
            MenuType={MenuType}
            inputSubmit={this.verifySubmit}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
          />
src/menu/components/table/normal-table/wrapsetting/settingform/index.jsx
@@ -6,7 +6,6 @@
class SettingForm extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,     // 菜单类型
    dict: PropTypes.object,      // 字典项
    config: PropTypes.object,    // 卡片行信息
    wrap: PropTypes.object,      // 数据源配置
@@ -54,7 +53,7 @@
  }
  render() {
    const { wrap, MenuType, config } = this.props
    const { wrap, config } = this.props
    const { getFieldDecorator } = this.props.form
    const { roleList } = this.state
@@ -159,7 +158,7 @@
                )}
              </Form.Item>
            </Col>
            {MenuType !== 'billPrint' ? <Col span={12}>
            <Col span={12}>
              <Form.Item label="黑名单">
                {getFieldDecorator('blacklist', {
                  initialValue: wrap.blacklist || []
@@ -175,7 +174,7 @@
                  </Select>
                )}
              </Form.Item>
            </Col> : null}
            </Col>
          </Row>
        </Form>
      </div>
src/menu/datasource/verifycard/settingform/index.jsx
@@ -190,7 +190,7 @@
  }
  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
@@ -386,7 +386,7 @@
                </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" />
@@ -405,8 +405,8 @@
                  <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'
@@ -418,7 +418,7 @@
                )}
              </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" />
@@ -436,8 +436,8 @@
                })(<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" />
@@ -454,7 +454,7 @@
                )}
              </Form.Item>
            </Col> : null}
            {menu.MenuType !== 'billPrint' ? <Col span={8}>
            <Col span={8}>
              <Form.Item label={
                <Tooltip placement="topLeft" title={'优先使用同级的搜索条件组件,同级搜索不存在时,依次向上选取,与当前组件的搜索条件一同用作数据过滤(当前组件的搜索条件优先)。'}>
                  <Icon type="question-circle" />
@@ -470,8 +470,8 @@
                  </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" />
@@ -488,7 +488,7 @@
                )}
              </Form.Item>
            </Col> : null}
            {menu.MenuType !== 'billPrint' ? <Col span={8}>
            <Col span={8}>
              <Form.Item label="初始化数据">
                {getFieldDecorator('onload', {
                  initialValue: setting.onload || 'true'
@@ -499,7 +499,7 @@
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            </Col>
          </Row>
        </Form>
      </div>
src/menu/popview/controller.jsx
New file
@@ -0,0 +1,70 @@
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
src/menu/popview/index.jsx
New file
@@ -0,0 +1,523 @@
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)
src/menu/popview/index.scss
New file
@@ -0,0 +1,303 @@
.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);
    }
  }
}
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -391,9 +391,7 @@
  }
  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 = []
@@ -408,40 +406,13 @@
      }
    }
    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)
@@ -456,7 +427,7 @@
        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,
@@ -470,8 +441,11 @@
        }
      }
      _columns.push(cell)
        return cell
    })
    }
    let _columns = getColumns(columns)
    if (rowspans.length === 0) {
      rowspans = null
src/tabviews/custom/index.jsx
@@ -234,21 +234,7 @@
        })
      }
      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)
      }
      // 权限过滤
@@ -301,13 +287,14 @@
            })
          })
        } 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 {
@@ -338,6 +325,31 @@
    })
  }
  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 => {
src/templates/comtableconfig/index.jsx
@@ -202,13 +202,11 @@
    })
  }
  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)
      }
@@ -220,6 +218,8 @@
        funcNames.push({func: item.callbackFunc, label: item.label || ''})
      }
    })
    tableNames = Array.from(new Set(tableNames))
    return {
      func: funcNames,
@@ -354,49 +354,6 @@
      })
    }
    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
@@ -479,8 +436,7 @@
      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',
@@ -495,7 +451,7 @@
        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) { // 菜单新建时设置排序
@@ -644,7 +600,6 @@
              duration: 5
            })
          }
        })
      })
    })
  }
src/templates/subtableconfig/index.jsx
@@ -275,50 +275,6 @@
      _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
@@ -329,49 +285,6 @@
      })
    }
    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
@@ -572,8 +485,6 @@
          }
        })
      })
    })
  }
  /**
src/views/menudesign/index.jsx
@@ -13,6 +13,7 @@
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'
@@ -32,10 +33,10 @@
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 = {
@@ -46,6 +47,7 @@
    MenuName: '',
    MenuNo: '',
    tableFields: [],
    delButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
@@ -79,6 +81,10 @@
    return !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('delButtons', this.delButtons)
  }
  /**
   * @description 组件销毁,清除state更新
   */
@@ -86,6 +92,11 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('delButtons', this.delButtons)
  }
  delButtons = (items) => {
    this.setState({delButtons: [...this.state.delButtons, ...items]})
  }
  closeView = () => {
@@ -149,7 +160,6 @@
              backgroundColor: '#ffffff', backgroundImage: '',
              paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px'
            },
            MenuType: MenuType
          }
          if (MenuType === 'billPrint') {
            config.style.paddingTop = '50px'
@@ -160,7 +170,6 @@
        } else {
          config.uuid = MenuId
          config.MenuID = MenuId
          config.MenuType = config.MenuType || MenuType
        }
        if (MenuType === 'billPrint') {
@@ -263,24 +272,24 @@
  }
  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: '请完善菜单基本信息!',
@@ -333,7 +342,7 @@
      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)
@@ -347,7 +356,7 @@
      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 => {
@@ -392,7 +401,36 @@
      }).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
@@ -495,7 +533,7 @@
  }
  verifyConfig = (show) => {
    const { config } = this.state
    const { config, MenuType } = this.state
    let error = ''
    config.components.forEach(item => {
@@ -507,7 +545,7 @@
          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}》未设置主键!`
        }
      }
@@ -619,6 +657,7 @@
          </DndProvider>
          <StyleController />
          <ModalController />
          <PopviewController />
        </div>
      </ConfigProvider>
    )