Эх сурвалжийг харах

首页布局修改 工作附件bug修复 会议bug修复等

fancy 6 жил өмнө
parent
commit
797db57ca3
31 өөрчлөгдсөн 839 нэмэгдсэн , 223 устгасан
  1. 1 3
      o2android/app/build.gradle
  2. BIN
      o2android/app/libs/o2_auth_sdk-release.aar
  3. 2 2
      o2android/app/src/main/java/jiguang/chat/activity/ChatDetailActivity.java
  4. 6 1
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/O2App.kt
  5. 12 10
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceMainActivity.kt
  6. 6 2
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/meeting/apply/MeetingApplyActivity.kt
  7. 6 2
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/meeting/edit/MeetingEditActivity.kt
  8. 18 3
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/meeting/main/MeetingMainFragment.kt
  9. 300 37
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/AppFragment.kt
  10. 6 2
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/IndexFragment.kt
  11. 71 70
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainActivity.kt
  12. 1 1
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MyAppPresenter.kt
  13. 2 1
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/NewsFragment.kt
  14. 1 1
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/openim/IMPersonConfigActivity.kt
  15. 8 4
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/openim/IMTribeCreateActivity.kt
  16. 93 19
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactPickerActivity.kt
  17. 3 2
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactPickerActivityContract.kt
  18. 24 1
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactPickerActivityPresenter.kt
  19. 44 2
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactUnitAndIdentityPickerPresenter.kt
  20. 5 2
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/webview/TaskWebViewActivity.kt
  21. 1 0
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/webview/TaskWebViewContract.kt
  22. 68 0
      o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/webview/TaskWebViewPresenter.kt
  23. 111 11
      o2android/app/src/main/res/layout/fragment_main_app.xml
  24. 46 43
      o2android/app/src/main/res/layout/fragment_main_bottom_bar_image.xml
  25. 1 2
      o2android/app/src/main/res/menu/menu_my_app.xml
  26. BIN
      o2android/app/src/main/res/mipmap-xhdpi/icon_main_app.png
  27. BIN
      o2android/app/src/main/res/mipmap-xhdpi/icon_main_app_red.png
  28. BIN
      o2android/app/src/main/res/mipmap-xhdpi/icon_main_app_red_blue.png
  29. BIN
      o2android/app/src/main/res/mipmap-xhdpi/pic_jieshu.png
  30. 1 0
      o2android/app/src/main/res/values/strings.xml
  31. 2 2
      o2android/gradle.properties

+ 1 - 3
o2android/app/build.gradle

@@ -135,7 +135,7 @@ android {
                                     BAIDU_MAP_APPKEY   : project.baiduMapAppKey,
                                     BAIDU_MAP_APPKEY   : project.baiduMapAppKey,
                                     BUGLY_APPID        : project.buglyAppId]
                                     BUGLY_APPID        : project.buglyAppId]
             zipAlignEnabled true
             zipAlignEnabled true
-            minifyEnabled true     //混淆
+            minifyEnabled true
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 
 
             //apk包重命名
             //apk包重命名
