lianghuang 4 éve
szülő
commit
02502be270

+ 4 - 4
coms/EventJenga.jsx

@@ -3,8 +3,8 @@ import JengaDrag from './jenga/panel/JengaDrag'
 import JengaNav from './jenga/nav/JengaNav'
 import JengaPanel from './jenga/panel/JengaPanel'
 // import JengaAction from './jenga/panel/JengaAction'
-// import JengaServiceDebug from '../../common/serviceDebug/JengaServiceDebug'
-// import ServiceLogView from '../../common/serviceLogView/ServiceLogView'
+import JengaServiceDebug from '../../common/serviceDebug/JengaServiceDebug'
+import ServiceLogView from '../../common/serviceLogView/ServiceLogView'
 import { shallowEqualImmutable } from 'utils/utils'
 
 export default class EventJenga extends React.Component {
@@ -28,9 +28,9 @@ export default class EventJenga extends React.Component {
           curEventNodeList={this.props.curEventNodeList}
           filterBlockIdsMap={this.props.filterBlockIdsMap}
         />
-        {/* <JengaServiceDebug />
+        <JengaServiceDebug />
         <ServiceLogView />
-        <JengaAction /> */}
+        {/* <JengaAction /> */}
       </div>
     )
   }

+ 3 - 3
coms/jenga/block/BlockAction.jsx

@@ -4,7 +4,7 @@ import LazyLoad from 'react-lazyload'
 import cls from 'classnames'
 import newEventActions from 'actions/newEvent'
 import Block from './base/Block'
-import BlockChildren from './base/BlockChildren'
+// import BlockChildren from './base/BlockChildren'
 import BlockOrder from './base/BlockOrder'
 import BlockDel from './base/BlockDel'
 import BlockCite from './base/BlockCite'
