ttk-app-core
Version:
enterprise develop framework
479 lines (425 loc) • 19.3 kB
JavaScript
import { Map, List, fromJS } from 'immutable'
import { reducer as MetaReducer } from 'edf-meta-engine'
import config from './config'
import { getInitState } from './data'
import { history } from 'edf-utils'
var listeners = Map()
//存放需要guide的menu及状态
let guideMenuList = {}
class reducer {
constructor(option) {
this.metaReducer = option.metaReducer
this.config = config.current
this.webapi = this.config.webapi
}
init = (state, option) => {
let initState = getInitState()
initState.data.other.username = sessionStorage['username']
state = this.metaReducer.init(state, getInitState())
if (this.config.menu && !this.config.webapi.getMenu) {
return this.load(state, { menu: this.config.menu })
}
var defaultMenuItem, firstMenuItem, defaultOpens = [], menuKeyNameMap = [], menuAppNameMap = []
state = this.metaReducer.sf(state, 'data.menuKeyNameMap', fromJS(menuKeyNameMap))
state = this.metaReducer.sf(state, 'data.menuAppNameMap', fromJS(menuAppNameMap))
let availableOrg = sessionStorage.getItem('currentOrgStatus')
if (availableOrg == 1) {
state = this.metaReducer.sf(state, 'data.isTabsStyle', false)
state = this.metaReducer.sf(state, 'data.isShowMenu', false)
state = this.metaReducer.sf(state, 'data.visible', false)
return this.setContent(state, '企业管理', 'edf-company-manage')
} else if (availableOrg == 2) {
state = this.metaReducer.sf(state, 'data.isTabsStyle', false)
state = this.metaReducer.sf(state, 'data.isShowMenu', false)
state = this.metaReducer.sf(state, 'data.visible', false)
return this.setContent(state, '新建企业', 'edf-company-manage-add')
}
return state
}
load = (state, { menu }, menuStyle) => {
if (!menu || menu.length == 0)
return state
var defaultMenuItem, firstMenuItem, defaultOpens = [], menuKeyNameMap = {}, menuAppNameMap = {}
const loop = (children) => {
const ret = []
children.forEach(child => {
menuKeyNameMap[child.name] = child.key
//history增加
if (child.appName) {
menuAppNameMap[child.appName] = {
name: child.name,
props: child.appParams || {}
}
if (child.hasOwnProperty('isGuide')) {
guideMenuList[child.appName] = {
status: child.isGuide,
menuId: child.code
}
}
menuAppNameMap[child.appName].props.accessType = 0
menuAppNameMap[child.appName].props.isFolded = child.isFolded
}
if (!child.children) {
if (!firstMenuItem) {
firstMenuItem = child
}
if (child.isDefault) {
defaultMenuItem = child
}
}
else {
if (child.isExpand) {
defaultOpens.push(child)
}
loop(child.children)
}
})
return ret
}
loop(menu)
defaultMenuItem = defaultMenuItem || firstMenuItem
//note 默认展现的APP
if (!defaultMenuItem) {
defaultMenuItem = menu ? menu[0] : {}
}
const menuSelectedKeys = fromJS(defaultMenuItem ? [defaultMenuItem.key] : [])
const menuDefaultOpenKeys = fromJS(defaultOpens.map(o => o.key))
const defaultContent = defaultMenuItem ? defaultMenuItem : {}
let fieldValueSetter = {
'data.currentMenuType': menuStyle,
'data.menu': fromJS(menu),
'data.menuKeyNameMap': fromJS(menuKeyNameMap),
'data.menuAppNameMap': fromJS(menuAppNameMap),
'data.menuSelectedKeys': menuSelectedKeys,
'data.menuDefaultOpenKeys': menuDefaultOpenKeys
}
state = this.metaReducer.sfs(state, fieldValueSetter)
let _defaultOpenKeys = this.getMenuSelectKeys(state, fromJS(menu))
state = this.metaReducer.sf(state, 'data.defaultOpenKeys', _defaultOpenKeys)
const childApp = history.getChildApp('edfx-app-portal')
if (childApp)
return this.setContent(state, '', childApp, {})
else {
state = this.metaReducer.sf(state, 'data.isTabsStyle', true)
state = this.metaReducer.sf(state, 'data.isShowMenu', true)
state = this.metaReducer.sf(state, 'data.visible', false)
return this.setContent(state, defaultContent.name, defaultContent.appName, defaultContent.appProps)
}
}
changeMenuType = (state, list, tabChangeWithMenu) => {
let _currentMenuType = this.metaReducer.gf(state, 'data.currentMenuType')
if (_currentMenuType == 2) list = []
if (list && list.length > 0) {
list = this.getMenuSelectKeys(state, fromJS(this.metaReducer.gf(state, 'data.menu')))
if (tabChangeWithMenu) {
list.push(tabChangeWithMenu)
}
state = this.metaReducer.sf(state, 'data.defaultOpenKeys', list)
}
else {
state = this.metaReducer.sf(state, 'data.defaultOpenKeys', list)
}
return state
}
getMenuSelectKeys = (state, menuItem) => {
//如果是收缩则不显示下级菜单
let expendMenuKeys = []
let _currentMenuType = this.metaReducer.gf(state, 'data.currentMenuType')
let _fold = this.metaReducer.gf(state, 'data.width')
if (_currentMenuType == 1) {
//const menuItem = this.metaAction.gf('data.menu')
if (menuItem.size > 0) {
menuItem.map((item, index) => {
if (item.get('appName') == 'edfx-app-home') return false
if (item.get('children').size > 0) {
expendMenuKeys.push(item.get('key'))
}
})
}
}
//expendMenuKeys.push("1011")
return expendMenuKeys
}
manageList = (state, { manageList }) => {
if (!manageList) {
manageList = []
manageList.push({ name: '无' })
}
if (manageList) {
state = this.metaReducer.sf(state, 'data.manageList', fromJS(manageList))
state = this.metaReducer.sf(state, 'data.manageListShow', fromJS(manageList))
}
return state
}
setContent = (state, name, appName, appProps) => {
//判断是否需要打开app内的引导
let keys = Object.keys(guideMenuList)
if (keys.indexOf(appName) != -1) {
if (!appProps) {
appProps = {}
}
appProps.isGuide = guideMenuList[appName].status
appProps.isMenuCode = guideMenuList[appName].menuId
}
//判断当前显示页签appName和要新打开的是否一致
const currContent = this.metaReducer.gf(state, 'data.content')
let appArr = ['ttk-access-app-tranreport', 'edfx-business-subject-manage']
if (currContent && appName == currContent.get('appName') && appArr.indexOf(appName) == -1)
return state
//如果要打开的app在map中,则修改props,反之添加到map中
let menuAppNameMap = this.metaReducer.gf(state, 'data.menuAppNameMap')
if (name && appName && appProps && menuAppNameMap.getIn([appName, 'name']) != name) {
menuAppNameMap = menuAppNameMap.set(appName, fromJS({ name, props: appProps }))
state = this.metaReducer.sf(state, 'data.menuAppNameMap', menuAppNameMap)
} else if (name && appName && appProps && menuAppNameMap.getIn([appName, 'name']) == name) {
menuAppNameMap = menuAppNameMap.updateIn([appName, 'props'], () => {
return appProps.toJS ? appProps : fromJS(appProps)
})
state = this.metaReducer.sf(state, 'data.menuAppNameMap', menuAppNameMap)
}
/**
* 参数问题,zhaoyun@ttk.com
*/
let _appProps = menuAppNameMap.getIn([appName, 'props'])
if (_appProps && _appProps.size > 0) {
appProps = _appProps
}
let content = null
if (appProps && appProps.size) {
content = fromJS({ name, appName, appProps: appProps.toJS(), editing: false })
} else {
content = fromJS({ name, appName, appProps, editing: false })
}
state = this.metaReducer.sf(state, 'data.content', content)
var openTabs = this.metaReducer.gf(state, 'data.openTabs') || List()
var hit = openTabs.findIndex(o => o.get('name') == name || o.get('appName') == appName) != -1
let orgSign = false
if (appProps !== undefined && appProps.size > 0 && appProps !== '{}') {
if (appProps.get('isTabsStyle') == false && appProps.get('isShowMenu') == false) {
state = this.metaReducer.sf(state, 'data.isTabsStyle', true)
state = this.metaReducer.sf(state, 'data.isShowMenu', true)
hit = false
orgSign = false
content = fromJS({ name: '我的桌面', appName: 'edfx-app-home', appProps: { isFolded: 0 } })
openTabs = List()
state = this.metaReducer.sf(state, 'data.content', content)
let listener = listeners.get(`onTabFocus_edfx-app-home`)
if (listener) {
setTimeout(() => listener(), 16)
}
}
}
const isTabsStyle = this.metaReducer.gf(state, 'data.isTabsStyle')
if (!hit) {
if (isTabsStyle && openTabs.size > 0) {
openTabs = openTabs.push(content)
}
else {
openTabs = List().push(content)
}
state = this.metaReducer.sf(state, 'data.openTabs', openTabs)
}
else {
if (!isTabsStyle) {
openTabs = List().push(content)
state = this.metaReducer.sf(state, 'data.openTabs', openTabs)
}
else {
//appName相同,但name不相同的情况下,更新opentabs,执行ontabfocus事件
if (openTabs.findIndex(o => o.get('name') != name && o.get('appName') == appName) != -1) {
openTabs = openTabs.updateIn([openTabs.findIndex(o => o.get('appName') == appName), 'name'], () => {
return name
})
openTabs = openTabs.updateIn([openTabs.findIndex(o => o.get('appName') == appName), 'appProps'], () => {
return appProps
})
}
state = this.metaReducer.sf(state, 'data.openTabs', openTabs)
let listener = listeners.get(`onTabFocus_${appName}`)
if (listener) {
setTimeout(() => listener(appProps), 16)
}
}
}
if (orgSign) {
setTimeout(() => {
history.pushChildApp('edfx-app-portal')
}, 0)
}
else {
setTimeout(() => {
history.pushChildApp('edfx-app-portal', content.get('appName'))
}, 0)
}
return state
}
closeContent = (state, name) => {
const curContent = this.metaReducer.gf(state, 'data.content')
const appName = curContent.get('appName')
return this.closeContentReally(state, name)
}
onlyCloseContent = (state, appName) => {
let openTabs = this.metaReducer.gf(state, 'data.openTabs').toJS()
let index = null
for (let i = 0; i < openTabs.length; i++) {
if (openTabs[i].appName == appName) {
index = i
break
}
}
openTabs.splice(index, 1)
state = this.metaReducer.sf(state, 'data.openTabs', fromJS(openTabs))
return state
}
closeContentReally = (state, name, fun, res, appName = "edfx-app-home") => {
var openTabs = this.metaReducer.gf(state, 'data.openTabs') || List()
let desktop = openTabs.toJS().slice(0, 1)
var hitIndex = openTabs.findIndex(o => o.get('name') == name)
if (name == 'all' || name == 'toggleManage') {
state = this.metaReducer.sf(state, 'data.width', true)
state = this.metaReducer.sf(state, 'data.openTabs', fromJS(desktop))
state = this.metaReducer.sf(state, 'data.content', openTabs.get(0))
if (name == 'toggleManage') {
history.pullChildApp(appName, fromJS(desktop))
return state
}
let listener = listeners.get(`onTabFocus_edfx-app-home`)
if (listener) {
setTimeout(() => listener(name == 'toggleManage' ? { action: 'toggleManage' } : {}), 16)
}
return state
}
state = this.removeEventListener(state, name)
openTabs = openTabs.remove(hitIndex)
state = this.metaReducer.sf(state, 'data.openTabs', openTabs)
state = this.metaReducer.sf(state, 'data.content', openTabs.get(openTabs.size - 1))
//判断左树状态
let currentApp = openTabs.get(openTabs.size - 1).toJS(),
currentMenuStyle = this.metaReducer.gf(state, 'data.currentMenuType')
if (currentMenuStyle == 2) {
if (currentApp.appProps.isFolded == 1) {
state = this.metaReducer.sf(state, 'data.width', false)
} else {
state = this.metaReducer.sf(state, 'data.width', true)
}
}
let activeApp = this.metaReducer.gf(state, 'data.content').toJS()
activeApp.appProps.accessType = 0
let listener = listeners.get(`onTabFocus_${activeApp.appName}`)
if (listener) {
setTimeout(() => listener(Map.isMap(activeApp.appProps) ? activeApp.appProps : Map(activeApp.appProps) || {}), 16)
//去掉延时器,避免当连续卸载APP时,回调函数将卸载掉的app的state重新写入reduxstate中,导致再次打开时报错
// listener(Map.isMap(activeApp.appProps) ? activeApp.appProps : Map(activeApp.appProps) || {})
}
history.pullChildApp(appName, openTabs)
return state
}
closeAll = (state) => {
state = this.metaReducer.sf(state, 'data.openTabs', new List())
return this.metaReducer.sf(state, 'data.content', new Map())
}
reInit = (state, content, openTabs) => {
state = this.metaReducer.sf(state, 'data.openTabs', openTabs)
return this.metaReducer.sf(state, 'data.content', content)
}
addEventListener = (state, eventName, handler) => {
const currContent = this.metaReducer.gf(state, 'data.content')
const appName = currContent.get('appName')
eventName = eventName + '_' + appName
if (!listeners.get(eventName)) {
listeners = listeners.set(eventName, handler)
}
return state
}
removeEventListener = (state, name) => {
if (name == 'all') { // 删除所有页签的listener
listeners = Map()
return state
}
let appName
const openTabs = this.metaReducer.gf(state, 'data.openTabs').toJS()
for (let i = 0; i < openTabs.length; i++) {
if (openTabs[i].name == name) {
appName = openTabs[i].appName
}
}
// 删除当前页签的listener
let listenersKey = Object.keys(listeners.toJS())
for (let i = 0; i < listenersKey.length; i++) {
if (listenersKey[i].indexOf('_' + appName) > -1 &&
listeners.get(listenersKey[i])) {
listeners = listeners.remove(listenersKey[i])
}
}
return state
}
//判断页面是否处于编辑状态
editing = (state, appName, status) => {
let openTabs = this.metaReducer.gf(state, 'data.openTabs').toJS()
openTabs.forEach(o => {
if (o.appName == appName) {
o.editing = status
}
})
state = this.metaReducer.sf(state, 'data.openTabs', fromJS(openTabs))
return state
}
appList = (state, response, action) => {
if (action && action == "reload") {
let listener = listeners.get(`onTabFocus_edfx-app-home`)
if (listener) {
// 1:更新桌面applist
setTimeout(() => listener(), 16)
}
}
state = this.metaReducer.sf(state, 'data.desktopAppList', fromJS(response))
return state
}
//企业列表搜索
manageListShow = (state, list) => {
if (list.length == 0) {
return state = this.metaReducer.sf(state, 'data.manageListShow', fromJS([{ name: '无匹配项', disabled: true }]))
}
return state = this.metaReducer.sf(state, 'data.manageListShow', fromJS(list))
}
//resize事件
resize = (state) => {
let listener = listeners.toJS()
let keys = Object.keys(listener)
for (let i = 0; i < keys.length; i++) {
if (keys[i].indexOf('onResize') != -1) {
setTimeout(() => listener[keys[i]](), 16)
}
}
return state
}
//客服、二维码
weixin = (state, status) => {
state = this.metaReducer.sf(state, 'data.service.qrcodeVisible', status)
return state
}
//content放大缩小事件
fold = (state, option) => {
let status = option['data.isShowMenu'] ? 1 : 0
//通知app放大缩小状态
let listener = listeners.toJS()
let keys = Object.keys(listener)
for (let i = 0; i < keys.length; i++) {
if (keys[i].indexOf('enlargeClick') != -1) {
setTimeout(() => listener[keys[i]](status), 16)
}
}
return this.metaReducer.sfs(state, option)
}
//关闭app内的Guide
closeGuide = (state, appName) => {
guideMenuList[appName].status = false
console.log(guideMenuList)
return state
}
}
export default function creator(option) {
const metaReducer = new MetaReducer(option),
o = new reducer({ ...option, metaReducer })
return { ...metaReducer, ...o }
}