@@ -216,7 +216,6 @@ dependencies {
     implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
     implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
     implementation "org.jetbrains.anko:anko-common:$anko_version"
     implementation "org.jetbrains.anko:anko-common:$anko_version"
 
 
-    //support
     implementation('com.android.support:support-v4:26.1.0') {
     implementation('com.android.support:support-v4:26.1.0') {
         force = true
         force = true
     }
     }
@@ -250,7 +249,6 @@ dependencies {
     implementation 'io.reactivex:rxjava:1.1.6'
     implementation 'io.reactivex:rxjava:1.1.6'
     implementation 'io.reactivex:rxandroid:1.2.1'
     implementation 'io.reactivex:rxandroid:1.2.1'
 
 
-    //bugly
     implementation 'com.tencent.bugly:crashreport:2.6.6'
     implementation 'com.tencent.bugly:crashreport:2.6.6'
 
 
     //极光推送
     //极光推送

BIN
o2android/app/libs/o2_auth_sdk-release.aar


+ 2 - 2
o2android/app/src/main/java/jiguang/chat/activity/ChatDetailActivity.java

@@ -17,7 +17,7 @@ import com.wugang.activityresult.library.ActivityResult;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization.ContactPickerActivity;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization.ContactPickerActivity;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.ContactPickerResult;
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.ContactPickerResult;
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.ContactPickerResultItem;
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.O2PersonPickerResultItem;
 
 
 import java.io.File;
 import java.io.File;
 import java.lang.ref.WeakReference;
 import java.lang.ref.WeakReference;
@@ -237,7 +237,7 @@ public class ChatDetailActivity extends BaseActivity {
                     if (data != null) {
                     if (data != null) {
                         ContactPickerResult result = data.getParcelableExtra(ContactPickerActivity.CONTACT_PICKED_RESULT);
                         ContactPickerResult result = data.getParcelableExtra(ContactPickerActivity.CONTACT_PICKED_RESULT);
                         if (result != null) {
                         if (result != null) {
-                            ArrayList<ContactPickerResultItem> users = result.getUsers();
+                            ArrayList<O2PersonPickerResultItem> users = result.getUsers();
                             if (users.size() != 0) {
                             if (users.size() != 0) {
                                 ArrayList<String> list = new ArrayList<>();
                                 ArrayList<String> list = new ArrayList<>();
                                 for (int i = 0; i < users.size(); i++) {
                                 for (int i = 0; i < users.size(); i++) {

+ 6 - 1
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/O2App.kt

@@ -130,7 +130,12 @@ class O2App : MultiDexApplication() {
 //  获取Application下的meta值
 //  获取Application下的meta值
     fun getAppMeta(metaName: String, default: String = "") : String {
     fun getAppMeta(metaName: String, default: String = "") : String {
         return try {
         return try {
-            packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA).metaData.getString(metaName, default)
+            if ("com.baidu.speech.APP_ID" == metaName) {
+                val appid = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA).metaData.getInt("com.baidu.speech.APP_ID")
+                ""+appid
+            }else {
+                packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA).metaData.getString(metaName, default)
+            }
         }catch (e: Exception) {
         }catch (e: Exception) {
             Log.e("O2app", "", e)
             Log.e("O2app", "", e)
             default
             default

+ 12 - 10
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceMainActivity.kt

@@ -12,6 +12,8 @@ import android.view.MenuItem
 import kotlinx.android.synthetic.main.activity_attendance_main.*
 import kotlinx.android.synthetic.main.activity_attendance_main.*
 import net.muliba.changeskin.FancySkinManager
 import net.muliba.changeskin.FancySkinManager
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.approval.AttendanceAppealApprovalActivity
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.list.AttendanceListActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.setting.AttendanceLocationSettingActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.setting.AttendanceLocationSettingActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.CommonFragmentPagerAdapter
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.CommonFragmentPagerAdapter
@@ -81,16 +83,16 @@ class AttendanceMainActivity : BaseMVPActivity<AttendanceMainContract.View, Atte
 
 
     override fun onOptionsItemSelected(item: MenuItem?): Boolean {
     override fun onOptionsItemSelected(item: MenuItem?): Boolean {
         return when(item?.itemId) {
         return when(item?.itemId) {
-//            R.id.menu_attendance_list -> {
-//                XLog.debug("click menu attendance list")
-//                go<AttendanceListActivity>()
-//                true
-//            }
-//            R.id.menu_attendance_appeal_approval -> {
-//                XLog.debug("click menu attendance approval list")
-//                go<AttendanceAppealApprovalActivity>()
-//                true
-//            }
+            R.id.menu_attendance_list -> {
+                XLog.debug("click menu attendance list")
+                go<AttendanceListActivity>()
+                true
+            }
+            R.id.menu_attendance_appeal_approval -> {
+                XLog.debug("click menu attendance approval list")
+                go<AttendanceAppealApprovalActivity>()
+                true
+            }
             R.id.menu_attendance_location_setting -> {
             R.id.menu_attendance_location_setting -> {
                 XLog.debug("click menu attendance location setting")
                 XLog.debug("click menu attendance location setting")
                 go<AttendanceLocationSettingActivity>()
                 go<AttendanceLocationSettingActivity>()

+ 6 - 2
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/meeting/apply/MeetingApplyActivity.kt

@@ -390,8 +390,12 @@ class MeetingApplyActivity : BaseMVPActivity<MeetingApplyContract.View, MeetingA
                     if (invitePersonAdd == t) {
                     if (invitePersonAdd == t) {
                         nameTv.text = t
                         nameTv.text = t
                     } else {
                     } else {
-                        nameTv.tag = t
-                        mPresenter.asyncLoadPersonName(nameTv, t!!)
+                        if (t != null && t.contains("@")) {
+                            nameTv.text = t.split("@").first()
+                        }else {
+                            nameTv.text = t
+                        }
+//                        mPresenter.asyncLoadPersonName(nameTv, t!!)
                     }
                     }
                 }
                 }
             }
             }

+ 6 - 2
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/meeting/edit/MeetingEditActivity.kt

@@ -252,8 +252,12 @@ class MeetingEditActivity : BaseMVPActivity<MeetingEditContract.View, MeetingEdi
                     if(invitePersonAdd==t){
                     if(invitePersonAdd==t){
                         nameTv.text = t
                         nameTv.text = t
                     }else{
                     }else{
-                        nameTv.tag = t
-                        mPresenter.asyncLoadPersonName(nameTv, t!!)
+                        if (t != null && t.contains("@")) {
+                            nameTv.text = t.split("@").first()
+                        }else {
+                            nameTv.text = t
+                        }
+//                        mPresenter.asyncLoadPersonName(nameTv, t!!)
                     }
                     }
                 }
                 }
             }
             }

+ 18 - 3
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/meeting/main/MeetingMainFragment.kt

@@ -180,9 +180,10 @@ class MeetingMainFragment : BaseMVPViewPagerFragment<MeetingMainFragmentContract
         if (list.size == 1) {
         if (list.size == 1) {
             val identifyId = list[0].distinguishedName
             val identifyId = list[0].distinguishedName
             val processId = meetingConfig?.process?.id
             val processId = meetingConfig?.process?.id
-            if (TextUtils.isEmpty(processId)) {
+            if (!TextUtils.isEmpty(processId)) {
                 mPresenter.startProcess("", identifyId, processId!!)
                 mPresenter.startProcess("", identifyId, processId!!)
             }else {
             }else {
+                hideLoadingDialog()
                 XToast.toastShort(context, "流程id缺失")
                 XToast.toastShort(context, "流程id缺失")
             }
             }
 
 
@@ -195,9 +196,9 @@ class MeetingMainFragment : BaseMVPViewPagerFragment<MeetingMainFragmentContract
 
 
     override fun positiveCallback(identifyId: String) {
     override fun positiveCallback(identifyId: String) {
         identifyDialog?.dismiss()
         identifyDialog?.dismiss()
-        showLoadingDialog()
         val processId = meetingConfig?.process?.id
         val processId = meetingConfig?.process?.id
-        if (TextUtils.isEmpty(processId)) {
+        if (!TextUtils.isEmpty(processId)) {
+            showLoadingDialog()
             mPresenter.startProcess("", identifyId, processId!!)
             mPresenter.startProcess("", identifyId, processId!!)
         }else {
         }else {
             XToast.toastShort(context, "流程id缺失")
             XToast.toastShort(context, "流程id缺失")
@@ -226,6 +227,7 @@ class MeetingMainFragment : BaseMVPViewPagerFragment<MeetingMainFragmentContract
         if (TextUtils.isEmpty(processId)) {
         if (TextUtils.isEmpty(processId)) {
             activity.go<MeetingApplyActivity>()
             activity.go<MeetingApplyActivity>()
         }else {
         }else {
+            showLoadingDialog()
             mPresenter.loadCurrentPersonIdentityWithProcess(processId!!)
             mPresenter.loadCurrentPersonIdentityWithProcess(processId!!)
         }
         }
     }
     }
@@ -272,9 +274,22 @@ class MeetingMainFragment : BaseMVPViewPagerFragment<MeetingMainFragmentContract
             override fun convert(holder: CommonRecyclerViewHolder?, t: MeetingInfoJson?) {
             override fun convert(holder: CommonRecyclerViewHolder?, t: MeetingInfoJson?) {
                 val time = (t?.startTime)?.substring(11, 16) + "-" + (t?.completedTime)?.substring(11, 16)
                 val time = (t?.startTime)?.substring(11, 16) + "-" + (t?.completedTime)?.substring(11, 16)
 
 
+                val isOld = if (t?.completedTime != null) {
+                    if (DateHelper.isLessNow(t.completedTime, "yyyy-MM-dd HH:mm:ss") ) {
+                        R.mipmap.pic_jieshu
+                    }else {
+                        R.mipmap.pic_deal
+                    }
+                }else {
+                    R.mipmap.pic_deal
+                }
+
                 holder?.setText(R.id.tv_meeting_list_item_time, time)
                 holder?.setText(R.id.tv_meeting_list_item_time, time)
                         ?.setText(R.id.tv_meeting_list_item_title, t?.subject)
                         ?.setText(R.id.tv_meeting_list_item_title, t?.subject)
                         ?.setText(R.id.tv_meeting_list_item_meeting_participants, "参加人: ")
                         ?.setText(R.id.tv_meeting_list_item_meeting_participants, "参加人: ")
+                        ?.setImageViewResource(R.id.iv_meeting_list_item_deal, isOld)
+
+
 
 
 
 
                 holder?.getView<TextView>(R.id.tv_meeting_list_item_meeting_room)!!.tag = t?.id
                 holder?.getView<TextView>(R.id.tv_meeting_list_item_meeting_room)!!.tag = t?.id

+ 300 - 37
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/AppFragment.kt

@@ -1,65 +1,328 @@
 package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.main
 package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.main
 
 
+import android.support.v4.app.ActivityCompat.invalidateOptionsMenu
+import android.support.v7.widget.GridLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.helper.ItemTouchHelper
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
 import kotlinx.android.synthetic.main.fragment_main_app.*
 import kotlinx.android.synthetic.main.fragment_main_app.*
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.CommonAdapter
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.ViewHolder
+import net.muliba.changeskin.FancySkinManager
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.main.AttendanceMainActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPViewPagerFragment
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPViewPagerFragment
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.bbs.main.BBSMainActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.clouddrive.CloudDriveActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.cms.index.CMSIndexActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.meeting.main.MeetingMainActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.process.ReadCompletedListActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.process.ReadListActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.process.TaskCompletedListActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.process.TaskListActivity
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.CommonRecycleViewAdapter
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.CommonRecyclerViewHolder
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.APIAddressHelper
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.enums.ApplicationEnum
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.enums.ApplicationEnum
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.AppItemVO
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.go
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.persistence.MyAppListObject
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.imageloader.O2ImageLoaderManager
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.imageloader.O2ImageLoaderOptions
+import java.util.*
+import kotlin.collections.ArrayList
 
 
 /**
 /**
  * Created by fancy on 2017/6/9.
  * Created by fancy on 2017/6/9.
  * Copyright © 2017 O2. All rights reserved.
  * Copyright © 2017 O2. All rights reserved.
  */
  */
 
 
-class AppFragment: BaseMVPViewPagerFragment<AppContract.View, AppContract.Presenter>(), AppContract.View {
-    override var mPresenter: AppContract.Presenter = AppPresenter()
+class AppFragment: BaseMVPViewPagerFragment<MyAppContract.View,MyAppContract.Presenter>(), MyAppContract.View{
+    override var mPresenter: MyAppContract.Presenter = MyAppPresenter()
     override fun layoutResId(): Int = R.layout.fragment_main_app
     override fun layoutResId(): Int = R.layout.fragment_main_app
 
 
+    private val appBeanList = ArrayList<MyAppListObject>()
+    private val oldAppBeanList = ArrayList<MyAppListObject>()
+    private val myAppBeanList = ArrayList<MyAppListObject>()
+    private val oldMyAppBeanList = ArrayList<MyAppListObject>()
+    private var isEdit = false
+    private val itemTouchHelper = ItemTouchHelper (object : ItemTouchHelper.Callback() {
+        override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
+            // 获取触摸响应的方向   包含两个 1.拖动dragFlags 2.侧滑删除swipeFlags
+            // 代表只能是向左侧滑删除,当前可以是这样ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT
+            val swipeFlags = ItemTouchHelper.LEFT
 
 
-    val appBeanList = ArrayList<AppItemVO>()
-    val adapter: CommonAdapter<AppItemVO> by lazy {
-        object : CommonAdapter<AppItemVO>(activity, appBeanList, R.layout.item_app_list) {
-            override fun convert(holder: ViewHolder?, app: AppItemVO?) {
-                holder?.setText(R.id.app_name_id, app?.appName?:"")
-                        ?.setImageViewBackground(R.id.app_id, app?.appImg ?: R.mipmap.ic_todo_more)
+            // 拖动
+            var dragFlags = if (recyclerView.layoutManager is GridLayoutManager) {
+                // GridView 样式四个方向都可以
+                ItemTouchHelper.UP or ItemTouchHelper.LEFT or
+                        ItemTouchHelper.DOWN or ItemTouchHelper.RIGHT
+            } else {
+                // ListView 样式不支持左右,只支持上下
+                ItemTouchHelper.UP or ItemTouchHelper.DOWN
             }
             }
+
+            return makeMovementFlags(dragFlags, swipeFlags)
         }
         }
-    }
 
 
-    override fun initUI() {
-        ApplicationEnum.values().map { appBeanList.add(AppItemVO(it.appName, it.key, it.iconResId)) }
-
-        app_list_id.adapter = adapter
-        app_list_id.setOnItemClickListener { _, _, position, _ ->
-            when(appBeanList[position].appKey){
-                ApplicationEnum.TASK.key -> activity.go<TaskListActivity>()
-                ApplicationEnum.TASKCOMPLETED.key -> activity.go<TaskCompletedListActivity>()
-                ApplicationEnum.READ.key -> activity.go<ReadListActivity>()
-                ApplicationEnum.READCOMPLETED.key -> activity.go<ReadCompletedListActivity>()
-                ApplicationEnum.BBS.key -> activity.go<BBSMainActivity>()
-                ApplicationEnum.CMS.key -> activity.go<CMSIndexActivity>()
-                ApplicationEnum.YUNPAN.key -> activity.go<CloudDriveActivity>()
-                ApplicationEnum.MEETING.key -> activity.go<MeetingMainActivity>()
-                ApplicationEnum.ATTENDANCE.key -> activity.go<AttendanceMainActivity>()
+        /**
+         * 拖动的时候不断的回调方法
+         */
+        override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
+            // 获取原来的位置
+            val fromPosition = viewHolder.adapterPosition
+            // 得到目标的位置
+            val targetPosition = target.adapterPosition
+            if (fromPosition < targetPosition)
+                for (i in fromPosition until targetPosition)
+                    Collections.swap(myAppBeanList, i, i + 1)// 改变实际的数据集
+            else
+                for (i in fromPosition downTo targetPosition + 1)
+                    Collections.swap(myAppBeanList, i, i - 1)// 改变实际的数据集
+
+            myAppEditAdapter.notifyItemMoved(fromPosition, targetPosition)
+            return true
+        }
+
+        /**
+         * 侧滑删除后会回调的方法
+         */
+        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
+            // 获取当前删除的位置
+            //val position = viewHolder.adapterPosition
+            //mItems.remove(position)
+            // adapter 更新notify当前位置删除
+            //mAdapter.notifyItemRemoved(position)
+        }
+
+        /**
+         * 拖动选择状态改变回调
+         */
+        override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
+            if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
+                // ItemTouchHelper.ACTION_STATE_IDLE 看看源码解释就能理解了
+                // 侧滑或者拖动的时候背景设置为灰色
+                viewHolder!!.itemView.setBackgroundColor(FancySkinManager.instance().getColor(activity, R.color.z_color_meeting_text))
             }
             }
         }
         }
 
 
+        /**
+         * 回到正常状态的时候回调
+         */
+        override fun clearView(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder) {
+            // 正常默认状态下背景恢复默认
+            viewHolder.itemView.setBackgroundColor(0)
+            //ViewCompat.setTranslationX(viewHolder.itemView, 0f)
+            viewHolder.itemView.translationX = 0f
+        }
+    })
+
+
+
+    override fun initUI() {
+        initAllApp()
+        initMyApp()
+        //绑定拖拽事件
+        itemTouchHelper.attachToRecyclerView(my_app_recycler_view)
     }
     }
 
 
 
 
     override fun lazyLoad() {
     override fun lazyLoad() {
+        mPresenter.getAllAppList()
+        mPresenter.getMyAppList()
+    }
 
 
+    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+        inflater?.inflate(R.menu.menu_my_app,menu)
+        super.onCreateOptionsMenu(menu, inflater)
+    }
+
+    override fun onPrepareOptionsMenu(menu: Menu?) {
+        if (isEdit) {
+            menu?.findItem(R.id.menu_app_edit)?.title = "完成"
+        } else {
+            menu?.findItem(R.id.menu_app_edit)?.title = "编辑"
+        }
+        if (activity is MainActivity) {
+            (activity as MainActivity).refreshMenu()
+        }
+        super.onPrepareOptionsMenu(menu)
+    }
+
+    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+        isEdit = when (isEdit) {
+            false -> {
+                my_app_text_view.visibility = View.VISIBLE
+                edit_ll_view.visibility = View.VISIBLE
+                my_app_rv.visibility = View.GONE
+                myAppEditAdapter.notifyDataSetChanged()
+                allAppAdapter.notifyDataSetChanged()
+                true
+            }
+            true -> {
+                my_app_text_view.visibility = View.GONE
+                edit_ll_view.visibility = View.GONE
+                my_app_rv.visibility = View.VISIBLE
+                mPresenter.addAndDelMyAppList(oldMyAppBeanList, myAppBeanList)
+                false
+            }
+
+        }
+        return super.onOptionsItemSelected(item)
+    }
+
+
+    private fun initAllApp(){
+        all_app_recycler_view.layoutManager = GridLayoutManager(activity,5)
+        all_app_recycler_view.adapter = allAppAdapter
+        allAppAdapter.setOnItemClickListener { _, position ->
+            if (isEdit) {
+                if (!appBeanList[position].isClick) {
+                    appBeanList[position].isClick = true
+                    myAppBeanList.add(appBeanList[position])
+                    allAppAdapter.notifyItemChanged(position)
+                    myAppEditAdapter.notifyItemInserted(myAppBeanList.size)
+                }
+            } else {
+                IndexFragment.go(appBeanList[position].appId!!, activity, appBeanList[position].appTitle?:"")
+            }
+        }
+    }
+
+    private fun initMyApp(){
+        my_app_rv.layoutManager = GridLayoutManager(activity,9)
+        my_app_rv.adapter = myAppAdapter
+
+        my_app_recycler_view.layoutManager = GridLayoutManager(activity,5)
+        my_app_recycler_view.adapter = myAppEditAdapter
+        myAppEditAdapter.setOnItemClickListener { _, position ->
+            if (isEdit) {
+                appBeanList.forEachIndexed { index, myAppListObject ->
+                    if (myAppListObject.appId == myAppBeanList[position].appId) {
+                        myAppListObject.isClick = false
+                        allAppAdapter.notifyItemChanged(index)
+                    }
+                }
+                myAppBeanList.removeAt(position)
+                myAppEditAdapter.notifyItemRemoved(position)
+                myAppEditAdapter.notifyItemRangeChanged(position,myAppBeanList.size)
+            } else {
+                IndexFragment.go(myAppBeanList[position].appId!!,activity, myAppBeanList[position].appTitle?:"")
+            }
+        }
+    }
+
+
+    override fun setAllAppList(allList: ArrayList<MyAppListObject>) {
+        appBeanList.clear()
+        oldAppBeanList.clear()
+        appBeanList.addAll(allList)
+        oldAppBeanList.addAll(allList)
+        allAppAdapter.notifyDataSetChanged()
+    }
+
+    override fun setMyAppList(myAppList: ArrayList<MyAppListObject>) {
+        oldMyAppBeanList.clear()
+        oldMyAppBeanList.addAll(myAppList)
+        myAppBeanList.clear()
+        myAppBeanList.addAll(myAppList)
+        for (app: MyAppListObject in appBeanList) {
+            for (myApp: MyAppListObject in myAppList){
+                if (app.appId == myApp.appId) {
+                    app.isClick = true
+                    break
+                }
+            }
+        }
+        myAppAdapter.notifyDataSetChanged()
+    }
+
+    override fun addAndDelMyAppList(isSuccess: Boolean) {
+        if (isSuccess) {
+            oldMyAppBeanList.clear()
+            oldMyAppBeanList.addAll(myAppBeanList)
+            myAppAdapter.notifyDataSetChanged()
+            myAppEditAdapter.notifyDataSetChanged()
+            allAppAdapter.notifyDataSetChanged()
+        }
+    }
+
+    private val allAppAdapter: CommonRecycleViewAdapter<MyAppListObject> by lazy {
+        object : CommonRecycleViewAdapter<MyAppListObject>(activity, appBeanList, R.layout.item_all_app_list) {
+            override fun convert(holder: CommonRecyclerViewHolder?, t: MyAppListObject?) {
+                val resId = ApplicationEnum.getApplicationByKey(t?.appId)?.iconResId
+                if (resId!=null) {
+                    holder?.setImageViewResource(R.id.app_id, resId)
+                }else {
+                    if (t?.appId != null){
+                        val portalIconUrl = APIAddressHelper.instance().getPortalIconUrl(t.appId!!)
+                        val icon = holder?.getView<ImageView>(R.id.app_id)
+                        if (icon !=null) {
+                            O2ImageLoaderManager.instance().showImage(icon, portalIconUrl, O2ImageLoaderOptions(placeHolder = R.mipmap.process_default))
+                        }
+                    }
+//                    val bitmap = BitmapFactory.decodeFile(O2CustomStyle.processDefaultImagePath(this@MyAppActivity))
+//                    if (bitmap != null) {
+//                        holder?.setImageViewBitmap(R.id.app_id, bitmap)
+//                    } else {
+//                        holder?.setImageViewResource(R.id.app_id, R.mipmap.process_default)
+//                    }
+                }
+
+                holder?.setText(R.id.app_name_id,t?.appTitle)
+                if (isEdit) {
+                    val delete = holder?.getView<ImageView>(R.id.delete_app_iv)
+                    delete?.visibility = View.VISIBLE
+                    if (t!!.isClick){
+                        delete?.setImageResource(R.mipmap.icon__app_chose)
+                    } else {
+                        delete?.setImageResource(R.mipmap.icon_app_add)
+                    }
+                } else {
+                    holder?.getView<ImageView>(R.id.delete_app_iv)?.visibility = View.GONE
+                }
+            }
+        }
+    }
+
+    private val myAppEditAdapter: CommonRecycleViewAdapter<MyAppListObject> by lazy {
+        object : CommonRecycleViewAdapter<MyAppListObject>(activity, myAppBeanList, R.layout.item_all_app_list) {
+            override fun convert(holder: CommonRecyclerViewHolder?, t: MyAppListObject?) {
+                val resId = ApplicationEnum.getApplicationByKey(t?.appId)?.iconResId
+                if (resId!=null) {
+                    holder?.setImageViewResource(R.id.app_id, resId)
+                }else {
+                    if (t?.appId != null){
+                        val portalIconUrl = APIAddressHelper.instance().getPortalIconUrl(t.appId!!)
+                        val icon = holder?.getView<ImageView>(R.id.app_id)
+                        if (icon !=null) {
+                            O2ImageLoaderManager.instance().showImage(icon, portalIconUrl, O2ImageLoaderOptions(placeHolder = R.mipmap.process_default))
+                        }
+                    }
+                }
+                if (isEdit) {
+                    val delete = holder?.getView<ImageView>(R.id.delete_app_iv)
+                    delete?.visibility = View.VISIBLE
+                    delete?.setImageResource(R.mipmap.icon_app_del)
+                    val text = holder?.getView<TextView>(R.id.app_name_id)
+                    text?.visibility = View.VISIBLE
+                    text?.text = t?.appTitle
+                } else {
+                    holder?.getView<ImageView>(R.id.delete_app_iv)?.visibility = View.GONE
+                    holder?.getView<TextView>(R.id.app_name_id)?.visibility = View.GONE
+                }
+            }
+        }
+    }
+
+    private val myAppAdapter: CommonRecycleViewAdapter<MyAppListObject> by lazy {
+        object : CommonRecycleViewAdapter<MyAppListObject>(activity, oldMyAppBeanList, R.layout.item_app_mini) {
+            override fun convert(holder: CommonRecyclerViewHolder?, t: MyAppListObject?) {
+                val resId = ApplicationEnum.getApplicationByKey(t?.appId)?.iconResId
+                if (resId!=null) {
+                    holder?.setImageViewResource(R.id.app_id, resId)
+                }else {
+                    if (t?.appId != null){
+                        val portalIconUrl = APIAddressHelper.instance().getPortalIconUrl(t.appId!!)
+                        val icon = holder?.getView<ImageView>(R.id.app_id)
+                        if (icon !=null) {
+                            O2ImageLoaderManager.instance().showImage(icon, portalIconUrl, O2ImageLoaderOptions(placeHolder = R.mipmap.process_default))
+                        }
+                    }
+                }
+            }
+        }
     }
     }
 }
 }

+ 6 - 2
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/IndexFragment.kt

@@ -83,7 +83,6 @@ class IndexFragment : BaseMVPViewPagerFragment<IndexContract.View, IndexContract
                 ApplicationEnum.ATTENDANCE.key -> activity.go<AttendanceMainActivity>()
                 ApplicationEnum.ATTENDANCE.key -> activity.go<AttendanceMainActivity>()
                 ApplicationEnum.CALENDAR.key -> activity.go<CalendarMainActivity>()
                 ApplicationEnum.CALENDAR.key -> activity.go<CalendarMainActivity>()
                 ApplicationEnum.MindMap.key -> {
                 ApplicationEnum.MindMap.key -> {
-                    XLog.info("脑图")
                     activity.go<FlutterConnectActivity>(FlutterConnectActivity.startFlutterAppWithRoute(ApplicationEnum.MindMap.key))
                     activity.go<FlutterConnectActivity>(FlutterConnectActivity.startFlutterAppWithRoute(ApplicationEnum.MindMap.key))
                 }
                 }
                 ApplicationEnum.O2AI.key -> {
                 ApplicationEnum.O2AI.key -> {
@@ -105,7 +104,12 @@ class IndexFragment : BaseMVPViewPagerFragment<IndexContract.View, IndexContract
                             }
                             }
 
 
                 }
                 }
-                ALL_APP_ID -> activity.go<MyAppActivity>()
+                ALL_APP_ID -> {
+//                    activity.go<MyAppActivity>()
+                    if (activity is MainActivity) {
+                        activity.gotoApp()
+                    }
+                }
                 else -> {
                 else -> {
                     //portal 打开
                     //portal 打开
                     activity.go<PortalWebViewActivity>(PortalWebViewActivity.startPortal(id, title))
                     activity.go<PortalWebViewActivity>(PortalWebViewActivity.startPortal(id, title))

+ 71 - 70
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainActivity.kt

@@ -56,11 +56,11 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
 
 
     override var mPresenter: MainContract.Presenter = MainPresenter()
     override var mPresenter: MainContract.Presenter = MainPresenter()
 
 
-    private val fragmentList: ArrayList<Fragment> = ArrayList(4)
-    private val fragmentTitles: ArrayList<String> = ArrayList(4)
+    private val fragmentList: ArrayList<Fragment> = ArrayList(5)
+    private val fragmentTitles: ArrayList<String> = ArrayList(5)
     private val mCurrentSelectIndexKey = "mCurrentSelectIndexKey"
     private val mCurrentSelectIndexKey = "mCurrentSelectIndexKey"
-    private var mCurrentSelectIndex = 0
-    lateinit var cameraImageUri: Uri
+    private var mCurrentSelectIndex = 2
+    private lateinit var cameraImageUri: Uri
 
 
 
 
     var pictureLoaderService: PictureLoaderService? = null
     var pictureLoaderService: PictureLoaderService? = null
@@ -76,14 +76,23 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
         setTheme(R.style.XBPMTheme_NoActionBar)
         setTheme(R.style.XBPMTheme_NoActionBar)
     }
     }
     override fun afterSetContentView(savedInstanceState: Bundle?) {
     override fun afterSetContentView(savedInstanceState: Bundle?) {
-        mCurrentSelectIndex = savedInstanceState?.getInt(mCurrentSelectIndexKey, 0) ?: 0
+        mCurrentSelectIndex = savedInstanceState?.getInt(mCurrentSelectIndexKey, 2) ?: 2
         setupToolBar(getString(R.string.app_name))
         setupToolBar(getString(R.string.app_name))
 
 
         XLog.info("main activity init..............")
         XLog.info("main activity init..............")
         val indexType = O2SDKManager.instance().prefs().getString(O2CustomStyle.INDEX_TYPE_PREF_KEY, O2CustomStyle.INDEX_TYPE_DEFAULT)
         val indexType = O2SDKManager.instance().prefs().getString(O2CustomStyle.INDEX_TYPE_PREF_KEY, O2CustomStyle.INDEX_TYPE_DEFAULT)
         val indexId = O2SDKManager.instance().prefs().getString(O2CustomStyle.INDEX_ID_PREF_KEY, "")
         val indexId = O2SDKManager.instance().prefs().getString(O2CustomStyle.INDEX_ID_PREF_KEY, "")
         XLog.info("main activity isIndex $indexType..............")
         XLog.info("main activity isIndex $indexType..............")
-        var indexName = getString(R.string.tab_todo)
+
+        val newsFragment = NewsFragment()
+        fragmentList.add(newsFragment)
+        fragmentTitles.add(getString(R.string.tab_message))
+
+        val contactFragment = NewContactFragment()
+        fragmentList.add(contactFragment)
+        fragmentTitles.add(getString(R.string.tab_contact))
+
+        val indexName = getString(R.string.tab_todo)
         if (indexType == O2CustomStyle.INDEX_TYPE_DEFAULT || TextUtils.isEmpty(indexId)) {
         if (indexType == O2CustomStyle.INDEX_TYPE_DEFAULT || TextUtils.isEmpty(indexId)) {
             val indexFragment = IndexFragment()
             val indexFragment = IndexFragment()
             fragmentList.add(indexFragment)
             fragmentList.add(indexFragment)
@@ -93,22 +102,17 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
             fragmentList.add(indexFragment)
             fragmentList.add(indexFragment)
             fragmentTitles.add(indexName)
             fragmentTitles.add(indexName)
         }
         }
-        mPresenter.checkO2AIEnable()
 
 
-        val newsFragment = NewsFragment()
-        fragmentList.add(newsFragment)
-        fragmentTitles.add(getString(R.string.tab_message))
-
-        val contactFragment = NewContactFragment()
-        fragmentList.add(contactFragment)
-        fragmentTitles.add(getString(R.string.tab_contact))
+        val appFragment = AppFragment()
+        fragmentList.add(appFragment)
+        fragmentTitles.add(getString(R.string.tab_app))
 
 
         val settingFragment = SettingsFragment()
         val settingFragment = SettingsFragment()
         fragmentList.add(settingFragment)
         fragmentList.add(settingFragment)
         fragmentTitles.add(getString(R.string.tab_settings))
         fragmentTitles.add(getString(R.string.tab_settings))
 
 
         content_fragmentView_id.adapter = adapter
         content_fragmentView_id.adapter = adapter
-        content_fragmentView_id.offscreenPageLimit = 4
+        content_fragmentView_id.offscreenPageLimit = 5
         content_fragmentView_id.addOnPageChangeListener {
         content_fragmentView_id.addOnPageChangeListener {
             onPageSelected { position ->
             onPageSelected { position ->
                 selectTab(position)
                 selectTab(position)
@@ -117,6 +121,7 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
 
 
         fab_main_start_ai.setOnClickListener(this)
         fab_main_start_ai.setOnClickListener(this)
         icon_main_bottom_news.setOnClickListener(this)
         icon_main_bottom_news.setOnClickListener(this)
+        icon_main_bottom_app.setOnClickListener(this)
 //        icon_main_bottom_index_blur.setOnClickListener(this)
 //        icon_main_bottom_index_blur.setOnClickListener(this)
         icon_main_bottom_index.setOnClickListener(this)
         icon_main_bottom_index.setOnClickListener(this)
         icon_main_bottom_contact.setOnClickListener(this)
         icon_main_bottom_contact.setOnClickListener(this)
@@ -131,13 +136,13 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
 
 
     override fun o2AIEnable(enable: Boolean) {
     override fun o2AIEnable(enable: Boolean) {
         XLog.info("O2AI enable: $enable")
         XLog.info("O2AI enable: $enable")
-        if (enable) {
-            icon_main_bottom_center_gap.visible()
-            fab_main_start_ai.visible()
-        }else {
-            icon_main_bottom_center_gap.gone()
-            fab_main_start_ai.gone()
-        }
+//        if (enable) {
+//            icon_main_bottom_center_gap.visible()
+//            fab_main_start_ai.visible()
+//        }else {
+//            icon_main_bottom_center_gap.gone()
+//            fab_main_start_ai.gone()
+//        }
     }
     }
 
 
     override fun onResume() {
     override fun onResume() {
@@ -188,8 +193,8 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
 
 
     override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
     override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
         if (keyCode == KeyEvent.KEYCODE_BACK) {
         if (keyCode == KeyEvent.KEYCODE_BACK) {
-            return if (mCurrentSelectIndex == 0 && fragmentList[0] is IndexPortalFragment) {
-                if ((fragmentList[0] as IndexPortalFragment).previousPage()) {
+            return if (mCurrentSelectIndex == 2 && fragmentList[2] is IndexPortalFragment) {
+                if ((fragmentList[2] as IndexPortalFragment).previousPage()) {
                     true
                     true
                 } else {
                 } else {
                     doubleClickExitHelper.onKeyDown(keyCode, event)
                     doubleClickExitHelper.onKeyDown(keyCode, event)
@@ -223,7 +228,7 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
                     data?.let {
                     data?.let {
                         val url = it.extras.getString("clipAvatarFilePath")
                         val url = it.extras.getString("clipAvatarFilePath")
                         XLog.debug("back Myinfo avatar uri : $url ")
                         XLog.debug("back Myinfo avatar uri : $url ")
-                        if (content_fragmentView_id.currentItem == 3) {
+                        if (content_fragmentView_id.currentItem == 3 && fragmentList[3] is MyFragment) {
                             (fragmentList[3] as MyFragment).modifyAvatar2Remote(url)
                             (fragmentList[3] as MyFragment).modifyAvatar2Remote(url)
                         }
                         }
 
 
@@ -235,20 +240,30 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
 
 
     override fun onClick(v: View?) {
     override fun onClick(v: View?) {
         when (v?.id) {
         when (v?.id) {
+//            R.id.icon_main_bottom_index_blur -> selectTab(0)
+            R.id.icon_main_bottom_news -> selectTab(0)
+            R.id.icon_main_bottom_contact -> selectTab(1)
             R.id.icon_main_bottom_index -> {
             R.id.icon_main_bottom_index -> {
-                if (fragmentList[0] is IndexPortalFragment) {
-                    (fragmentList[0] as IndexPortalFragment).loadWebview()
+                if (fragmentList[2] is IndexPortalFragment) {
+                    (fragmentList[2] as IndexPortalFragment).loadWebview()
                 }
                 }
-                selectTab(0)
+                selectTab(2)
             }
             }
-//            R.id.icon_main_bottom_index_blur -> selectTab(0)
-            R.id.icon_main_bottom_news -> selectTab(1)
-            R.id.icon_main_bottom_contact -> selectTab(2)
-            R.id.icon_main_bottom_setting -> selectTab(3)
+            R.id.icon_main_bottom_app -> selectTab(3)
+            R.id.icon_main_bottom_setting -> selectTab(4)
             R.id.fab_main_start_ai -> startAi()
             R.id.fab_main_start_ai -> startAi()
         }
         }
     }
     }
 
 
+    //刷新ActionBar的菜单按钮 应用页面使用
+    fun refreshMenu() {
+        invalidateOptionsMenu()
+    }
+    //跳转到应用页面 首页使用
+    fun gotoApp() {
+        selectTab(3)
+    }
+
     private fun startAi() {
     private fun startAi() {
         IndexFragment.go(ApplicationEnum.O2AI.key, this)
         IndexFragment.go(ApplicationEnum.O2AI.key, this)
     }
     }
@@ -306,7 +321,16 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
     private fun changeBottomIcon(i: Int) {
     private fun changeBottomIcon(i: Int) {
         resetBottomBtnAlpha()
         resetBottomBtnAlpha()
         when (i) {
         when (i) {
+
             0 -> {
             0 -> {
+                image_icon_main_bottom_news.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_news_red))
+                tv_icon_main_bottom_news.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
+            }
+            1 -> {
+                image_icon_main_bottom_contact.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_contact_red))
+                tv_icon_main_bottom_contact.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
+            }
+            2 -> {
                 val path = O2CustomStyle.indexMenuLogoFocusImagePath(this)
                 val path = O2CustomStyle.indexMenuLogoFocusImagePath(this)
                 if (!TextUtils.isEmpty(path)) {
                 if (!TextUtils.isEmpty(path)) {
                     BitmapUtil.setImageFromFile(path!!, icon_main_bottom_index)
                     BitmapUtil.setImageFromFile(path!!, icon_main_bottom_index)
@@ -314,20 +338,11 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
                     icon_main_bottom_index.setImageResource(R.mipmap.index_bottom_menu_logo_focus)
                     icon_main_bottom_index.setImageResource(R.mipmap.index_bottom_menu_logo_focus)
                 }
                 }
             }
             }
-            1 -> {
-                image_icon_main_bottom_news.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_news_red))
-                tv_icon_main_bottom_news.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
-            }
-            2 -> {
-                image_icon_main_bottom_contact.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_contact_red))
-                tv_icon_main_bottom_contact.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
-            }
-//
-//            3 -> {
-//                image_icon_main_bottom_my.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_my_red))
-//                tv_icon_main_bottom_my.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
-//            }
             3 -> {
             3 -> {
+                image_icon_main_bottom_app.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_app_red))
+                tv_icon_main_bottom_app.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
+            }
+            4 -> {
                 image_icon_main_bottom_setting.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_setting_red))
                 image_icon_main_bottom_setting.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_setting_red))
                 tv_icon_main_bottom_setting.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
                 tv_icon_main_bottom_setting.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_primary))
             }
             }
@@ -338,12 +353,11 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
     private fun changePageView(position: Int) {
     private fun changePageView(position: Int) {
         content_fragmentView_id.setCurrentItem(position, false)
         content_fragmentView_id.setCurrentItem(position, false)
         when (position) {
         when (position) {
-            0 -> setIndexToolBar()
-            1 -> resetToolBar(getString(R.string.tab_message))
-            2 -> resetToolBar(getString(R.string.tab_contact))
-
-//            3 -> setIndexToolBar()
-            3 -> resetToolBar(getString(R.string.tab_settings))
+            0 -> resetToolBar(getString(R.string.tab_message))
+            1 -> resetToolBar(getString(R.string.tab_contact))
+            2 -> setIndexToolBar()
+            3 -> resetToolBar(getString(R.string.tab_contact))
+            4 -> resetToolBar(getString(R.string.tab_settings))
         }
         }
 
 
     }
     }
@@ -359,31 +373,18 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
     }
     }
 
 
     private fun resetBottomBtnAlpha() {
     private fun resetBottomBtnAlpha() {
+        image_icon_main_bottom_news.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_news))
+        tv_icon_main_bottom_news.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
+        image_icon_main_bottom_contact.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_contact))
+        tv_icon_main_bottom_contact.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
         val path = O2CustomStyle.indexMenuLogoBlurImagePath(this)
         val path = O2CustomStyle.indexMenuLogoBlurImagePath(this)
         if (!TextUtils.isEmpty(path)) {
         if (!TextUtils.isEmpty(path)) {
             BitmapUtil.setImageFromFile(path!!, icon_main_bottom_index)
             BitmapUtil.setImageFromFile(path!!, icon_main_bottom_index)
         }else {
         }else {
             icon_main_bottom_index.setImageResource(R.mipmap.index_bottom_menu_logo_blur)
             icon_main_bottom_index.setImageResource(R.mipmap.index_bottom_menu_logo_blur)
         }
         }
-//        icon_main_bottom_index_blur.visible()
-//        image_icon_main_bottom_index_blur.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_index_blur))
-//        tv_icon_main_bottom_index_blur.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
-        image_icon_main_bottom_news.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_news))
-        tv_icon_main_bottom_news.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
-        image_icon_main_bottom_contact.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_contact))
-        tv_icon_main_bottom_contact.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
-//        if (TextUtils.isEmpty(FancySkinManager.instance().currentSkinPath()) && TextUtils.isEmpty(FancySkinManager.instance().currentSkinSuffix())) { //没有皮肤资源
-//            val bitmap = BitmapFactory.decodeFile(O2CustomStyle.indexMenuLogoBlurImagePath(this))
-//            if (bitmap==null) {
-//                icon_main_bottom_index.setImageResource(R.mipmap.index_bottom_menu_logo_blur)
-//            }else {
-//                icon_main_bottom_index.setImageBitmap(bitmap)
-//            }
-//        }else {
-//            icon_main_bottom_index.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_index_logo))
-//        }
-//        image_icon_main_bottom_my.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_my))
-//        tv_icon_main_bottom_my.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
+        image_icon_main_bottom_app.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_app))
+        tv_icon_main_bottom_app.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
         image_icon_main_bottom_setting.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_setting))
         image_icon_main_bottom_setting.setImageDrawable(FancySkinManager.instance().getDrawable(this, R.mipmap.icon_main_setting))
         tv_icon_main_bottom_setting.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
         tv_icon_main_bottom_setting.setTextColor(FancySkinManager.instance().getColor(this, R.color.z_color_text_primary))
     }
     }

