king
2022-12-30 6afb82b92c7de7a3d5551e721b4c8de39bd7de9d
src/mob/mobshell/index.jsx
@@ -1,26 +1,25 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import { message } from 'antd'
import { Empty, notification, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import Card from './card'
import './index.scss'
const Container = ({config, handleList, handleMenu, deleteMenu, doubleClickCard }) => {
  let target = null
const { confirm } = Modal
  const [cards, setCards] = useState(config.components)
const Container = ({menu, handleList }) => {
  const [cards, setCards] = useState(menu.components)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    handleList({...config, components: _cards})
    console.log(_cards)
    handleList({...menu, components: _cards})
    setCards(_cards)
  }
  if (!is(fromJS(cards), fromJS(config.components))) {
    setCards(config.components)
  if (menu.components.length > cards.length) {
    setCards(menu.components)
  }
  
  const findCard = id => {
@@ -31,78 +30,206 @@
    }
  }
  // const doubleClickBtn = id => {
  //   const { card } = findCard(id)
  //   doubleClickCard(card)
  // }
  const updateConfig = (element) => {
    const _cards = cards.map(item => item.uuid === element.uuid ? element : item)
    handleList({...menu, components: _cards})
    setCards(_cards)
  }
  // const editCard = id => {
  //   const { card } = findCard(id)
  //   handleMenu(card)
  // }
  const deleteCard = (id) => {
    const { card } = findCard(id)
  // const delCard = id => {
  //   const { card } = findCard(id)
  //   deleteMenu(card)
  // }
    let hasComponent = false
    if (card.type === 'tabs') {
      card.subtabs.forEach(tab => {
        if (tab.components.length > 0) {
          hasComponent = true
        }
      })
    }
  const hasDrop = (item) => {
    target = item
    confirm({
      title: `确定删除${card.name ? `《${card.name}》` : '组件'}吗?`,
      content: hasComponent ? '当前组件中含有子组件!' : '',
      onOk() {
        const _cards = cards.filter(item => item.uuid !== card.uuid)
        handleList({...menu, components: _cards})
        setCards(_cards)
      },
      onCancel() {}
    })
  }
  const [, drop] = useDrop({
    accept: 'mob',
    accept: 'menu',
    drop(item) {
      if (item.hasOwnProperty('originalIndex')) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        delete item.added // 删除组件添加标记
        return
      }
      if (cards.length > 0 && cards[0].type === 'login') {
        message.warning('登录页不可添加其他元素!')
        return
      let style = null
      if (item.component === 'search') { // 搜索组件不可重复添加
        if (cards.filter(card => card.type === 'topbar' && card.wrap.type !== 'navbar').length > 0) {
          notification.warning({
            top: 92,
            message: '导航栏使用了搜索,不可添加搜索组件!',
            duration: 5
          })
          return
        }
        if (cards.filter(card => card.type === 'search').length > 0) {
          notification.warning({
            top: 92,
            message: '搜索条件不可重复添加!',
            duration: 5
          })
          return
        }
      } else if (item.component === 'navbar') {
        if (cards.filter(card => card.type === 'navbar').length > 0) {
          notification.warning({
            top: 92,
            message: '菜单栏不可重复添加!',
            duration: 5
          })
          return
        }
        if (!menu.style.paddingBottom) {
          style = {...menu.style, paddingBottom: '50px'}
        }
      } else if (item.component === 'topbar') {
        if (cards.filter(card => card.type === 'topbar').length > 0) {
          notification.warning({
            top: 92,
            message: '导航栏不可重复添加!',
            duration: 5
          })
          return
        }
        if (!menu.style.paddingTop) {
          style = {...menu.style, paddingTop: '50px'}
        }
      } else if (item.component === 'officialAccount') {
        if (cards.filter(card => card.type === 'officialAccount').length > 0) {
          notification.warning({
            top: 92,
            message: '关注组件不可重复添加!',
            duration: 5
          })
          return
        }
      }
      let newcard = fromJS(item.param).toJS()
      newcard.uuid = Utils.getuuid()
      let name = ''
      let names = {
        bar: '柱状图',
        line: '折线图',
        tabs: '标签组',
        pie: '饼图',
        search: '搜索',
        table: '表格',
        group: '分组',
        editor: '富文本',
        code: '自定义',
        carousel: '轮播',
        dashboard: '仪表盘',
        form: '表单',
        card: '卡片',
        navbar: '导航栏',
        menubar: '菜单栏',
        balcony: '浮动卡',
        timeline: '时间轴',
        officialAccount: '关注公众号',
        sharecode: '分享码',
        iframe: 'iframe',
        login: '登录'
      }
      let i = 1
      
      let targetId = cards.length > 0 ? cards[cards.length - 1].uuid : 0
      if (target) {
        targetId = target.uuid
      while (!name && names[item.component]) {
        let _name = names[item.component] + i
        if (menu.components.filter(com => com.name === _name).length === 0) {
          name = _name
        }
        i++
      }
      let newcard = {
        uuid: Utils.getuuid(),
        type: item.component,
        subtype: item.subtype,
        config: item.config,
        width: item.width || 24,
        name: name,
        floor: 1,   // 组件的层级
        isNew: true // 新添加标志,用于初始化
      }
      let targetId = ''
      if (item.dropTargetId) {
        targetId = item.dropTargetId
        delete item.dropTargetId
      } else if (cards.length > 0) {
        targetId = cards.slice(-1)[0].uuid
      }
      const { index: overIndex } = findCard(`${targetId}`)
      let targetIndex = overIndex
      let _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] })
      let Topbar = null
      let Navbar = null
      _cards = _cards.filter(item => {
        if (item.type === 'topbar') {
          Topbar = item
        } else if (item.type === 'navbar') {
          Navbar = item
        }
      targetIndex++
        return item.type !== 'topbar' && item.type !== 'navbar'
      })
      const _cards = update(cards, { $splice: [[targetIndex, 0, newcard]] })
      if (Topbar) {
        _cards.unshift(Topbar)
      }
      if (Navbar) {
        _cards.push(Navbar)
      }
      handleList({...config, components: _cards})
      target = null
      if (style) {
        handleList({...menu, style, components: _cards})
      } else {
        handleList({...menu, components: _cards})
      }
      setCards(_cards)
    }
  })
  let style = JSON.stringify(menu.style || {})
  style = style.replace(/@mywebsite@\//ig, window.GLOB.baseurl)
  style = JSON.parse(style)
  return (
    <div ref={drop} className="mob-shell-inner">
      {cards.map(card => (
        <Card
          id={card.uuid}
          key={card.uuid}
          card={card}
          moveCard={moveCard}
          // editCard={editCard}
          // delCard={delCard}
          findCard={findCard}
          hasDrop={hasDrop}
          // doubleClickCard={doubleClickBtn}
        />
      ))}
      {/* {cards.length === 0 ?
        <div className="common-drawarea-placeholder">
          {placeholder}
        </div> : null
      } */}
    <div ref={drop} className="mob-shell-inner" id="menu-shell-inner">
      <div className="ant-row" style={style}>
        {cards.map(card => (
          <Card
            id={card.uuid}
            key={card.uuid}
            card={card}
            moveCard={moveCard}
            delCard={deleteCard}
            findCard={findCard}
            updateConfig={updateConfig}
          />
        ))}
        {cards.length === 0 ?
          <Empty description="请添加组件" /> : null
        }
      </div>
    </div>
  )
}
export default Container