Browse Source

uas手机版
应用菜单item封装红点获取逻辑

RaoMeng 5 years ago
parent
commit
2c923c19c7

+ 2 - 0
uas-office-web/uas-mobile/src/components/common/func/FuncGroup.jsx

@@ -39,6 +39,7 @@ export default class FuncGroup extends Component {
       rightIcon,
       operable,
       onOperationClick,
+      onFuncDataChange,
     } = this.props
 
     let funcItems = []
@@ -57,6 +58,7 @@ export default class FuncGroup extends Component {
             }
             onFuncClick={onFuncClick}
             onOperationClick={onOperationClick}
+            onFuncDataChange={onFuncDataChange}
             key={'funcChild' + funcIndex}/>,
         )
       })

+ 14 - 12
uas-office-web/uas-mobile/src/components/common/func/FuncItem.jsx

@@ -8,6 +8,9 @@ import './common-func.less'
 import { Icon } from 'antd-mobile'
 import { isObjEmpty } from '../../../utils/common/common.util'
 import { fetchGet } from '../../../utils/common/fetchRequest'
+import { FUNC_TYPE_DOC } from '../../../configs/constans.config'
+import { GlobalEvent } from '../../../utils/common/eventbus/eventbus.util'
+import { EVENT_DOC_FUNC_COUNT } from '../../../utils/common/eventbus/events.types'
 
 export default class FuncItem extends Component {
 
@@ -21,15 +24,17 @@ export default class FuncItem extends Component {
     let { funcObj } = this.props
     if (!isObjEmpty(funcObj.countUrl)) {
       fetchGet(funcObj.countUrl).then(response => {
-        funcObj.sup = response.data || 100
-        this.render()
+        funcObj.sup = response.data
+        this.props.onFuncDataChange && this.props.onFuncDataChange(funcObj)
+        if (funcObj.funcType === FUNC_TYPE_DOC) {
+          GlobalEvent.emit(EVENT_DOC_FUNC_COUNT, this, funcObj)
+        }
       })
     }
   }
 
   shouldComponentUpdate (nextProps, nextState, nextContext) {
-    console.log('rm', nextProps)
-    // return nextProps.someData !== this.state.someData
+    return true
   }
 
   componentWillUnmount () {
@@ -38,7 +43,6 @@ export default class FuncItem extends Component {
 
   render () {
     let { funcObj, operation, sup } = this.props
-
     return (
       funcObj &&
       <div
@@ -49,8 +53,8 @@ export default class FuncItem extends Component {
                src={funcObj.img}/>
           <span className='func-func-text'>{funcObj.name}</span>
           {
-            (sup || funcObj.sup) &&
-            <sup className='func-func-sup'>{sup || funcObj.sup}</sup>
+            (sup || funcObj.sup) ?
+              <sup className='func-func-sup'>{sup || funcObj.sup}</sup> : ''
           }
         </div>
         {
@@ -66,15 +70,13 @@ export default class FuncItem extends Component {
   }
 
   onFuncClick = () => {
+    const { funcObj } = this.props
     this.props.onFuncClick &&
-    this.props.onFuncClick(this.props.funcObj)
+    this.props.onFuncClick(funcObj)
   }
 
   onOperationClick = () => {
-    const { funcObj, operation } = this.props
-    // if (operation === FUNC_OPERATION_ADD_DISABLE) {
-    //   return
-    // }
+    const { funcObj } = this.props
     this.props.onOperationClick &&
     this.props.onOperationClick(funcObj)
   }

+ 49 - 8
uas-office-web/uas-mobile/src/components/common/mainHeader/MainHeader.jsx

@@ -7,13 +7,24 @@ import React, { Component } from 'react'
 import FuncItem from '../func/FuncItem'
 import { withRouter } from 'react-router-dom'
 import { API } from '../../../configs/api.config'
+import { connect } from 'react-redux'
+import { refreshMainState } from '../../../redux/actions/mainState'
+import { freshHomeState } from '../../../redux/actions/homeState'
+import { GlobalEvent } from '../../../utils/common/eventbus/eventbus.util'
 
 class MainHeader extends Component {
 
   constructor () {
     super()
 
-    this.state = {}
+    this.state = {
+      homeHeaderIcon: [
+        { 'name': '我的日程', countUrl: API.APPCOMMON_COUNT + 'dailyTask.action' },
+        { 'name': '待审批', countUrl: API.APPCOMMON_COUNT + 'processToDo.action' },
+        { 'name': '我的待办', countUrl: API.APPCOMMON_COUNT + 'taskToDo.action' },
+        { 'name': '我的订阅' },
+      ],
+    }
   }
 
   componentDidMount () {
@@ -25,18 +36,19 @@ class MainHeader extends Component {
   }
 
   render () {
-    let homeHeaderIcon = [
-      { 'name': '我的日程', countUrl: API.APPCOMMON_COUNT + 'dailyTask.action' },
-      { 'name': '待审批', countUrl: API.APPCOMMON_COUNT + 'processToDo.action' },
-      { 'name': '我的待办', countUrl: API.APPCOMMON_COUNT + 'taskToDo.action' },
-      { 'name': '我的订阅' },
-    ]
+    const { mainState } = this.props
+    let { homeHeaderIcon } = this.state
+    homeHeaderIcon[0].sup = mainState.dailyCount
+    homeHeaderIcon[1].sup = mainState.processCount
+    homeHeaderIcon[2].sup = mainState.taskCount
+
     let homeHeaderList = []
     homeHeaderIcon.forEach((item, index) => {
       homeHeaderList.push(
         <FuncItem
           funcObj={item}
           onFuncClick={this.onFuncClick.bind(this)}
+          onFuncDataChange={this.onFuncDataChange.bind(this)}
           key={index}/>,
       )
     })
@@ -56,6 +68,35 @@ class MainHeader extends Component {
       this.props.history.push('/schedulePage')
     }
   }
+
+  onFuncDataChange = (funcObj) => {
+    const count = funcObj.sup
+    if (funcObj.name === '我的日程') {
+      refreshMainState({
+        dailyCount: count,
+      })
+    } else if (funcObj.name === '待审批') {
+      refreshMainState({
+        processCount: count,
+      })
+    } else if (funcObj.name === '待办任务') {
+      refreshMainState({
+        taskCount: count,
+      })
+    }
+    const { mainState } = this.props
+    const dailyCount = parseInt(mainState.dailyCount)
+    const processCount = parseInt(mainState.processCount)
+    const taskCount = parseInt(mainState.taskCount)
+
+    freshHomeState({
+      mainCount: dailyCount + processCount + taskCount,
+    })
+  }
 }
 
-export default withRouter(MainHeader)
+let mapStateToProps = (state) => ({
+  mainState: state.mainState,
+})
+
+export default connect(mapStateToProps)(withRouter(MainHeader))

+ 2 - 1
uas-office-web/uas-mobile/src/configs/api.config.js

@@ -5,7 +5,8 @@
 
 export const _host = window.location.origin
   && 'http://usoft.f3322.net:10007/uas'
-  && 'http://10.1.7.104:8080/ERP'
+  && 'http://10.1.7.104:8080/ERP'//吴炳
+  && 'http://10.1.7.44:8081/erp'//吴雨骁
 
 export const _baseURL = _host + (process.env.REACT_APP_ROUTER_BASE_NAME || '')
 

+ 7 - 0
uas-office-web/uas-mobile/src/configs/constans.config.js

@@ -17,5 +17,12 @@ export const FUNC_OPERATION_CANCEL = 'uas-cancel'
 export const FUNC_OPERATION_ADD = 'uas-select'
 export const FUNC_OPERATION_ADD_DISABLE = 'uas-select-disable'
 
+/**
+ * 菜单类型标识
+ */
+export const FUNC_TYPE_DOC = 'FUNC_TYPE_DOC'
+export const FUNC_TYPE_REPORT = 'FUNC_TYPE_REPORT'
+
+
 
 

+ 0 - 29
uas-office-web/uas-mobile/src/pages/private/homePage/DocRoot.jsx

@@ -7,14 +7,6 @@ import React, { Component } from 'react'
 import { connect } from 'react-redux'
 import { isObjEmpty } from '../../../utils/common/common.util'
 import FuncGroup from '../../../components/common/func/FuncGroup'
-import { fetchPostObj } from '../../../utils/common/fetchRequest'
-import { API } from '../../../configs/api.config'
-import { Toast } from 'antd-mobile'
-import { message } from 'antd'
-import {
-  analysisDocList,
-  refreshDocList,
-} from '../../../redux/actions/docState'
 
 class DocRoot extends Component {
 
@@ -26,7 +18,6 @@ class DocRoot extends Component {
 
   componentDidMount () {
     console.log('DocRoot')
-    this.getServices()
   }
 
   componentWillUnmount () {
@@ -54,26 +45,6 @@ class DocRoot extends Component {
       </div>
     )
   }
-
-  getServices = () => {
-    Toast.loading('正在获取应用列表', 0)
-    fetchPostObj(API.APPCOMMON_GETSERVICE, {
-      kind: 'uasapp',
-    }).then(response => {
-      Toast.hide()
-      analysisDocList(response)
-    }).catch(error => {
-      Toast.hide()
-      refreshDocList({
-        docFuncGroupList: [],
-      })
-      if (typeof error === 'string') {
-        message.error(error)
-      } else {
-        message.error('应用列表获取失败')
-      }
-    })
-  }
 }
 
 let mapStateToProps = (state) => ({

+ 13 - 3
uas-office-web/uas-mobile/src/pages/private/homePage/HomePage.jsx

@@ -3,12 +3,18 @@ import { connect } from 'react-redux'
 import './home-page.less'
 import { TabBar, SearchBar } from 'antd-mobile'
 import UasIcon from '../../../configs/iconfont.conig'
-import { freshHomeState } from '../../../redux/actions/homeState'
+import {
+  freshHomeState,
+  onDocFuncCountRefresh,
+} from '../../../redux/actions/homeState'
 import MainRoot from './MainRoot'
 import ReportRoot from './ReportRoot'
 import DocRoot from './DocRoot'
 import MineRoot from './MineRoot'
 import { clearListState } from '../../../redux/actions/listState'
+import { GlobalEvent } from '../../../utils/common/eventbus/eventbus.util'
+import { EVENT_DOC_FUNC_COUNT } from '../../../utils/common/eventbus/events.types'
+import { requestServices } from '../../../utils/private/services.request'
 
 /**
  * Created by RaoMeng on 2020/11/9
@@ -28,6 +34,11 @@ class HomePage extends Component {
   componentDidMount () {
     document.title = 'UAS系统'
     clearListState()
+
+    //获取应用列表
+    requestServices()
+    //刷新应用红点
+    GlobalEvent.on(EVENT_DOC_FUNC_COUNT, onDocFuncCountRefresh, this)
   }
 
   componentWillUnmount () {
@@ -63,7 +74,7 @@ class HomePage extends Component {
         icon={<UasIcon type="uas-main-normal"/>}
         selectedIcon={<UasIcon type="uas-main-select"/>}
         selected={this.props.homeState.selectedTab === 0}
-        badge={100}
+        badge={this.props.homeState.mainCount}
         dot={false}
         onPress={this.onMainTabSelected}
       >
@@ -167,7 +178,6 @@ class HomePage extends Component {
    * 切换首页
    */
   onMainTabSelected = () => {
-
     freshHomeState({
       selectedTab: 0,
     })

+ 2 - 1
uas-office-web/uas-mobile/src/pages/private/homePage/MainRoot.jsx

@@ -12,6 +12,7 @@ import './main-root.less'
 import { withRouter } from 'react-router-dom'
 import FuncGroup from '../../../components/common/func/FuncGroup'
 import { isObjEmpty, isObjNull } from '../../../utils/common/common.util'
+import { requestServices } from '../../../utils/private/services.request'
 
 class MainRoot extends Component {
 
@@ -23,7 +24,7 @@ class MainRoot extends Component {
 
   componentDidMount () {
     document.title = 'UAS系统'
-    console.log('MainRoot', this.props.docState)
+    console.log('MainRoot')
   }
 
   componentWillUnmount () {

+ 2 - 0
uas-office-web/uas-mobile/src/redux/actions/docState.js

@@ -6,6 +6,7 @@
 import store from '../store/store'
 import { CLEAR_DOC_STATE, REFRESH_DOC_LIST } from '../constants/actionTypes'
 import { isObjEmpty } from '../../utils/common/common.util'
+import { FUNC_TYPE_DOC } from '../../configs/constans.config'
 
 /**
  * 保存列表状态
@@ -58,6 +59,7 @@ export const analysisDocList = (response) => {
               countUrl: childItem.url && childItem.url.counturl,
               groupIndex: groupIndex,
               childIndex: childIndex,
+              funcType: FUNC_TYPE_DOC,
             }
             docFuncList.push(docFunc)
           })

+ 13 - 3
uas-office-web/uas-mobile/src/redux/actions/homeState.js

@@ -1,6 +1,6 @@
 /**
  * Created by RaoMeng on 2020/11/9
- * Desc: 页数据处理
+ * Desc: 页数据处理
  */
 import store from '../store/store'
 import {
@@ -10,7 +10,7 @@ import {
 
 /**
  * Created by RaoMeng on 2020/11/9
- * Desc: 刷新页状态
+ * Desc: 刷新页状态
  */
 export const freshHomeState = (data) => {
   return store.dispatch({
@@ -20,7 +20,7 @@ export const freshHomeState = (data) => {
 }
 
 /**
- * 清除页状态
+ * 清除页状态
  * @returns {Function}
  */
 export const clearHomeState = () => {
@@ -28,3 +28,13 @@ export const clearHomeState = () => {
     type: CLEAR_HOME_STATE,
   })
 }
+
+/**
+ * 刷新应用红点
+ */
+export const onDocFuncCountRefresh = (funcObj) => {
+  return store.dispatch({
+    type: FRESH_HOME_STATE,
+    funcObj,
+  })
+}

+ 37 - 0
uas-office-web/uas-mobile/src/redux/actions/mainState.js

@@ -0,0 +1,37 @@
+/**
+ * Created by RaoMeng on 2020/12/2
+ * Desc: 首页数据处理
+ */
+import store from '../store/store'
+import {
+  CLEAR_MAIN_STATE,
+  FRESH_MAIN_STATE,
+} from '../constants/actionTypes'
+import { GlobalEvent } from '../../utils/common/eventbus/eventbus.util'
+
+/**
+ * Created by RaoMeng on 2020/11/9
+ * Desc: 刷新首页状态
+ */
+export const refreshMainState = (data) => {
+  return store.dispatch({
+    type: CLEAR_MAIN_STATE,
+    ...data,
+  })
+}
+
+/**
+ * 清除首页状态
+ * @returns {Function}
+ */
+export const clearMainState = () => {
+  return store.dispatch({
+    type: FRESH_MAIN_STATE,
+  })
+}
+
+const test = () => {
+  GlobalEvent.on('test', (value) => {
+    console.log('raomeng', value)
+  })
+}

+ 5 - 0
uas-office-web/uas-mobile/src/redux/constants/actionTypes.js

@@ -7,6 +7,10 @@
 export const CLEAR_HOME_STATE = 'CLEAR_HOME_STATE'
 export const FRESH_HOME_STATE = 'FRESH_HOME_STATE'
 
+/**********************************首页********************************************/
+export const CLEAR_MAIN_STATE = 'CLEAR_MAIN_STATE'
+export const FRESH_MAIN_STATE = 'FRESH_MAIN_STATE'
+
 /**********************************列表********************************************/
 export const SAVE_LIST_STATE = 'SAVE_LIST_STATE'
 export const CLEAR_LIST_STATE = 'CLEAR_LIST_STATE'
@@ -14,6 +18,7 @@ export const CLEAR_LIST_STATE = 'CLEAR_LIST_STATE'
 /**********************************应用********************************************/
 export const REFRESH_DOC_LIST = 'REFRESH_DOC_LIST'
 export const CLEAR_DOC_STATE = 'CLEAR_DOC_STATE'
+export const REFRESH_DOC_COUNT = 'REFRESH_DOC_COUNT'
 
 /**********************************报表********************************************/
 export const REFRESH_REPORT_LIST = 'REFRESH_REPORT_LIST'

+ 16 - 1
uas-office-web/uas-mobile/src/redux/reducers/redDocState.js

@@ -1,7 +1,8 @@
 import {
-  CLEAR_DOC_STATE,
+  CLEAR_DOC_STATE, REFRESH_DOC_COUNT,
   REFRESH_DOC_LIST,
 } from '../constants/actionTypes'
+import { isObjEmpty } from '../../utils/common/common.util'
 
 /**
  * Created by RaoMeng on 2020/11/9
@@ -24,6 +25,20 @@ const redDocState = (state = initDocState, action) => {
         ...state,
         ...action,
       }
+    case REFRESH_DOC_COUNT:
+      const funcObj = action.funcObj
+      if (!isObjEmpty(funcObj)) {
+        let docFuncGroupList = state.docFuncGroupList
+        if (!isObjEmpty(docFuncGroupList) &&
+          !isObjEmpty(docFuncGroupList[funcObj.groupIndex])) {
+          docFuncGroupList[funcObj.groupIndex].funcList[funcObj.childIndex].sup = funcObj.sup
+        }
+        return {
+          ...state,
+          docFuncGroupList,
+        }
+      }
+      break
     case CLEAR_DOC_STATE:
       //清空应用列表数据
       return initDocState

+ 1 - 1
uas-office-web/uas-mobile/src/redux/reducers/redHomeState.js

@@ -8,8 +8,8 @@ import {
 } from '../constants/actionTypes'
 
 const initHomeState = {
+  mainCount: 0,
   selectedTab: 0,
-
 }
 
 const redHomeState = (state = initHomeState, action) => {

+ 16 - 2
uas-office-web/uas-mobile/src/redux/reducers/redMainState.js

@@ -1,9 +1,15 @@
+import { FRESH_MAIN_STATE, CLEAR_MAIN_STATE } from '../constants/actionTypes'
+
 /**
  * Created by RaoMeng on 2020/11/9
  * Desc: 主页数据缓存
  */
 
-const initMainState = {}
+const initMainState = {
+  dailyCount: 0,
+  processCount: 0,
+  taskCount: 0,
+}
 
 const redMainState = (state = initMainState, action) => {
   if (action === undefined) {
@@ -11,7 +17,15 @@ const redMainState = (state = initMainState, action) => {
   }
 
   switch (action.type) {
-
+    case FRESH_MAIN_STATE:
+      //更新首页数据
+      return {
+        ...state,
+        ...action,
+      }
+    case CLEAR_MAIN_STATE:
+      //清空首页数据
+      return initMainState
     default:
       return state
   }

+ 106 - 0
uas-office-web/uas-mobile/src/utils/common/eventbus/eventbus.util.js

@@ -0,0 +1,106 @@
+/**
+ * Created by RaoMeng on 2020/12/2
+ * Desc: 全局事件响应
+ * github地址:https://github.com/tbreuss/eventbus
+ */
+export class EventBus {
+
+  constructor () {
+    this.events = {}
+  }
+
+  /**
+   * Adds listener to EventBus
+   * @param {string} type The name of the event to listen for
+   * @param {function} callback Callback to call when event was triggered
+   * @param {object} scope The scope in which the callback shall be executed
+   * @param  {...any} args Any number of args to be passed to the callback
+   */
+  on (type, callback, scope, ...args) {
+    if (typeof this.events[type] === 'undefined') { // Check if there is already event of this type registered
+      this.events[type] = [] // If not, create array for it
+    }
+    this.events[type].push({ scope, callback, args }) // Finally push new event to events array
+  }
+
+  /**
+   * Removes listener from EventBus
+   * @param {string} type The name of the event to remove
+   * @param {function} callback Callback of the event to remove
+   * @param {object} scope The scope of the to be removed event
+   */
+  off (type, callback, scope) {
+    if (typeof this.events[type] === 'undefined') { // Check if event of this type exists
+      return // If not just return
+    }
+
+    // keep all elements that aren't equal to the passed event
+    const filterFn = event => event.scope !== scope || event.callback !==
+      callback
+    this.events[type] = this.events[type].filter(filterFn)
+  }
+
+  /**
+   * Checks if the passed event is registered in the EventBus
+   * @param {string} type Type of the to be checked event
+   * @param {callback} callback Callback of the to be checked event
+   * @param {object} scope Scope of the to be checked event
+   */
+  has (type, callback, scope) {
+    if (typeof this.events[type] === 'undefined') { // Check if the passed type even exists
+      return false // If not, quit method
+    }
+
+    // If callback and scope are undefined then every registered event is match, thus any event of the type matches
+    let numOfCallbacks = this.events[type].length
+    if (callback === undefined && scope === undefined) { // If scope and callback are not defined
+      return numOfCallbacks > 0 // If there are any callbacks we can be sure it matches the passed one
+    }
+
+    const conditionFn = event => {
+      const scopeIsSame = scope ? event.scope === scope : true // Check if scope is equal to the one passed
+      const callbackIsSame = event.callback === callback // Check if callback is equal to the one passed
+      if (scopeIsSame && callbackIsSame) { // Check if current event and passed event are equal
+        return true // If so, break loop and return true
+      }
+    }
+    return this.events[type].some(conditionFn)
+  }
+
+  /**
+   * Emits an event on the EventBus
+   * @param {string} type Type of event to emit
+   * @param {object} target The caller
+   * @param {...any} args Any number of args to be passed to the callback
+   */
+  emit (type, target, ...args) {
+    if (typeof this.events[type] === 'undefined') { // Check if any event of the passed type exists
+      return // If not, quit method
+    }
+
+    let bag = { type, target }
+
+    const events = this.events[type].slice() // Little hack to clone array
+
+    for (const event of events) { // Iterate all events
+      if (event && event.callback) { // Check if callback of event is set
+        event.callback.apply(event.scope, [bag, ...args, ...event.args]) // Call callback
+      }
+    }
+  }
+
+  debug () {
+    let str = ''
+    for (const [type, events] of Object.entries(this.events)) {
+      for (const event of events) {
+        let className = event.scope && event.scope.constructor.name ||
+          'Anonymous'
+        str += `${className} listening for "${type}"\n`
+      }
+    }
+    return str
+  }
+
+}
+
+export const GlobalEvent = new EventBus()

+ 6 - 0
uas-office-web/uas-mobile/src/utils/common/eventbus/events.types.js

@@ -0,0 +1,6 @@
+/**
+ * Created by RaoMeng on 2020/12/2
+ * Desc: 全局事件type
+ */
+
+export const EVENT_DOC_FUNC_COUNT = 'EVENT_DOC_FUNC_COUNT'

+ 28 - 0
uas-office-web/uas-mobile/src/utils/private/services.request.js

@@ -0,0 +1,28 @@
+import { Toast } from 'antd-mobile'
+import { fetchPostObj } from '../common/fetchRequest'
+import { API } from '../../configs/api.config'
+import { analysisDocList, refreshDocList } from '../../redux/actions/docState'
+import { message } from 'antd'
+
+/**
+ * 获取应用列表
+ */
+export function requestServices () {
+  Toast.loading('正在获取应用列表', 0)
+  fetchPostObj(API.APPCOMMON_GETSERVICE, {
+    kind: 'uasapp',
+  }).then(response => {
+    Toast.hide()
+    analysisDocList(response)
+  }).catch(error => {
+    Toast.hide()
+    refreshDocList({
+      docFuncGroupList: [],
+    })
+    if (typeof error === 'string') {
+      message.error(error)
+    } else {
+      message.error('应用列表获取失败')
+    }
+  })
+}