+ 1 - 1
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MyAppPresenter.kt

@@ -45,7 +45,7 @@ class MyAppPresenter : BasePresenterImpl<MyAppContract.View>(), MyAppContract.Pr
                         result.add(obj)
                         result.add(obj)
                     }
                     }
                     if (result.isEmpty()) {
                     if (result.isEmpty()) {
-                        var url = O2SDKManager.instance().prefs().getString(O2.PRE_CENTER_URL_KEY, "")
+                        val url = O2SDKManager.instance().prefs().getString(O2.PRE_CENTER_URL_KEY, "")
                         getApiService(mView?.getContext(), url)
                         getApiService(mView?.getContext(), url)
                                 ?.getCustomStyle()
                                 ?.getCustomStyle()
                                 ?.subscribeOn(Schedulers.immediate())
                                 ?.subscribeOn(Schedulers.immediate())

+ 2 - 1
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/NewsFragment.kt

@@ -27,6 +27,7 @@ import cn.jpush.im.android.eventbus.EventBus
 import jiguang.chat.activity.ChatActivity
 import jiguang.chat.activity.ChatActivity
 import kotlinx.android.synthetic.main.fragment_main_news.*
 import kotlinx.android.synthetic.main.fragment_main_news.*
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2App
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2App
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2SDKManager
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPViewPagerFragment
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPViewPagerFragment
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.openim.IMTribeCreateActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.openim.IMTribeCreateActivity
@@ -217,7 +218,7 @@ class NewsFragment : BaseMVPViewPagerFragment<NewsContract.View, NewsContract.Pr
                         val bundle = ContactPickerActivity.startPickerBundle(
                         val bundle = ContactPickerActivity.startPickerBundle(
                                 arrayListOf("personPicker"),
                                 arrayListOf("personPicker"),
                                 multiple = true,
                                 multiple = true,
-                                initUserList = arrayListOf(JMessageClient.getMyInfo().userName)
+                                initUserList = arrayListOf(O2SDKManager.instance().distinguishedName)
                         )
                         )
                         (activity as MainActivity).contactPicker(bundle) { result ->
                         (activity as MainActivity).contactPicker(bundle) { result ->
                             if (result != null) {
                             if (result != null) {

+ 1 - 1
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/openim/IMPersonConfigActivity.kt

@@ -48,7 +48,7 @@ class IMPersonConfigActivity : BaseMVPActivity<IMPersonConfigContract.View, IMPe
             goThenKill<PersonActivity>(PersonActivity.startBundleData(distinguishedName))
             goThenKill<PersonActivity>(PersonActivity.startBundleData(distinguishedName))
         }
         }
         rl_im_person_tribe_create_btn.setOnClickListener {
         rl_im_person_tribe_create_btn.setOnClickListener {
-            val personList = arrayListOf(O2SDKManager.instance().cId, personId)
+            val personList = arrayListOf(O2SDKManager.instance().distinguishedName, personId)
             val bundle = ContactPickerActivity.startPickerBundle(
             val bundle = ContactPickerActivity.startPickerBundle(
                     arrayListOf("personPicker"),
                     arrayListOf("personPicker"),
                     multiple = true,
                     multiple = true,

+ 8 - 4
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/openim/IMTribeCreateActivity.kt

@@ -79,7 +79,7 @@ class IMTribeCreateActivity : BaseMVPActivity<IMTribeCreateContract.View, IMTrib
                     }
                     }
                 }
                 }
                 else -> {
                 else -> {
-                    if (personList[position] != O2SDKManager.instance().cId) {
+                    if (personList[position] != O2SDKManager.instance().distinguishedName) {
                         personList.removeAt(position)
                         personList.removeAt(position)
                         personAdapter.notifyDataSetChanged()
                         personAdapter.notifyDataSetChanged()
                     }
                     }
@@ -181,7 +181,7 @@ class IMTribeCreateActivity : BaseMVPActivity<IMTribeCreateContract.View, IMTrib
                         avatar.setImageResource(R.mipmap.icon_add_people)
                         avatar.setImageResource(R.mipmap.icon_add_people)
                         delete?.visibility = View.GONE
                         delete?.visibility = View.GONE
                     } else {
                     } else {
-                        if (t == O2SDKManager.instance().cId) {
+                        if (t == O2SDKManager.instance().distinguishedName) {
                             delete?.visibility = View.GONE
                             delete?.visibility = View.GONE
                         }
                         }
                         val url = APIAddressHelper.instance().getPersonAvatarUrlWithId(t!!)
                         val url = APIAddressHelper.instance().getPersonAvatarUrlWithId(t!!)
@@ -193,8 +193,12 @@ class IMTribeCreateActivity : BaseMVPActivity<IMTribeCreateContract.View, IMTrib
                     if (invitePersonAdd == t) {
                     if (invitePersonAdd == t) {
                         nameTv.text = t
                         nameTv.text = t
                     } else {
                     } else {
-                        nameTv.tag = t
-                        mPresenter.asyncLoadPersonName(nameTv, t!!)
+                        if (t != null && t.contains("@")) {
+                            nameTv.text = t.split("@").first()
+                        }else {
+                            nameTv.text = t
+                        }
+//                        mPresenter.asyncLoadPersonName(nameTv, t!!)
                     }
                     }
                 }
                 }
             }
             }

+ 93 - 19
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactPickerActivity.kt

@@ -10,9 +10,8 @@ import android.view.MenuItem
 import kotlinx.android.synthetic.main.snippet_appbarlayout_tablayout_toolbar.*
 import kotlinx.android.synthetic.main.snippet_appbarlayout_tablayout_toolbar.*
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.R
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPActivity
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPActivity
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.ContactPickerResult
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.ContactPickerResultItem
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.NewContactListVO
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.person.PersonJson
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.*
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XToast
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XToast
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.gone
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.gone
@@ -20,6 +19,7 @@ import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.replaceFragmentSafe
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.visible
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.visible
 
 
 class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View, ContactPickerActivityContract.Presenter>(), ContactPickerActivityContract.View {
 class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View, ContactPickerActivityContract.Presenter>(), ContactPickerActivityContract.View {
+
     override var mPresenter: ContactPickerActivityContract.Presenter = ContactPickerActivityPresenter()
     override var mPresenter: ContactPickerActivityContract.Presenter = ContactPickerActivityPresenter()
 
 
 
 
@@ -73,10 +73,10 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
     private var duty: ArrayList<String> = ArrayList()//人员职责
     private var duty: ArrayList<String> = ArrayList()//人员职责
 
 
 
 
-    private val mSelectDepartments: ArrayList<ContactPickerResultItem> = arrayListOf()
-    private val mSelectIdentities: ArrayList<ContactPickerResultItem> = arrayListOf()
-    private val mSelectGroups: ArrayList<ContactPickerResultItem> = arrayListOf()
-    private val mSelectUsers: ArrayList<ContactPickerResultItem> = arrayListOf()
+    private val mSelectDepartments: ArrayList<O2UnitPickerResultItem> = arrayListOf()
+    private val mSelectIdentities: ArrayList<O2IdentityPickerResultItem> = arrayListOf()
+    private val mSelectGroups: ArrayList<O2GroupPickerResultItem> = arrayListOf()
+    private val mSelectUsers: ArrayList<O2PersonPickerResultItem> = arrayListOf()
 
 
     private val fragments = ArrayList<Fragment>()
     private val fragments = ArrayList<Fragment>()
     private var currentSelect = 0
     private var currentSelect = 0
@@ -109,7 +109,8 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
             }else {
             }else {
                 it
                 it
             }
             }
-            mSelectDepartments.add(ContactPickerResultItem(name, it))
+            val unit = O2UnitPickerResultItem(name = name, distinguishedName = it)
+            mSelectDepartments.add(unit)
         }
         }
         val initIdList: ArrayList<String> = intent.extras?.getStringArrayList(PICKED_ID_ARRAY_KEY) ?: ArrayList()
         val initIdList: ArrayList<String> = intent.extras?.getStringArrayList(PICKED_ID_ARRAY_KEY) ?: ArrayList()
         initIdList.forEach {
         initIdList.forEach {
@@ -118,7 +119,8 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
             }else {
             }else {
                 it
                 it
             }
             }