@@ -166,7 +166,7 @@ export default class BlockAction extends Block {
                 eventNodeId={this.props.eventNodeId}
               />
             </div>
-            {this.state.isExpand ? (
+            {/* {this.state.isExpand ? (
               <BlockChildren
                 loops={this.getLoops()}
                 layer={this.props.layer + 1}
@@ -178,7 +178,7 @@ export default class BlockAction extends Block {
                 eventNodeId={this.props.eventNodeId}
                 visibleBlockIds={this.props.visibleBlockIds}
               />
-            ) : null}
+            ) : null} */}
           </div>
         </div>
       </LazyLoad>

+ 935 - 0
coms/jenga/block/base/action/BlockActionMethod.jsx

@@ -0,0 +1,935 @@
+import React from 'react'
+import i18n from 'i18next'
+import cls from 'classnames'
+import { Menu, Dropdown, Tooltip, Popover } from 'antd'
+import newEventActions from 'actions/newEvent'
+import newEventStores from 'stores/newEvent'
+import widgetStore from 'stores/widget'
+import {
+  nodeIsChild,
+  nodeIsService,
+  nodeIsTimerService,
+  nodeIsTransaction,
+  nodeIsNormalService,
+  nodeIsFunctionGroup,
+  nodeIsApi,
+  nodeIsDyTransaction,
+  nodeIsSql,
+  nodeIsSharedService
+} from 'stores/funcs/nodeType'
+import {
+  getEventNodeById,
+  getEventBlockByBid,
+  getActionBlockObjNode,
+  getBlockObj,
+  getBlockAciton
+} from 'stores/funcs/newEvent'
+import {
+  isAsyncDbMethod,
+  isAsyncDbCustomsMethod,
+  isAsyncMethod,
+  genParams,
+  genAsyncParams,
+  getReloadMethods,
+  isMethodAllowed,
+  getModuleInstanceNameLocale,
+  modulePropMethod,
+  isParentWidgetProps,
+  getActionMethods,
+  getTargetMethod,
+  isChangedActionValid
+} from 'stores/funcs/event/methodUtils'
+import { shallowEqualImmutable, cpJson } from 'utils/utils'
+import { isHySa } from 'utils/commons/ctrlHide'
+import { BLOCK_OP_TYPE } from 'const/const'
+import propType from 'const/propType'
+import externalPath from 'src/http/api/externalPath'
+import iconStrObj from 'src/assets/icons/iconsStr'
+import BlockActionMethodParams from './BlockActionMethodParams'
+import BlockActionReload from './BlockActionReload'
+import BlockActionDelay from './BlockActionDelay'
+
+const MenuItem = Menu.Item
+
+export default class BlockActionMethod extends React.Component {
+  constructor(props) {
+    super(props)
+    this.obj = this.getObject() // 当前选中了的对象,动作受它影响
+    this.state = {
+      methods: this.getMethods(), // 可选动作
+      actionName: this.getActionName(),
+      isMini: this.getActionIsMini(),
+      // hasParams: this.getHasParams(),
+      methodParams: this.getMethodParams(),
+      paramsVisible: this.getParamsVisible(),
+      delay: this.getDelay()
+    }
+
+    this.onEventChange = this.onEventChange.bind(this)
+
+    // reload相关
+    // this.hasDiffParams = this.hasDiffParams.bind(this)
+    // this.autoReloadSpecialAction = this.autoReloadSpecialAction.bind(this)
+    this.onReloadAction = this.onReloadAction.bind(this) // 刷新
+
+    this.onChangeDelay = this.onChangeDelay.bind(this)
+    this.genDefaultAction = this.genDefaultAction.bind(this)
+
+    // 处理选择的method相关
+    this.decorateAction = this.decorateAction.bind(this)
+    // this.combineOldAction = this.combineOldAction.bind(this)
+
+    this.onMethodSelect = this.onMethodSelect.bind(this) // action的选择
+    this.onToggleParamsVisible = this.onToggleParamsVisible.bind(this)
+    this.getMethods = this.getMethods.bind(this)
+    this.getObject = this.getObject.bind(this)
+    this.getActionName = this.getActionName.bind(this)
+    this.getActionIsMini = this.getActionIsMini.bind(this)
+    // this.getHasParams = this.getHasParams.bind(this)
+    this.getMethodParams = this.getMethodParams.bind(this)
+    this.getParamsVisible = this.getParamsVisible.bind(this)
+    this.getDelay = this.getDelay.bind(this)
+    this.getDelayContent = this.getDelayContent.bind(this)
+    this.getActionLocaleName = this.getActionLocaleName.bind(this)
+    this.filterTargetMethod = this.filterTargetMethod.bind(this)
+
+    this.getTipInfo = this.getTipInfo.bind(this)
+    this.isAllowedMethod = this.isAllowedMethod.bind(this)
+    this.forbiddenTips = this.forbiddenTips.bind(this)
+  }
+
+  shouldComponentUpdate(nextProps, nextState) {
+    return (
+      !shallowEqualImmutable(this.props, nextProps) ||
+      !shallowEqualImmutable(this.state, nextState)
+    )
+  }
+
+  componentDidMount() {
+    this.unsubscribe = newEventStores.listen(this.onEventChange)
+    // this.autoReloadSpecialAction()
+  }
+
+  componentWillUnmount() {
+    this.unsubscribe()
+  }
+
+  componentDidUpdate(preProps) {
+    if (preProps.bid !== this.props.bid) {
+      this.obj = this.getObject()
+      this.setState(
+        {
+          methods: this.getMethods(), // 可选动作
+          actionName: this.getActionName(),
+          isMini: this.getActionIsMini(),
+          // hasParams: this.getHasParams(),
+          methodParams: this.getMethodParams(),
+          paramsVisible: this.getParamsVisible(),
+          delay: this.getDelay()
+        },
+        () => {
+          // this.autoReloadSpecialAction()
+        }
+      )
+    }
+  }
+
+  onEventChange(status) {
+    let obj = {}
+    let shouldUpdate = true
+    if (status) {
+      if (
+        (status.types.includes('updateBlockProp') &&
+          this.props.bid === status.data.affectBlockId &&
+          status.data.prop === 'object') ||
+        (status.types.includes('reloadBlock') &&
+          this.props.bid === status.data.affectBlockId)
+      ) {
+        // obj通知更新
+        this.obj = this.getObject()
+        obj.methods = this.getMethods() // 可选动作
+        obj.actionName = this.getActionName()
+        obj.isMini = this.getActionIsMini()
+        // obj.hasParams = this.getHasParams()
+        obj.methodParams = this.getMethodParams()
+        obj.paramsVisible = this.getParamsVisible()
+        obj.delay = this.getDelay()
+        this.setState(obj, () => {
+          if (this.obj && !this.state.actionName) {
+            // 创建相关方法
+            this.genDefaultAction()
+          }
+        })
+        shouldUpdate = false
+      }
+      if (
+        status.types.includes('changeActionBlockAction') &&
+        this.props.bid === status.data.affectBlockId &&
+        status.data.prop === 'paramsVisible'
+      ) {
+        obj.paramsVisible = this.getParamsVisible()
+      }
+      if (status.types.includes('updateActionMethod')) {
+        // 更新方法(主要是参数变化)
+        let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+        let objNode = getActionBlockObjNode({
+          obj: this.obj,
+          nodeId
+        })
+        if (
+          objNode &&
+          objNode.id === status.data.nodeId &&
+          (!status.data.targetBlockId ||
+            status.data.targetBlockId === this.props.bid) &&
+          status.data.methods.includes(this.state.actionName)
+        ) {
+          let keepVisible = true
+          if (
+            ['clone', 'sendSMS', 'sendSMS_stage'].indexOf(
+              this.state.actionName
+            ) >= 0
+          ) {
+            keepVisible = false
+          }
+          this.onReloadAction(keepVisible, false)
+        }
+      }
+    }
+    if (Object.keys(obj).length > 0 && shouldUpdate) {
+      this.setState(obj)
+    }
+  }
+
+  // hasDiffParams(objNode) {
+  //   let result = false
+  //   let method =
+  //     widgetStore.widget[objNode.type].map.methodsMap[this.state.actionName]
+  //   let params = genParams(method, objNode, this.props.bid, true)
+  //   let block = getEventBlockByBid(this.props.bid)
+  //   let preParams = block && block.action && block.action.params
+  //   if ((!params && preParams) || (params && !preParams)) {
+  //     // 有一个为空
+  //     result = true
+  //   } else if (params && preParams && params.length !== preParams.length) {
+  //     // 都有参数且长度不一致
+  //     result = true
+  //   } else if (params && preParams && params.length === preParams.length) {
+  //     // 都有参数且长度一致
+  //     let hasDif = false
+  //     params.forEach((param, index) => {
+  //       if (
+  //         param.name !== preParams[index].name ||
+  //         param.type !== preParams[index].type ||
+  //         ((param.pType || preParams[index].pType) &&
+  //           param.pType !== preParams[index].pType)
+  //       ) {
+  //         hasDif = true
+  //       }
+  //     })
+  //     result = hasDif
+  //   } else {
+  //     result = false
+  //   }
+  //   return result
+  // }
+
+  // autoReloadSpecialAction() {
+  //   let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+  //   let objNode = getActionBlockObjNode({
+  //     obj: this.obj,
+  //     nodeId
+  //   })
+  //   if (objNode) {
+  //     let methods = getReloadMethods(objNode)
+  //     if (methods && this.hasDiffParams(objNode)) {
+  //       newEventActions.updateActionMethod({
+  //         nodeId: objNode.id,
+  //         targetBlockId: this.props.bid,
+  //         methods: methods
+  //       })
+  //     }
+  //   }
+  // }
+
+  filterTargetMethod(method) {
+    let result = method
+    if (result) {
+      let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+      let objNode = getActionBlockObjNode({
+        obj: this.obj,
+        nodeId
+      })
+      let node = getEventNodeById(nodeId)
+      if (
+        !isChangedActionValid({
+          rootNode: node,
+          blockNode: objNode,
+          blockObj: this.obj,
+          actionName: result.name
+        })
+      ) {
+        result = undefined
+      }
+    }
+    return result
+  }
+
+  onReloadAction(keepVisible, addRecord) {
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let objNode = getActionBlockObjNode({
+      obj: this.obj,
+      nodeId
+    })
+    let method = this.filterTargetMethod(
+      getTargetMethod(objNode, this.state.actionName)
+    )
+    if (method) {
+      this.onMethodSelect(
+        { item: { props: { method: method } } },
+        keepVisible,
+        undefined,
+        false
+      )
+    } else {
+      this.setState(
+        {
+          actionName: null,
+          isMini: false,
+          // hasParams: false,
+          methodParams: [],
+          paramsVisible: 'all'
+        },
+        () => {
+          newEventActions.updateBlockProp({
+            nodeId,
+            blockId: this.props.bid,
+            prop: 'action',
+            value: null,
+            trigger: true,
+            addRecord: addRecord === undefined ? true : addRecord
+          })
+        }
+      )
+    }
+  }
+
+  onChangeDelay() {
+    let delay = this.getDelay()
+    this.setState({
+      delay: delay
+    })
+  }
+
+  genDefaultAction() {
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let objNode = getActionBlockObjNode({
+      obj: this.obj,
+      nodeId
+    })
+    if (objNode) {
+      let method
+      if (nodeIsService(objNode.type)) {
+        let methods = this.getMethods()
+        if (methods && methods.length > 0) {
+          if (nodeIsTimerService(objNode.type)) {
+            if (this.obj === 'curObj') {
+              method = methods.find(meth => {
+                return meth.name === 'recordResult'
+              })
+            }
+          } else if (nodeIsTransaction(objNode.type)) {
+            if (this.obj !== 'curObj') {
+              method = methods.find(meth => {
+                return meth.name === 'runTransaction'
+              })
+            } else {
+              method = methods.find(meth => {
+                return meth.name === 'paramResult'
+              })
+            }
+          } else if (nodeIsDyTransaction(objNode.type)) {
+            method = methods.find(meth => {
+              return meth.name === 'runDyTransaction'
+            })
+          } else if (nodeIsNormalService(objNode.type)) {
+            if (this.obj !== 'curObj') {
+              method = methods.find(meth => {
+                return meth.name === 'fireService' || meth.name === 'runService'
+              })
+            } else {
+              method = methods.find(meth => {
+                return meth.name === 'paramResult'
+              })
+            }
+          }
+        }
+      } else if (nodeIsFunctionGroup(objNode.type)) {
+        let methods = this.getMethods()
+        if (methods && methods.length > 0) {
+          // 触发动作组
+          if (this.obj !== 'curObj') {
+            method = methods.find(meth => {
+              return meth.name === 'fireFuncGroup'
+            })
+          } else {
+            method = methods.find(meth => {
+              return meth.name === 'funcResult'
+            })
+          }
+        }
+      } else if (objNode.type === 'data-event') {
+        let methods = this.getMethods()
+        if (methods && methods.length > 0) {
+          method = methods.find(meth => {
+            return meth.name === 'fireEvent'
+          })
+          // // 设置返回结果
+          // if (method) {
+          //   this.onMethodSelect(undefined, false, method)
+          // }
+        }
+      } else if (nodeIsApi(objNode.type)) {
+        let methods = this.getMethods()
+        let targetMethodName =
+          objNode.type === 'server-api'
+            ? 'sendServerApiRequest'
+            : 'sendApiRequest'
+        if (methods && methods.length > 0) {
+          method = methods.find(meth => {
+            return meth.name === targetMethodName
+          })
+        }
+      } else if (nodeIsSql(objNode.type)) {
+        let methods = this.getMethods()
+        if (methods && methods.length > 0) {
+          method = methods.find(meth => {
+            return meth.name === 'run'
+          })
+        }
+      } else if (nodeIsSharedService(objNode.type)) {
+        let methods = this.getMethods()
+        if (methods && methods.length > 0) {
+          method = methods.find(meth => {
+            return meth.name === 'fireService' || meth.name === 'runService'
+          })
+        }
+      }
+      if (method) {
+        this.onMethodSelect(undefined, false, method)
+      }
+    }
+  }
+
+  decorateAction(nAction, method, keepVisible, asyncCb) {
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let objNode = getActionBlockObjNode({
+      obj: this.obj,
+      nodeId
+    })
+    if (method.mini) {
+      nAction.mini = method.mini
+    }
+    if (method.miniType) {
+      nAction.miniType = method.miniType
+    }
+    if (method.miniEmit) {
+      nAction.miniEmit = method.miniEmit
+    }
+    if (method.meth) {
+      nAction.meth = method.meth
+    }
+    if (method.paramsAsObj) {
+      nAction.paramsAsObj = method.paramsAsObj
+    }
+    if (method.callback) {
+      nAction.callback = true // 表明有callback
+    }
+    let isAsync =
+      isAsyncDbMethod(method.name) ||
+      isAsyncMethod(method.name) ||
+      isAsyncDbCustomsMethod(method.name)
+    if (isAsync) {
+      genAsyncParams(method, objNode, this.props.bid, params => {
+        if (params) {
+          nAction.params = params
+        }
+        // this.combineOldAction(nAction, keepVisible)
+        asyncCb && asyncCb()
+      })
+    } else {
+      let params = genParams(method, objNode, this.props.bid, true)
+      if (params && params.length > 0) {
+        nAction.params = params
+      }
+      // this.combineOldAction(nAction, keepVisible)
+    }
+  }
+
+  // combineOldAction(newAction, keepVisible) {
+  //   let block = getEventBlockByBid(this.props.bid)
+  //   if (block && block.action && block.action.name === newAction.name) {
+  //     if (keepVisible) {
+  //       newAction.visible = block.action.visible
+  //     }
+  //     // action信息
+  //     if (block.action.info) {
+  //       newAction.info = cpJson(block.action.info)
+  //     }
+  //     if (block.action.params && newAction.params) {
+  //       newAction.params.forEach(newParam => {
+  //         block.action.params.forEach(oldParam => {
+  //           if (
+  //             newParam.name === oldParam.name &&
+  //             newParam.type === oldParam.type
+  //           ) {
+  //             if (oldParam.pGroup) {
+  //               if (newParam.pGroup === oldParam.pGroup) {
+  //                 newParam.value = oldParam.value
+  //               }
+  //             } else {
+  //               // 是否是克隆对象的子对象
+  //               if (oldParam.type === propType.CloneChild) {
+  //                 let cloneIDParam = block.action.params[0]
+  //                 if (
+  //                   cloneIDParam &&
+  //                   cloneIDParam.name === 'cloneId' &&
+  //                   cloneIDParam.value
+  //                 ) {
+  //                   // 并非子对象则还原
+  //                   if (oldParam.value && oldParam.value.length > 0) {
+  //                     oldParam.value.forEach(idProp => {
+  //                       if (!nodeIsChild(cloneIDParam.value, idProp.id)) {
+  //                         idProp.id = null
+  //                         idProp.props = []
+  //                       }
+  //                     })
+  //                   }
+  //                 }
+  //               }
+  //               newParam.value = oldParam.value
+  //             }
+  //           }
+  //         })
+  //       })
+  //     }
+  //   }
+  // }
+
+  onTriggerAction(nAction, addRecord) {
+    // 选择后触发相关的界面改变
+    this.setState(
+      {
+        actionName: nAction.name,
+        isMini: nAction.mini,
+        // hasParams: !!(nAction.params && nAction.params.length > 0),
+        methodParams: cpJson(nAction.params) || [],
+        paramsVisible: nAction.paramsVisible
+      },
+      () => {
+        let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+        newEventActions.updateBlockProp({
+          nodeId,
+          blockId: this.props.bid,
+          prop: 'action',
+          value: nAction,
+          trigger: true,
+          addRecord: addRecord === undefined ? true : addRecord
+        })
+      }
+    )
+  }
+
+  onMethodSelect(option, keepVisible, targetMethod, addRecord) {
+    if (option && option.key === 'emptyContent') {
+      return
+    }
+    let method
+    if (targetMethod) {
+      method = targetMethod
+    } else if (
+      option &&
+      option.item &&
+      option.item.props &&
+      option.item.props.method
+    ) {
+      method = option.item.props.method
+    }
+    if (method) {
+      // 选择了对象之后的操作
+      let nAction = { name: method.name, paramsVisible: 'all' }
+      this.decorateAction(
+        nAction,
+        method,
+        keepVisible,
+        this.onTriggerAction.bind(this, nAction, addRecord)
+      )
+      if (
+        !isAsyncDbMethod(method.name) &&
+        !isAsyncMethod(method.name) &&
+        !isAsyncDbCustomsMethod(method.name)
+      ) {
+        this.onTriggerAction(nAction, addRecord)
+      }
+    }
+  }
+
+  onToggleParamsVisible() {
+    newEventActions.toggleActionParamsVisible({ blockId: this.props.bid })
+  }
+
+  getMethods() {
+    return getActionMethods({
+      obj: this.obj,
+      curNodeId: this.props.eventNodeId || newEventStores.curEventNodeId,
+      isNewEvent: true
+    })
+  }
+
+  getObject() {
+    let _obj
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let curBlock = getEventBlockByBid(this.props.bid, nodeId)
+    if (curBlock) {
+      _obj = getBlockObj({ block: curBlock })
+    }
+    return _obj
+  }
+
+  getActionName() {
+    let result = null
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let block = getEventBlockByBid(this.props.bid, nodeId)
+    if (block) {
+      result = getBlockAciton(block)
+    }
+    return result
+  }
+
+  getActionIsMini() {
+    let result = false
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let block = getEventBlockByBid(this.props.bid, nodeId)
+    if (block) {
+      switch (block.op) {
+        case BLOCK_OP_TYPE.CALL:
+          result = block.mini || false
+          break
+        case BLOCK_OP_TYPE.LET:
+          result = block.args[0].mini || false
+          break
+      }
+    }
+    return result
+  }
+
+  // getHasParams() {
+  //   let result = false
+  //   let block = getEventBlockByBid(this.props.bid)
+  //   if (
+  //     block &&
+  //     block.type === EVENT_BLOCK_TYPE.ACTION &&
+  //     block.action &&
+  //     block.action.params
+  //   ) {
+  //     result = block.action.params.length > 0
+  //   }
+  //   return result
+  // }
+
+  getMethodParams() {
+    let result = []
+    let actionName = this.getActionName()
+    if (actionName) {
+      let methods = this.getMethods()
+      if (methods) {
+        let targetMethod = methods.find(method => {
+          return method.name === actionName
+        })
+        if (targetMethod) {
+          let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+          let objNode = getActionBlockObjNode({
+            obj: this.obj,
+            nodeId
+          })
+          result = genParams(targetMethod, objNode, this.props.bid, true)
+        }
+      }
+    }
+    return result
+  }
+
+  getParamsVisible() {
+    let result = undefined
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let block = getEventBlockByBid(this.props.bid, nodeId)
+    if (block && block.paramsVisible) {
+      result = block.paramsVisible
+    }
+    return result || 'all'
+  }
+
+  getDelay() {
+    let result = 0
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let block = getEventBlockByBid(this.props.bid, nodeId)
+    if (block && block.delay) {
+      result = block.delay || 0
+    }
+    return result
+  }
+
+  getDelayContent() {
+    if (this.state.delay && this.state.delay > 0) {
+      return (
+        i18n.t('EventView.jenga_action_block.delayPrefix') +
+        this.state.delay +
+        i18n.t('EventView.jenga_action_block.delayPostfix')
+      )
+    }
+    return ''
+  }
+
+  getActionLocaleName() {
+    let name = this.state.actionName ? this.state.actionName || '' : ''
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let objNode = getActionBlockObjNode({
+      obj: this.obj,
+      nodeId
+    })
+    if (objNode) {
+      if (
+        isParentWidgetProps(objNode) &&
+        this.state.actionName === 'miniPropValueChange'
+      ) {
+        let method = modulePropMethod()
+        name = method.locale ? method.locale[i18n.language] : name
+      } else if (this.state.isMini) {
+        name = getModuleInstanceNameLocale({
+          nodeId: objNode.id,
+          type: 'methods',
+          name: this.state.actionName
+        })
+      } else {
+        let nodeInfo = objNode ? widgetStore.widget[objNode.type] : undefined
+        if (objNode && nodeInfo && nodeInfo.map && nodeInfo.map.methodsMap) {
+          name =
+            nodeInfo.map.methodsMap[name] &&
+            nodeInfo.map.methodsMap[name].locale
+              ? nodeInfo.map.methodsMap[name].locale[i18n.language]
+              : name
+        }
+      }
+    }
+    return name
+  }
+
+  getTipInfo(item) {
+    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    let objNode = getActionBlockObjNode({
+      obj: this.obj,
+      nodeId
+    })
+    let type = objNode && objNode.type
+    if (type && item) {
+      let stopPro = e => {
+        e.stopPropagation()
+      }
+      let info = widgetStore.widget[type].map.methodsMap[item.name]
+      let content = info && info.desc && info.desc[i18n.language]
+      let link =
+        i18n.language === 'en' ? info && info.linkEN : info && info.linkZH
+      content = content ? (
+        <div onClick={stopPro}>
+          {content}
+          {info && link ? (
+            <a className="a-tag" href={link} target="_blank">
+              {i18n.t('Tips.more')}
+            </a>
+          ) : (
+            undefined
+          )}
+        </div>
+      ) : (
+        undefined
+      )
+      return (
+        (!isHySa() && info && content && (
+          <Tooltip
+            title={content}
+            placement="right"
+            destroyTooltipOnHide={true}
+          >
+            <div className="block-map-help">
+              <div
+                className="ih5-icon-help"
+                dangerouslySetInnerHTML={{ __html: iconStrObj.help }}
+              />
+            </div>
+          </Tooltip>
+        )) ||
+        null
+      )
+    } else {
+      return null
+    }
+  }
+
+  isAllowedMethod(method) {
+    let curNodeId = this.props.eventNodeId || newEventStores.curEventNodeId
+    return isMethodAllowed({
+      obj: this.obj,
+      method,
+      curNodeId,
+      isNewEvent: true
+    })
+  }
+
+  forbiddenTips() {
+    return (
+      <div>
+        <span>
+          {i18n.t('EventView.jenga_action_block.cross_page_method_warn')}
+        </span>
+        <a href={externalPath.crossPageMethod} target="_blank">
+          {i18n.t('EventView.jenga_action_block.cross_page_method_detail')}
+        </a>
+      </div>
+    )
+  }
+
+  render() {
+    let isVisibleOn =
+      this.state.methodParams.length > 0 &&
+      this.state.paramsVisible &&
+      this.state.paramsVisible === 'all'
+    let isVisibleOff =
+      this.state.methodParams.length > 0 &&
+      this.state.paramsVisible &&
+      this.state.paramsVisible === 'part'
+    let actionMethodMenu = () => {
+      return (
+        <Menu className="method-select-menu" onClick={this.onMethodSelect}>
+          {!this.state.methods || this.state.methods.length === 0 ? (
+            <MenuItem key={'emptyContent'} className="empty-content">
+              {i18n.t('EventView.jenga_action_block.emptyMethod')}
+            </MenuItem>
+          ) : (
+            this.state.methods.map((method, index) => {
+              let isAllowedMethod = this.isAllowedMethod(method)
+              return (
+                <MenuItem
+                  key={index}
+                  method={method}
+                  disabled={!isAllowedMethod}
+                  className={cls({
+                    selected: this.state.actionName === method.name,
+                    last: method.last
+                  })}
+                >
+                  <div className="f--hlc">
+                    {isAllowedMethod ? (
+                      <div className="method-title">
+                        {method.locale
+                          ? method.locale[i18n.language]
+                          : method.name}
+                      </div>
+                    ) : (
+                      <Popover
+                        overlayClassName={'popover-tips method-popover-tips'}
+                        content={this.forbiddenTips()}
+                        placement="right"
+                        destroyTooltipOnHide={true}
+                      >
+                        <div className="method-title">
+                          {method.locale
+                            ? method.locale[i18n.language]
+                            : method.name}
+                        </div>
+                      </Popover>
+                    )}
+                    {this.getTipInfo(method)}
+                  </div>
+                </MenuItem>
+              )
+            })
+          )}
+        </Menu>
+      )
+    }
+
+    return (
+      <div className="action-method flex-1">
+        <div className="method-body flex-1">
+          <div className="body-wrap f--hlc">
+            <Dropdown
+              trigger={['click']}
+              getPopupContainer={triggerNode => triggerNode.parentNode}
+              overlayClassName={'method-select-dropdown'}
+              overlay={actionMethodMenu()}
+            >
+              <div className="method-select f--hlc">
+                <div className="ant-dropdown-input f--hlc">
+                  <div
+                    className={cls('method-name f--hlc', {
+                      placeholder: !this.getActionLocaleName()
+                    })}
+                  >
+                    {this.getActionLocaleName() ||
+                      i18n.t('EventView.jenga_action_block.selectMethod')}
+                    {this.getTipInfo({ name: this.state.actionName })}
+                  </div>
+                  {this.getDelayContent() ? (
+                    <div className="delay-time">{this.getDelayContent()}</div>
+                  ) : null}
+                </div>
+                <div className="ant-dropdown-icon" />
+              </div>
+            </Dropdown>
+            <BlockActionReload reload={this.onReloadAction.bind(this, false)} />
+            <BlockActionDelay
+              changeDelay={this.onChangeDelay.bind(this)}
+              bid={this.props.bid}
+              eventNodeId={this.props.eventNodeId}
+            />
+          </div>
+          <BlockActionMethodParams
+            params={this.state.methodParams}
+            actionName={this.state.actionName}
+            paramsVisible={this.state.paramsVisible}
+            bid={this.props.bid}
+            layer={this.props.layer}
+            groupLayer={this.props.groupLayer}
+            nestGroupLayer={this.props.nestGroupLayer}
+            extraGapGroupLayer={this.props.extraGapGroupLayer}
+            eventNodeId={this.props.eventNodeId}
+          />
+        </div>
+        <div className="method-expand-control f--hcc">
+          {this.state.methodParams.length === 0 ||
+          !this.state.actionName ? null : (
+            <button
+              className={cls('btn-clear btn-toggle-params-visible', {
+                'visible-on': isVisibleOn,
+                'visible-off': isVisibleOff
+              })}
+              // onClick={this.onToggleParamsVisible}
+            >
+              {isVisibleOn && (
+                <div
+                  className="icon"
+                  dangerouslySetInnerHTML={{ __html: iconStrObj.dropUpIcon }}
+                />
+              )}
+              {isVisibleOff && (
+                <div
+                  className="icon"
+                  dangerouslySetInnerHTML={{ __html: iconStrObj.dropDownIcon }}
+                />
+              )}
+            </button>
+          )}
+        </div>
+      </div>
+    )
+  }
+}

+ 483 - 0
coms/jenga/block/base/action/BlockActionMethodParams.jsx

@@ -0,0 +1,483 @@
+import React from 'react'
+import i18n from 'i18next'
+import { is } from 'immutable'
+import newEventActions from 'actions/newEvent'
+import newEventStores from 'stores/newEvent'
+import {
+  getActionBlockObjNode,
+  getEventBlockByBid
+} from 'stores/funcs/newEvent'
+import {
+  hasEsDbSeniorSearch,
+  isApiMethod,
+  paramIsHideKeep,
+  isDbMallMethodShouldReload
+} from 'stores/funcs/event/methodUtils'
+import { shallowEqualImmutable } from 'utils/utils'
+import { EVENT_BLOCK_TYPE } from 'const/const'
+import propType from 'const/propType'
+// import {
+//   getActionDbNodeType,
+//   getDbCols,
+//   getNode,
+//   getActionDbId
+// } from './dbComs/actionDbFuncs'
+import BlockActionMethodParamItem from './BlockActionMethodParamItem'
+// import BlockActionMethodParamApiToggle from './BlockActionMethodParamApiToggle'
+// import BlockActionMethodParamEsSeniorSearch from './BlockActionMethodParamEsSeniorSearch'
+
+export default class BlockActionMethodParams extends React.Component {
+  constructor(props) {
+    super(props)
+    this.state = {
+      // paramsValue: this.getParamsValue(),
+      // dbInfo: {}
+    }
+
+    this.onEventChange = this.onEventChange.bind(this)
+    // this.updateDbInfo = this.updateDbInfo.bind(this)
+    this.paramShouldShow = this.paramShouldShow.bind(this)
+    // this.updateMethod = this.updateMethod.bind(this)
+    this.getObject = this.getObject.bind(this)
+    this.getName = this.getName.bind(this)
+    // this.getParamsValue = this.getParamsValue.bind(this)
+    // this.getInfo = this.getInfo.bind(this)
+    this.getVisible = this.getVisible.bind(this)
+    // this.replenishApiParams = this.replenishApiParams.bind(this)
+    this.renderInfo = this.renderInfo.bind(this)
+  }
+
+  shouldComponentUpdate(nextProps, nextState) {
+    return (
+      !shallowEqualImmutable(this.props, nextProps) ||
+      !shallowEqualImmutable(this.state, nextState)
+    )
+  }
+
+  componentDidMount() {
+    this.unsubscribe = newEventStores.listen(this.onEventChange)
+    // this.updateDbInfo()
+  }
+
+  componentWillUnmount() {
+    this.unsubscribe()
+  }
+
+  componentDidUpdate(preProps) {
+    // if (preProps.bid !== this.props.bid) {
+    //   this.setState({
+    //     paramsValue: this.getParamsValue()
+    //   })
+    //   this.updateDbInfo()
+    // } else if (
+    //   !preProps.actionName &&
+    //   preProps.actionName !== this.props.actionName
+    // ) {
+    //   // actionName由无到有
+    //   process.nextTick(() => {
+    //     this.updateDbInfo()
+    //   })
+    // } else if (
+    //   // DbMall比较特殊,切换不同方法时需要重新获取DbCols
+    //   preProps.actionName !== this.props.actionName &&
+    //   isDbMallMethodShouldReload(this.props.actionName)
+    // ) {
+    //   process.nextTick(() => {
+    //     this.updateDbInfo()
+    //   })
+    // }
+  }
+
+  onEventChange(status) {
+    // let obj = {}
+    // if (status) {
+    //   if (
+    //     status.types.includes('updateBlockProp') &&
+    //     this.props.bid === status.data.affectBlockId &&
+    //     ['object', 'action'].indexOf(status.data.prop) >= 0
+    //   ) {
+    //     let paramsValue = this.getParamsValue()
+    //     if (!is(this.state.params, params)) {
+    //       obj.params = params
+    //     }
+    //     // 切换对象时检查
+    //     if (['object'].indexOf(status.data.prop) >= 0) {
+    //       this.updateDbInfo()
+    //     }
+    //   } else if (
+    //     status.types.includes('reloadParamsItemMethod') &&
+    //     this.props.bid === status.data.affectBlockId
+    //   ) {
+    //     this.updateMethod()
+    //   }
+    // }
+    // if (Object.keys(obj).length > 0) {
+    //   this.setState(obj)
+    // }
+  }
+
+  // updateDbInfo() {
+  //   let { bid } = this.props
+  //   let node = getNode({
+  //     bid: this.props.bid,
+  //     obj: this.getObject(),
+  //     useObj: true,
+  //     actionName: this.getName()
+  //   })
+  //   let dbId = getActionDbId({ node: node, bid: bid })
+  //   let dbNodeType = getActionDbNodeType({
+  //     node: node,
+  //     bid: bid
+  //   })
+  //   if (dbId) {
+  //     getDbCols({
+  //       dbId: dbId,
+  //       nodeType: dbNodeType,
+  //       cb: dbCols => {
+  //         this.setState({
+  //           dbInfo: { dbId, dbCols, dbNodeType }
+  //         })
+  //       }
+  //     })
+  //   } else {
+  //     if (Object.keys(this.state.dbInfo).length >= 0) {
+  //       this.setState({
+  //         dbInfo: {}
+  //       })
+  //     }
+  //   }
+  // }
+
+  paramShouldShow(param, index) {
+    let result = true
+    switch (this.getVisible()) {
+      case 'part':
+        if (
+          (!param.value && param.value !== 0 && param.value !== false) ||
+          ((param.type === propType.Formula ||
+            param.type === propType.FormulaColor ||
+            param.type === propType.FormulaJson) &&
+            param.value &&
+            !param.value.code)
+        ) {
+          result = false
+        }
+        break
+    }
+    if (
+      result &&
+      paramIsHideKeep({
+        param: param,
+        bid: this.props.bid,
+        actionName: this.getName(),
+        index: index,
+        nodeId: this.props.eventNodeId || newEventStores.curEventNodeId,
+        isNewEvent: true
+      })
+    ) {
+      result = false
+    }
+    return result
+  }
+
+  // updateMethod() {
+  //   let objNode = getActionBlockObjNode({
+  //     obj: this.getObject(),
+  //     blockId: this.props.bid
+  //   })
+  //   if (objNode) {
+  //     newEventActions.updateActionMethod({
+  //       nodeId: objNode.id,
+  //       targetBlockId: this.props.bid,
+  //       methods: [this.getName()]
+  //     })
+  //   }
+  // }
+
+  getObject() {
+    let _obj = null
+    let block = getEventBlockByBid(this.props.bid)
+    if (block) {
+      _obj = block.object
+    }
+    return _obj
+  }
+
+  getName() {
+    return this.props.actionName ? this.props.actionName || null : null
+  }
+
+  // getParamsValue() {
+  //   let result = []
+  //   let block = getEventBlockByBid(this.props.bid)
+  //   if (
+  //     block &&
+  //     block.type === EVENT_BLOCK_TYPE.ACTION &&
+  //     block.action &&
+  //     block.action.params
+  //   ) {
+  //     result = block.action.params
+  //   }
+  //   return result
+  // }
+
+  getVisible() {
+    return this.props.paramsVisible ? this.props.paramsVisible || 'all' : 'all'
+  }
+
+  // getInfo() {
+  //   let result = undefined
+  //   let block = getEventBlockByBid(this.props.bid)
+  //   if (
+  //     block &&
+  //     block.type === EVENT_BLOCK_TYPE.ACTION &&
+  //     block.action &&
+  //     block.action.info
+  //   ) {
+  //     result = block.action.info
+  //   }
+  //   return result
+  // }
+
+  // replenishApiParams(apiGroups, result) {
+  //   let groupHeader = (title, index) => {
+  //     let className = 'params-group'
+  //     if (index === 0) {
+  //       className += ' first'
+  //     }
+  //     return (
+  //       <div className={className} key={index + title}>
+  //         <div className="title">{title}</div>
+  //         <BlockActionMethodParamApiToggle
+  //           group={title}
+  //           bid={this.props.bid}
+  //           actionName={this.props.actionName}
+  //         />
+  //       </div>
+  //     )
+  //   }
+  //   let addGroupParams = (name, index, groupParams) => {
+  //     let groupIndex = apiGroups.findIndex(group => group.name === name)
+  //     if (groupIndex < 0) {
+  //       groupParams.push(groupHeader(name, index))
+  //     } else {
+  //       let group = apiGroups[groupIndex]
+  //       groupParams.push(group.header)
+  //       groupParams = groupParams.concat(group.coms)
+  //       apiGroups.splice(groupIndex, 1)
+  //     }
+  //     return groupParams
+  //   }
+  //   // 默认title
+  //   let defaultHeaders = ['Header', 'Body']
+  //   let groupParams = []
+  //   defaultHeaders.forEach((header, index) => {
+  //     groupParams = addGroupParams(header, index, groupParams)
+  //   })
+  //   // 把剩余的加上
+  //   if (apiGroups.length > 0) {
+  //     apiGroups.forEach(group => {
+  //       groupParams.push(group.header)
+  //       groupParams = groupParams.concat(group.coms)
+  //     })
+  //   }
+  //   result = result.concat(groupParams)
+  //   return result
+  // }
+
+  // replenishSeniorSearchParams(searchParams, result) {
+  //   let groupParams = []
+  //   let groupHeader = title => {
+  //     let className = 'params-group first'
+  //     return (
+  //       <div className={className} key={title}>
+  //         <BlockActionMethodParamEsSeniorSearch
+  //           group={title}
+  //           bid={this.props.bid}
+  //           actionName={this.props.actionName}
+  //         />
+  //       </div>
+  //     )
+  //   }
+  //   let addGroupParams = name => {
+  //     groupParams.push(groupHeader(name))
+  //     groupParams = groupParams.concat(searchParams[0].coms)
+  //     return groupParams
+  //   }
+  //   if (searchParams && searchParams.length > 0) {
+  //     groupParams = addGroupParams('SeniorEsSearch')
+  //     if (result && result.length > 0) {
+  //       if (
+  //         result[0].props &&
+  //         result[0].props.param &&
+  //         result[0].props.param.name === 'query'
+  //       ) {
+  //         let pre = result.slice(0, 1)
+  //         let sub = result.slice(1, result.length)
+  //         result = pre.concat(groupParams).concat(sub)
+  //       } else {
+  //         result = groupParams.concat(result)
+  //       }
+  //     } else {
+  //       result = groupParams
+  //     }
+  //   }
+  //   return result
+  // }
+
+  renderInfo() {
+    let params = this.props.params
+    let visible = this.getVisible()
+    let shouldRender = 0
+    let normal = [] // 普通params
+    let cloneChild = [] // 克隆对象params
+    let groups = [] // 带pGroup的params {name, coms}
+    let groupStyle = isApiMethod(this.props.actionName)
+      ? {
+          backgroundColor: '#385452',
+          marginBottom: 0,
+          paddingBottom: '2px'
+        }
+      : undefined
+    let groupClass = undefined
+    params.map((param, index) => {
+      groupClass =
+        hasEsDbSeniorSearch(this.props.actionName) && param.pGroup
+          ? 'group-param-item'
+          : groupClass
+      if (this.paramShouldShow(param, index)) {
+        shouldRender += 1
+        if (param.pGroup && false) {
+          let pGroup = groups.find(item => {
+            return item.name === param.pGroup
+          })
+          if (pGroup) {
+            pGroup.coms.push(
+              <BlockActionMethodParamItem
+                key={index}
+                paramStyle={groupStyle}
+                paramClass={groupClass}
+                bid={this.props.bid}
+                layer={this.props.layer}
+                groupLayer={this.props.groupLayer}
+                nestGroupLayer={this.props.nestGroupLayer}
+                extraGapGroupLayer={this.props.extraGapGroupLayer}
+                actionName={this.props.actionName}
+                index={index}
+                param={param}
+                dbInfo={this.state.dbInfo}
+                visible={visible}
+              />
+            )
+          } else {
+            let className = 'params-group'
+            if (groups.length === 0) {
+              className += ' first'
+            }
+            let groupName = i18n.exists('EventView.DbHeader.' + param.pGroup)
+              ? i18n.t('EventView.DbHeader.' + param.pGroup)
+              : param.pGroup
+            let group = {
+              name: param.pGroup,
+              header: (
+                <div className={className} key={index + param.pGroup}>
+                  <div className="title">{groupName}</div>
+                  {isApiMethod(this.props.actionName) ? (
+                    <BlockActionMethodParamApiToggle
+                      group={param.pGroup}
+                      bid={this.props.bid}
+                      actionName={this.props.actionName}
+                    />
+                  ) : null}
+                </div>
+              ),
+              coms: [
+                <BlockActionMethodParamItem
+                  key={index}
+                  paramStyle={groupStyle}
+                  paramClass={groupClass}
+                  bid={this.props.bid}
+                  layer={this.props.layer}
+                  groupLayer={this.props.groupLayer}
+                  nestGroupLayer={this.props.nestGroupLayer}
+                  extraGapGroupLayer={this.props.extraGapGroupLayer}
+                  actionName={this.props.actionName}
+                  index={index}
+                  param={param}
+                  dbInfo={this.state.dbInfo}
+                  visible={visible}
+                />
+              ]
+            }
+            groups.push(group)
+          }
+        } else if (param.type === propType.CloneChild && false) {
+          cloneChild.push(
+            <BlockActionMethodParamItem
+              key={index}
+              bid={this.props.bid}
+              layer={this.props.layer}
+              groupLayer={this.props.groupLayer}
+              nestGroupLayer={this.props.nestGroupLayer}
+              extraGapGroupLayer={this.props.extraGapGroupLayer}
+              actionName={this.props.actionName}
+              index={index}
+              param={param}
+              dbInfo={this.state.dbInfo}
+              visible={visible}
+            />
+          )
+        } else {
+          normal.push(
+            <BlockActionMethodParamItem
+              key={index}
+              bid={this.props.bid}
+              layer={this.props.layer}
+              groupLayer={this.props.groupLayer}
+              nestGroupLayer={this.props.nestGroupLayer}
+              extraGapGroupLayer={this.props.extraGapGroupLayer}
+              actionName={this.props.actionName}
+              index={index}
+              param={param}
+              dbInfo={this.state.dbInfo}
+              visible={visible}
+              eventNodeId={this.props.eventNodeId}
+            />
+          )
+        }
+      }
+    })
+    let result = normal
+    // if (isApiMethod(this.props.actionName)) {
+    //   result = this.replenishApiParams(groups, result)
+    // } else if (hasEsDbSeniorSearch(this.props.actionName)) {
+    //   result = this.replenishSeniorSearchParams(groups, result)
+    // } else {
+    //   if (groups.length !== 0) {
+    //     let groupParams = []
+    //     groups.forEach(group => {
+    //       groupParams.push(group.header)
+    //       groupParams = groupParams.concat(group.coms)
+    //     })
+    //     result = result.concat(groupParams)
+    //   }
+    // }
+    return {
+      renderParams: result,
+      shouldRender: shouldRender,
+      cloneChildParams: cloneChild
+    }
+  }
+
+  render() {
+    let { shouldRender, renderParams, cloneChildParams } = this.renderInfo()
+    return shouldRender > 0 ? (
+      <div className="params-wrap">
+        <div className="params">{renderParams}</div>
+        {/* {cloneChildParams && cloneChildParams.length > 0
+          ? cloneChildParams
+          : null} */}
+      </div>
+    ) : null
+  }
+}