-            mSelectIdentities.add(ContactPickerResultItem(name, it))
+            val identity = O2IdentityPickerResultItem(name = name, distinguishedName = it)
+            mSelectIdentities.add(identity)
         }
         }
         val initGroupList: ArrayList<String> = intent.extras?.getStringArrayList(PICKED_GROUP_ARRAY_KEY) ?: ArrayList()
         val initGroupList: ArrayList<String> = intent.extras?.getStringArrayList(PICKED_GROUP_ARRAY_KEY) ?: ArrayList()
         initGroupList.forEach {
         initGroupList.forEach {
@@ -127,7 +129,8 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
             }else {
             }else {
                 it
                 it
             }
             }
-            mSelectGroups.add(ContactPickerResultItem(name, it))
+            val group = O2GroupPickerResultItem(name = name, distinguishedName = it)
+            mSelectGroups.add(group)
         }
         }
         val initUserList: ArrayList<String> = intent.extras?.getStringArrayList(PICKED_USER_ARRAY_KEY) ?: ArrayList()
         val initUserList: ArrayList<String> = intent.extras?.getStringArrayList(PICKED_USER_ARRAY_KEY) ?: ArrayList()
         initUserList.forEach {
         initUserList.forEach {
@@ -136,7 +139,8 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
             }else {
             }else {
                 it
                 it
             }
             }
-            mSelectUsers.add(ContactPickerResultItem(name, it))
+            val user = O2PersonPickerResultItem(name = name, distinguishedName = it)
+            mSelectUsers.add(user)
         }
         }
 
 
         initView()
         initView()
@@ -191,6 +195,36 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
         return super.onKeyDown(keyCode, event)
         return super.onKeyDown(keyCode, event)
     }
     }
 
 
+    override fun setPersonInfo(info: PersonJson, type: String) {
+        if (type == "0") { //identity
+            mSelectIdentities.filter {
+                it.person == info.distinguishedName
+            }.forEach {
+                it.person = info.id
+                it.personDn = info.distinguishedName
+                it.personName = info.name
+                it.personUnique = info.unique
+            }
+        } else {
+            mSelectUsers.filter {
+                it.distinguishedName == info.distinguishedName
+            }.forEach {
+                it.id = info.id
+                it.name = info.name
+                it.unique = info.unique
+                it.distinguishedName = info.distinguishedName
+                it.employee = info.employee
+                it.genderType = info.genderType
+                it.mail = info.mail
+                it.mobile = info.mobile
+                it.officePhone = ""
+                it.qq = info.qq
+                it.weixin = info.weixin
+            }
+        }
+    }
+
+
 
 
     // 检查值是否已经包含在选中的列表中
     // 检查值是否已经包含在选中的列表中
     fun isSelectedValue(value: NewContactListVO) : Boolean {
     fun isSelectedValue(value: NewContactListVO) : Boolean {
@@ -213,10 +247,30 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
     // 删除一个选中的值
     // 删除一个选中的值
     fun removeSelectedValue(value: NewContactListVO) {
     fun removeSelectedValue(value: NewContactListVO) {
         when(value) {
         when(value) {
-            is NewContactListVO.Department -> mSelectDepartments.remove(ContactPickerResultItem(value.name, value.distinguishedName))
-            is NewContactListVO.Identity -> mSelectIdentities.remove(ContactPickerResultItem(value.name, value.distinguishedName))
-            is NewContactListVO.Group -> mSelectGroups.remove(ContactPickerResultItem(value.name, value.distinguishedName))
-            is NewContactListVO.Person -> mSelectUsers.remove(ContactPickerResultItem(value.name, value.distinguishedName))
+            is NewContactListVO.Department -> {
+                val item = mSelectDepartments.firstOrNull { it.distinguishedName == value.distinguishedName }
+                if (item != null) {
+                    mSelectDepartments.remove(item)
+                }
+            }
+            is NewContactListVO.Identity -> {
+                val item = mSelectIdentities.firstOrNull { it.distinguishedName == value.distinguishedName }
+                if (item != null) {
+                    mSelectIdentities.remove(item)
+                }
+            }
+            is NewContactListVO.Group -> {
+                val item = mSelectGroups.firstOrNull { it.distinguishedName == value.distinguishedName }
+                if (item != null) {
+                    mSelectGroups.remove(item)
+                }
+            }
+            is NewContactListVO.Person -> {
+                val item = mSelectUsers.firstOrNull { it.distinguishedName == value.distinguishedName }
+                if (item != null) {
+                    mSelectUsers.remove(item)
+                }
+            }
         }
         }
         refreshMenu()
         refreshMenu()
     }
     }
@@ -228,10 +282,30 @@ class ContactPickerActivity : BaseMVPActivity<ContactPickerActivityContract.View
             return
             return
         }
         }
         when(value) {
         when(value) {
-            is NewContactListVO.Department -> mSelectDepartments.add(ContactPickerResultItem(value.name, value.distinguishedName))
-            is NewContactListVO.Identity -> mSelectIdentities.add(ContactPickerResultItem(value.name, value.distinguishedName))
-            is NewContactListVO.Group -> mSelectGroups.add(ContactPickerResultItem(value.name, value.distinguishedName))
-            is NewContactListVO.Person -> mSelectUsers.add(ContactPickerResultItem(value.name, value.distinguishedName))
+            is NewContactListVO.Department -> {
+                val o2Unit = O2UnitPickerResultItem(value.id, value.name, value.unique,
+                        value.distinguishedName, value.typeList, value.shortName,
+                        value.level, value.levelName)
+                mSelectDepartments.add(o2Unit)
+            }
+            is NewContactListVO.Identity -> {
+                val o2Identity = O2IdentityPickerResultItem(value.id, value.name, value.unique,
+                        value.distinguishedName, value.person, value.unit, value.unitName, "", "", "",
+                        value.unitLevel, value.unitLevelName)
+                mSelectIdentities.add(o2Identity)
+                //todo 查询person信息填充进去
+                mPresenter.getPerson(value.person, "0")
+            }
+            is NewContactListVO.Group -> {
+                val o2group = O2GroupPickerResultItem(value.id, value.name, value.unique, value.distinguishedName)
+                mSelectGroups.add(o2group)
+            }
+            is NewContactListVO.Person -> {
+                val o2person = O2PersonPickerResultItem(name = value.name, distinguishedName = value.distinguishedName)
+                mSelectUsers.add(o2person)
+                //todo 查询person信息填充进去
+                mPresenter.getPerson(value.distinguishedName, "1")
+            }
         }
         }
         refreshMenu()
         refreshMenu()
     }
     }

+ 3 - 2
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactPickerActivityContract.kt

@@ -2,6 +2,7 @@ package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization
 
 
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenter
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenter
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseView
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseView
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.person.PersonJson
 
 
 /**
 /**
  * Created by fancyLou on 2019-08-20.
  * Created by fancyLou on 2019-08-20.
@@ -10,9 +11,9 @@ import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseView
 
 
 object ContactPickerActivityContract {
 object ContactPickerActivityContract {
     interface View: BaseView{
     interface View: BaseView{
-
+        fun setPersonInfo(info: PersonJson, type: String)
     }
     }
     interface Presenter: BasePresenter<View> {
     interface Presenter: BasePresenter<View> {
-
+        fun getPerson(dn: String, type: String)
     }
     }
 }
 }

+ 24 - 1
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactPickerActivityPresenter.kt

@@ -1,7 +1,11 @@
 package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization
 package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.organization
 
 
-import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenter
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenterImpl
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenterImpl
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.AndroidUtils
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.o2Subscribe
+import rx.android.schedulers.AndroidSchedulers
+import rx.schedulers.Schedulers
 
 
 /**
 /**
  * Created by fancyLou on 2019-08-20.
  * Created by fancyLou on 2019-08-20.
@@ -9,5 +13,24 @@ import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenterImpl
  */
  */
 
 
 class ContactPickerActivityPresenter: BasePresenterImpl<ContactPickerActivityContract.View>(), ContactPickerActivityContract.Presenter {
 class ContactPickerActivityPresenter: BasePresenterImpl<ContactPickerActivityContract.View>(), ContactPickerActivityContract.Presenter {
+    override fun getPerson(dn: String, type: String) {
+        XLog.debug("getPerson dn:$dn, type:$type")
+        getOrganizationAssembleControlApi(mView?.getContext())?.person(dn)
+                ?.subscribeOn(Schedulers.io())
+                ?.observeOn(AndroidSchedulers.mainThread())
+                ?.o2Subscribe {
+                    onNext {
+                        val person = it?.data
+                        if (person != null) {
+                            mView?.setPersonInfo(person, type)
+                        }else {
+                            XLog.error("没有查询到用户信息,$dn")
+                        }
+                    }
+                    onError { e, isNetworkError ->
+                        XLog.error("net: $isNetworkError", e)
+                    }
+                }
+    }
 
 
 }
 }

+ 44 - 2
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/organization/ContactUnitAndIdentityPickerPresenter.kt

@@ -5,9 +5,11 @@ import net.muliba.accounting.app.ExceptionHandler
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenterImpl
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenterImpl
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.service.OrganizationAssembleControlAlphaService
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.service.OrganizationAssembleControlAlphaService
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.identity.UnitDutyIdentityForm
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.identity.UnitDutyIdentityForm
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.person.PersonList
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.unit.UnitListForm
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.unit.UnitListForm
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.NewContactListVO
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.vo.NewContactListVO
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.XLog
+import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.o2Subscribe
 import rx.Observable
 import rx.Observable
 import rx.android.schedulers.AndroidSchedulers
 import rx.android.schedulers.AndroidSchedulers
 import rx.functions.Action1
 import rx.functions.Action1
@@ -77,9 +79,30 @@ class ContactUnitAndIdentityPickerPresenter: BasePresenterImpl<ContactUnitAndIde
                     val identityObservable = if (dutyList.isEmpty()){
                     val identityObservable = if (dutyList.isEmpty()){
                         service.identityListWithUnit(parent).map { response ->
                         service.identityListWithUnit(parent).map { response ->
                             val retList = ArrayList<NewContactListVO>()
                             val retList = ArrayList<NewContactListVO>()
+                            val idList = ArrayList<String>()
                             val list = response.data
                             val list = response.data
                             if (list != null && list.isNotEmpty()) {
                             if (list != null && list.isNotEmpty()) {
-                                list.map { retList.add(it.copyToOrgVO()) }
+                                list.map {
+                                    idList.add(it.person)
+                                    retList.add(it.copyToOrgVO())
+                                }
+                            }
+                            //这里需要把person的dn查询出来
+                            if (idList.isNotEmpty()) {
+                                assService.searchPersonDNList(PersonList(idList)).observeOn(Schedulers.immediate()).o2Subscribe {
+                                    onNext { assRes ->
+                                        val dnList = assRes.data.personList
+                                        if (dnList.isNotEmpty()) {
+                                            retList.forEachIndexed { index, identity ->
+                                                (identity as NewContactListVO.Identity).person = dnList[index]
+                                            }
+                                        }
+                                    }
+                                    onError { e, isNetworkError ->
+                                        XLog.error("$isNetworkError", e)
+                                    }
+                                }
+//                                XLog.debug("查询personDN完成。。。。$retList")
                             }
                             }
                             retList
                             retList
                         }
                         }
@@ -89,10 +112,28 @@ class ContactUnitAndIdentityPickerPresenter: BasePresenterImpl<ContactUnitAndIde
                         form.nameList = dutyList
                         form.nameList = dutyList
                         assService.identityListByUnitAndDuty(form).map { response ->
                         assService.identityListByUnitAndDuty(form).map { response ->
                             val retList = ArrayList<NewContactListVO>()
                             val retList = ArrayList<NewContactListVO>()
+                            val idList = ArrayList<String>()
                             val list = response.data
                             val list = response.data
                             if (list != null && list.isNotEmpty()) {
                             if (list != null && list.isNotEmpty()) {
                                 list.map { retList.add(it.copyToOrgVO()) }
                                 list.map { retList.add(it.copyToOrgVO()) }
                             }
                             }
+                            //这里需要把person的dn查询出来
+                            if (idList.isNotEmpty()) {
+                                assService.searchPersonDNList(PersonList(idList)).observeOn(Schedulers.immediate()).o2Subscribe {
+                                    onNext { assRes ->
+                                        val dnList = assRes.data.personList
+                                        if (dnList.isNotEmpty()) {
+                                            retList.forEachIndexed { index, identity ->
+                                                (identity as NewContactListVO.Identity).person = dnList[index]
+                                            }
+                                        }
+                                    }
+                                    onError { e, isNetworkError ->
+                                        XLog.error("$isNetworkError", e)
+                                    }
+                                }
+//                                XLog.debug("查询personDN完成。。。。$retList")
+                            }
                             retList
                             retList
                         }
                         }
                     }
                     }
@@ -136,7 +177,8 @@ class ContactUnitAndIdentityPickerPresenter: BasePresenterImpl<ContactUnitAndIde
             val retList = ArrayList<NewContactListVO>()
             val retList = ArrayList<NewContactListVO>()
             val list = response.data
             val list = response.data
             if (list != null && list.isNotEmpty()) {
             if (list != null && list.isNotEmpty()) {
-                list.map { retList.add(NewContactListVO.Department(it.id, it.name, it.distinguishedName, it.woSubDirectUnitList.size, 0)) }
+                list.map { retList.add(NewContactListVO.Department(it.id, it.name, it.unique, it.distinguishedName,
+                        it.typeList, it.shortName, it.level, it.levelName, it.woSubDirectUnitList.size, 0)) }
             }
             }
             Observable.just(retList)
             Observable.just(retList)
         }.subscribeOn(Schedulers.io())
         }.subscribeOn(Schedulers.io())

+ 5 - 2
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/webview/TaskWebViewActivity.kt

@@ -348,8 +348,11 @@ class TaskWebViewActivity : BaseMVPActivity<TaskWebViewContract.View, TaskWebVie
         runOnUiThread {
         runOnUiThread {
             showLoadingDialog()
             showLoadingDialog()
         }
         }
-
-        mPresenter.downloadAttachment(attachmentId, workId)
+        if (isWorkCompleted) {
+            mPresenter.downloadWorkCompletedAttachment(attachmentId, workCompletedId)
+        }else {
+            mPresenter.downloadAttachment(attachmentId, workId)
+        }
     }
     }
 
 
     /**
     /**

+ 1 - 0
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/webview/TaskWebViewContract.kt

@@ -30,6 +30,7 @@ object TaskWebViewContract {
         fun uploadAttachment(attachmentFilePath: String, site: String, workId: String)
         fun uploadAttachment(attachmentFilePath: String, site: String, workId: String)
         fun replaceAttachment(attachmentFilePath: String, site: String, attachmentId: String, workId: String)
         fun replaceAttachment(attachmentFilePath: String, site: String, attachmentId: String, workId: String)
         fun downloadAttachment(attachmentId: String, workId: String)
         fun downloadAttachment(attachmentId: String, workId: String)
+        fun downloadWorkCompletedAttachment(attachmentId: String, workCompleted: String)
         fun save(workId: String, formData: String)
         fun save(workId: String, formData: String)
         fun submit(data: TaskData?, workId: String, formData: String?)
         fun submit(data: TaskData?, workId: String, formData: String?)
         fun delete(workId: String)
         fun delete(workId: String)

+ 68 - 0
o2android/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/webview/TaskWebViewPresenter.kt

@@ -261,6 +261,74 @@ class TaskWebViewPresenter : BasePresenterImpl<TaskWebViewContract.View>(), Task
     }
     }
 
 
 
 
+    override fun downloadWorkCompletedAttachment(attachmentId: String, workCompleted: String) {
+        if (TextUtils.isEmpty(attachmentId) || TextUtils.isEmpty(workCompleted)) {
+            mView?.invalidateArgs()
+            XLog.error("arguments is null att:$attachmentId, workCompleted:$workCompleted")
+            mView?.finishLoading()
+            return
+        }
+        getProcessAssembleSurfaceServiceAPI(mView?.getContext())?.let { service->
+            service.getWorkCompletedAttachmentInfo(attachmentId, workCompleted)
+                    .subscribeOn(Schedulers.io())
+                    .flatMap { response ->
+                        val info: AttachmentInfo? = response.data
+                        if (info != null) {
+                            val path = FileExtensionHelper.getXBPMWORKAttachmentFileByName(info.name)
+                            val file = File(path)
+                            if (!file.exists()) { //下载
+                                try {
+                                    SDCardHelper.generateNewFile(path)
+                                    val call = service.downloadWorkCompletedAttachment(attachmentId, workCompleted)
+                                    val downloadRes = call.execute()
+                                    val headerDisposition = downloadRes.headers().get("Content-Disposition")
+                                    XLog.debug("header disposition: $headerDisposition")
+                                    val dataInput = DataInputStream(downloadRes.body()?.byteStream())
+                                    val fileOut = DataOutputStream(FileOutputStream(file))
+                                    val buffer = ByteArray(4096)
+                                    var count = 0
+                                    do {
+                                        count = dataInput.read(buffer)
+                                        if (count > 0) {
+                                            fileOut.write(buffer, 0, count)
+                                        }
+                                    } while (count > 0)
+                                    fileOut.close()
+                                    dataInput.close()
+                                } catch (e: Exception) {
+                                    XLog.error("下载附件失败!", e)
+                                    if (file.exists()) {
+                                        file.delete()
+                                    }
+                                }
+                            }
+                            Observable.create { t ->
+                                val thisfile = File(path)
+                                if (file.exists()) {
+                                    t?.onNext(thisfile)
+                                } else {
+                                    t?.onError(Exception("附件下载异常,找不到文件!"))
+                                }
+                                t?.onCompleted()
+                            }
+                        } else {
+                            Observable.create(object : Observable.OnSubscribe<File> {
+                                override fun call(t: Subscriber<in File>?) {
+                                    t?.onError(Exception("没有获取到附件信息,无法下载附件!"))
+                                    t?.onCompleted()
+                                }
+                            })
+                        }
+
+                    }
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe({ file -> mView?.downloadAttachmentSuccess(file) }, { e ->
+                        mView?.downloadFail( "下载附件失败,${e.message}")
+                    })
+        }
+    }
+
+
     override fun upload2FileStorage(filePath: String, referenceType: String, reference: String, scale: Int) {
     override fun upload2FileStorage(filePath: String, referenceType: String, reference: String, scale: Int) {
         XLog.debug("上传图片,filePath:$filePath, referenceType:$referenceType, reference:$reference, scale:$scale")
         XLog.debug("上传图片,filePath:$filePath, referenceType:$referenceType, reference:$reference, scale:$scale")
         if (filePath.isEmpty() || reference.isEmpty() || referenceType.isEmpty()) {
         if (filePath.isEmpty() || reference.isEmpty() || referenceType.isEmpty()) {

+ 111 - 11
o2android/app/src/main/res/layout/fragment_main_app.xml

@@ -1,15 +1,115 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@color/z_color_background">
+    android:layout_height="match_parent">
 
 
-    <GridView
-        android:id="@+id/app_list_id"
+    <LinearLayout
+        android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginTop="@dimen/spacing_small"
-        android:numColumns="5"
-        android:stretchMode="columnWidth"/>
-</LinearLayout>
+        android:layout_height="wrap_content">
+        <ImageView
+            android:id="@+id/my_app_top_image"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scaleType="fitXY"
+            android:src="@mipmap/my_app_top"/>
+
+        <LinearLayout
+            android:id="@+id/my_app_list_ll"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:background="@android:color/white"
+            android:padding="@dimen/meeting_padding">
+
+            <android.support.constraint.ConstraintLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <TextView
+                    android:id="@+id/my_app_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textSize="@dimen/font_meeting_time"
+                    android:textColor="@color/z_color_text_primary_dark"
+                    android:paddingBottom="8dp"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    android:text="我的应用"/>
+
+                <TextView
+                    android:id="@+id/my_app_text_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textSize="@dimen/font_normal"
+                    android:textColor="@color/z_color_text_hint"
+                    app:layout_constraintStart_toEndOf="@id/my_app_text"
+                    app:layout_constraintTop_toTopOf="parent"
+                    android:layout_marginStart="@dimen/spacing_tiny"
+                    android:visibility="gone"
+                    android:text="(按住拖动调整顺序)"/>
+
+                <android.support.v7.widget.RecyclerView
+                    android:id="@+id/my_app_rv"
+                    app:layout_constraintStart_toEndOf="@id/my_app_text"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintTop_toTopOf="parent"
+                    android:layout_marginStart="@dimen/spacing_tiny"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"/>
+
+            </android.support.constraint.ConstraintLayout>
+
+            <LinearLayout
+                android:id="@+id/edit_ll_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:visibility="gone"
+                android:layout_marginTop="@dimen/spacing_meeting">
+
+                <View
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/split_line"
+                    android:background="@color/z_color_split_meeting_line"
+                    />
+
+                <android.support.v7.widget.RecyclerView
+                    android:id="@+id/my_app_recycler_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"/>
+            </LinearLayout>
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_marginTop="@dimen/meeting_padding"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="@dimen/meeting_padding"
+            android:orientation="vertical"
+            android:background="@android:color/white">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="@dimen/font_meeting_time"
+                android:textColor="@color/z_color_text_primary_dark"
+                android:text="全部应用"/>
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/split_line"
+                android:background="@color/z_color_split_meeting_line"
+                android:layout_marginTop="@dimen/spacing_meeting"/>
+
+            <android.support.v7.widget.RecyclerView
+                android:id="@+id/all_app_recycler_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </LinearLayout>
+</ScrollView>

+ 46 - 43
o2android/app/src/main/res/layout/fragment_main_bottom_bar_image.xml

@@ -8,7 +8,7 @@
         android:layout_width="match_parent"
         android:layout_width="match_parent"
         android:layout_height="1px"
         android:layout_height="1px"
         android:background="@color/z_color_split_line"
         android:background="@color/z_color_split_line"
-        android:padding="0dp"></LinearLayout>
+        android:padding="0dp" />
 
 
     <LinearLayout
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_width="match_parent"
@@ -16,38 +16,8 @@
         android:background="@color/z_color_bottom_bar_background"
         android:background="@color/z_color_bottom_bar_background"
         android:orientation="horizontal"
         android:orientation="horizontal"
         android:padding="0dp">
         android:padding="0dp">
-        <ImageView
-            android:id="@+id/icon_main_bottom_index"
-            android:layout_width="0dp"
-            android:layout_weight="1"
-            android:layout_height="match_parent"
-            android:layout_margin="3dp"
-            android:src="@mipmap/index_bottom_menu_logo_focus"
-            android:scaleType="fitCenter"
-            />
-        <!--<RelativeLayout-->
-            <!--android:id="@+id/icon_main_bottom_index_blur"-->
-            <!--android:layout_width="0dp"-->
-            <!--android:layout_weight="1"-->
-            <!--android:layout_height="match_parent"-->
-            <!--android:padding="2dp"-->
-            <!--android:visibility="gone">-->
-            <!--<ImageView-->
-                <!--android:id="@+id/image_icon_main_bottom_index_blur"-->
-                <!--android:layout_centerHorizontal="true"-->
-                <!--android:layout_width="35dp"-->
-                <!--android:layout_height="35dp"-->
-                <!--android:src="@mipmap/icon_main_index_blur"/>-->
-            <!--<TextView-->
-                <!--android:id="@+id/tv_icon_main_bottom_index_blur"-->
-                <!--android:layout_below="@id/image_icon_main_bottom_index_blur"-->
-                <!--android:layout_centerHorizontal="true"-->
-                <!--android:layout_width="wrap_content"-->
-                <!--android:layout_height="wrap_content"-->
-                <!--android:textSize="12sp"-->
-                <!--android:textColor="@color/z_color_text_primary"-->
-                <!--android:text="@string/tab_todo"/>-->
-        <!--</RelativeLayout>-->
+
+
         <RelativeLayout
         <RelativeLayout
             android:id="@+id/icon_main_bottom_news"
             android:id="@+id/icon_main_bottom_news"
             android:layout_width="0dp"
             android:layout_width="0dp"
@@ -70,16 +40,6 @@
                 android:textColor="@color/z_color_text_primary"
                 android:textColor="@color/z_color_text_primary"
                 android:text="@string/tab_message"/>
                 android:text="@string/tab_message"/>
         </RelativeLayout>
         </RelativeLayout>
-
-        <RelativeLayout
-            android:id="@+id/icon_main_bottom_center_gap"
-            android:layout_width="0dp"
-            android:layout_weight="1"
-            android:layout_height="match_parent"
-            android:padding="2dp"
-            android:visibility="gone">
-
-        </RelativeLayout>
         <RelativeLayout
         <RelativeLayout
             android:id="@+id/icon_main_bottom_contact"
             android:id="@+id/icon_main_bottom_contact"
             android:layout_width="0dp"
             android:layout_width="0dp"
@@ -103,6 +63,49 @@
                 android:text="@string/tab_contact"/>
                 android:text="@string/tab_contact"/>
         </RelativeLayout>
         </RelativeLayout>
 
 
+        <ImageView
+            android:id="@+id/icon_main_bottom_index"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:layout_margin="3dp"
+            android:src="@mipmap/index_bottom_menu_logo_focus"
+            android:scaleType="fitCenter"
+            />
+        <!--<RelativeLayout-->
+            <!--android:id="@+id/icon_main_bottom_center_gap"-->
+            <!--android:layout_width="0dp"-->
+            <!--android:layout_weight="1"-->
+            <!--android:layout_height="match_parent"-->
+            <!--android:padding="2dp"-->
+            <!--android:visibility="gone">-->
+
+        <!--</RelativeLayout>-->
+        <RelativeLayout
+            android:id="@+id/icon_main_bottom_app"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:padding="2dp">
+            <ImageView
+                android:id="@+id/image_icon_main_bottom_app"
+                android:layout_centerHorizontal="true"
+                android:layout_width="33dp"
+                android:layout_height="33dp"
+                android:layout_marginTop="2dp"
+                android:src="@mipmap/icon_main_app"/>
+            <TextView
+                android:id="@+id/tv_icon_main_bottom_app"
+                android:layout_below="@id/image_icon_main_bottom_app"
+                android:layout_centerHorizontal="true"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="12sp"
+                android:textColor="@color/z_color_text_primary"
+                android:text="@string/tab_app"/>
+        </RelativeLayout>
+
+
         <RelativeLayout
         <RelativeLayout
             android:id="@+id/icon_main_bottom_setting"
             android:id="@+id/icon_main_bottom_setting"
             android:layout_width="0dp"
             android:layout_width="0dp"

+ 1 - 2
o2android/app/src/main/res/menu/menu_my_app.xml

@@ -1,7 +1,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context=".app.main.activity.ChatActivity">
+    >
 
 
     <item android:id="@+id/menu_app_edit"
     <item android:id="@+id/menu_app_edit"
         app:showAsAction="always"
         app:showAsAction="always"

BIN
o2android/app/src/main/res/mipmap-xhdpi/icon_main_app.png


BIN
o2android/app/src/main/res/mipmap-xhdpi/icon_main_app_red.png


BIN
o2android/app/src/main/res/mipmap-xhdpi/icon_main_app_red_blue.png


BIN
o2android/app/src/main/res/mipmap-xhdpi/pic_jieshu.png


+ 1 - 0
o2android/app/src/main/res/values/strings.xml

@@ -92,6 +92,7 @@
     <string name="tab_contact">通讯录</string>
     <string name="tab_contact">通讯录</string>
     <string name="tab_my">我的</string>
     <string name="tab_my">我的</string>
     <string name="tab_settings">设置</string>
     <string name="tab_settings">设置</string>
+    <string name="tab_app">应用</string>
 
 
     <!-- font awesome -->
     <!-- font awesome -->
     <string name="fa_angle_right">&#xf105;</string>
     <string name="fa_angle_right">&#xf105;</string>

+ 2 - 2
o2android/gradle.properties

@@ -20,8 +20,8 @@ org.gradle.parallel=true
 
 
 
 
 # o2
 # o2
-o2.versionName=4.9.4
-o2.versionCode=94
+o2.versionName=4.9.5
+o2.versionCode=95
 
 
 
 
 # sjgj
 # sjgj