From 85717af618538aab6069a01a81ab9934a47be1fd Mon Sep 17 00:00:00 2001 From: fancy Date: Mon, 10 Apr 2023 10:38:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E7=89=88=E8=80=83=E5=8B=A4=20?= =?UTF-8?q?=E6=89=93=E5=8D=A1=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/AttendanceCheckInV2Contract.kt | 18 + .../main/AttendanceCheckInV2NewFragment.kt | 413 ++++++++++++++++++ .../main/AttendanceCheckInV2Presenter.kt | 54 +++ .../attendance/main/AttendanceMainActivity.kt | 16 +- .../main/AttendanceStatisticV2Contract.kt | 23 + .../main/AttendanceStatisticV2Fragment.kt | 46 ++ .../main/AttendanceStatisticV2Presenter.kt | 13 + .../v1/zoneXBPM/app/o2/main/MainActivity.kt | 5 +- .../v1/zoneXBPM/app/o2/main/MainPresenter.kt | 13 +- .../fragment_attendance_check_in_v2.xml | 90 ++++ .../fragment_attendance_statistic_v2.xml | 12 + .../AttendanceAssembleControlService.kt | 25 ++ .../model/bo/api/attendance/AttendanceJSON.kt | 73 ++++ 13 files changed, 784 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Contract.kt create mode 100644 app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2NewFragment.kt create mode 100644 app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Presenter.kt create mode 100644 app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Contract.kt create mode 100644 app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Fragment.kt create mode 100644 app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Presenter.kt create mode 100644 app/src/main/res/layout/fragment_attendance_check_in_v2.xml create mode 100644 app/src/main/res/layout/fragment_attendance_statistic_v2.xml diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Contract.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Contract.kt new file mode 100644 index 0000000..dab790c --- /dev/null +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Contract.kt @@ -0,0 +1,18 @@ +package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.main + +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.model.bo.api.attendance.* + + +object AttendanceCheckInV2Contract { + interface View : BaseView { + fun preCheckData(data: AttendanceV2PreCheckData?) + fun checkInPostResponse(result: Boolean) + } + + interface Presenter : BasePresenter { + fun preCheckDataLoad() + fun checkInPost(body: AttendanceV2CheckInBody) + } +} diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2NewFragment.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2NewFragment.kt new file mode 100644 index 0000000..4a3690d --- /dev/null +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2NewFragment.kt @@ -0,0 +1,413 @@ +package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.main + +import android.graphics.drawable.GradientDrawable +import android.os.Handler +import android.os.Message +import android.text.TextUtils +import android.widget.EditText +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.GridLayoutManager +import com.baidu.location.BDAbstractLocationListener +import com.baidu.location.BDLocation +import com.baidu.location.LocationClient +import com.baidu.location.LocationClientOption +import com.baidu.mapapi.model.LatLng +import com.baidu.mapapi.utils.DistanceUtil +import kotlinx.android.synthetic.main.fragment_attendance_check_in_new.* +import kotlinx.android.synthetic.main.fragment_attendance_check_in_v2.* +import kotlinx.android.synthetic.main.fragment_attendance_check_in_v2.image_attendance_check_in_new_location_check_icon +import kotlinx.android.synthetic.main.fragment_attendance_check_in_v2.rl_attendance_check_in_new_knock_btn +import kotlinx.android.synthetic.main.fragment_attendance_check_in_v2.rv_attendance_check_in_new_schedules +import kotlinx.android.synthetic.main.fragment_attendance_check_in_v2.tv_attendance_check_in_new_check_in +import kotlinx.android.synthetic.main.fragment_attendance_check_in_v2.tv_attendance_check_in_new_now_time +import kotlinx.android.synthetic.main.fragment_attendance_check_in_v2.tv_attendance_check_in_new_workplace +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.core.component.adapter.CommonRecycleViewAdapter +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.CommonRecyclerViewHolder +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.attendance.* +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.im.MessageType +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.CheckButtonDoubleClick +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.DateHelper +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.extension.gone +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.visible +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.GridLayoutItemDecoration +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.dialog.O2DialogSupport +import org.jetbrains.anko.dip +import java.util.* +import kotlin.collections.ArrayList + +/** + * Created by fancyLou on 2020-07-17. + * Copyright © 2020 O2. All rights reserved. + */ + +class AttendanceCheckInV2NewFragment : BaseMVPViewPagerFragment(), + AttendanceCheckInV2Contract.View { + override var mPresenter: AttendanceCheckInV2Contract.Presenter = AttendanceCheckInV2Presenter() + override fun layoutResId(): Int = R.layout.fragment_attendance_check_in_v2 + + + private val workplaceList = ArrayList() + private val recordList = ArrayList() + private var lastRecord: AttendanceV2CheckItemData? = null + private var needCheckIn = false //是否可打卡 + private var allowFieldWork = false // 是否允许外勤 + private var requiredFieldWorkRemarks = false // 外勤是否必须打卡 + + private val recordAdapter: CommonRecycleViewAdapter by lazy { + object : CommonRecycleViewAdapter(activity, recordList, R.layout.item_attendance_check_in_schdule_list) { + override fun convert(holder: CommonRecyclerViewHolder?, t: AttendanceV2CheckItemData?) { + if (holder != null && t != null) { + val status = if(t.isRecord) { + t.recordTime + } else { + "未打卡" + } + holder.setText(R.id.tv_item_attendance_check_in_schedule_list_type, t.checkInTypeString) + .setText(R.id.tv_item_attendance_check_in_schedule_list_time, t.preDutyTime) + .setText(R.id.tv_item_attendance_check_in_schedule_list_status, status) + val updateBtn = holder.getView(R.id.tv_item_attendance_check_in_schedule_list_update_btn) + updateBtn.gone() + if (t.isLastRecord) { + updateBtn.visible() + } + } + } + } + } + + + //定位 + private val mLocationClient: LocationClient by lazy { LocationClient(activity) } + private var myLocation: BDLocation? = null //当前我的位置 + private var checkInPosition: AttendanceV2WorkPlace? = null//离的最近的工作地点位置 + private var isInCheckInPositionRange = false + + + //刷新打卡按钮的时间 + private val handler = Handler { msg -> + if (msg.what == 1) { + val nowTime = DateHelper.nowByFormate("HH:mm:ss") + tv_attendance_check_in_new_now_time?.text = nowTime + } + return@Handler true + } + private val timerTask = object : TimerTask() { + override fun run() { + val message = Message() + message.what = 1 + handler.sendMessage(message) + } + } + private val timer: Timer by lazy { Timer() } + + + override fun lazyLoad() { + mPresenter.preCheckDataLoad() + } + + override fun initUI() { + LocationClient.setAgreePrivacy(true) + //定位 + mLocationClient.registerLocationListener(object : BDAbstractLocationListener() { + override fun onReceiveLocation(location: BDLocation?) { + XLog.debug("onReceive locType:${location?.locType}, latitude:${location?.latitude}, longitude:${location?.longitude}") + if (location != null) { + myLocation = location + //计算 + calNearestWorkplace() + } + } + }) + initBaiduLocation() + mLocationClient.start() + + //打卡班次 + rv_attendance_check_in_new_schedules.layoutManager = GridLayoutManager(activity, 2) + rv_attendance_check_in_new_schedules.addItemDecoration(GridLayoutItemDecoration(activity?.dip(10) ?: 10, activity?.dip(10) ?: 10, 2)) + rv_attendance_check_in_new_schedules.adapter = recordAdapter + recordAdapter.setOnItemClickListener { _, position -> + // 点击更新打卡 + clickUpdateRecord(recordList[position]) + } + + //打卡按钮 + rl_attendance_check_in_new_knock_btn.setOnClickListener { + if (CheckButtonDoubleClick.isFastDoubleClick(R.id.rl_attendance_check_in_new_knock_btn)) { + return@setOnClickListener + } + // 打卡 + clickCheckIn() + } + //时间 + timer.schedule(timerTask, 0, 1000) + } + + private fun setCheckInBtnEnable(enable: Boolean) { + needCheckIn = enable + val draw = rl_attendance_check_in_new_knock_btn.background as? GradientDrawable + if (enable) { + activity?.let { + draw?.setColor(ContextCompat.getColor(it, R.color.z_color_primary)) + } + } else { + activity?.let { + draw?.setColor(ContextCompat.getColor(it, R.color.disabled)) + } + } + } + + + override fun onDestroyView() { + timer.cancel() + timerTask.cancel() + super.onDestroyView() + } + + override fun onDestroy() { + // 退出时销毁定位 + mLocationClient.stop() + super.onDestroy() + } + + override fun preCheckData(data: AttendanceV2PreCheckData?) { + if (data == null) { + setCheckInBtnEnable(false) + return + } + XLog.debug("$data") + needCheckIn = data.canCheckIn //今天是否还需要打卡 + allowFieldWork = data.allowFieldWork + requiredFieldWorkRemarks = data.requiredFieldWorkRemarks + workplaceList.clear() + workplaceList.addAll(data.workPlaceList ?: ArrayList()) + // 检查是否在范围内 + calNearestWorkplace() + if (needCheckIn) { + // 打卡记录 + val checkItemList = data.checkItemList ?: ArrayList() + // 是否最后一条已经打卡过的数据 + lastRecord = checkItemList.firstOrNull { element -> element.checkInResult == "PreCheckIn" } + needCheckIn = lastRecord != null + for ((index, item) in checkItemList.withIndex()) { + var isRecord = false + var recordTime = "" + if (item.checkInResult != "PreCheckIn") { + isRecord = true + var signTime = item.recordDate + if (signTime.length > 16) { + signTime = signTime.substring(11, 16); + } + recordTime = "已打卡 $signTime" // lpFormat(lp, 'mobile.checkInWithTime', {time: signTime}); + } + item.recordTime = recordTime + item.isRecord = isRecord // 是否已经打卡 + item.checkInTypeString = if(item.checkInType == "OnDuty") { "上班打卡" }else{ "下班打卡"} + var preDutyTime = item.preDutyTime + if (TextUtils.isEmpty(item.shiftId)) { + preDutyTime = "" // 如果没有班次信息 表示 自由工时 或者 休息日 不显示 打卡时间 + } + item.preDutyTime = preDutyTime + // 处理是否是最后一个已经打卡的记录 + if (item.checkInResult != "PreCheckIn") { + if (index == checkItemList.size - 1) { // 最后一条 + item.isLastRecord = true // 最后一条已经打卡的记录 + } else { + val nextItem = checkItemList[index+1] + if (nextItem.checkInResult == "PreCheckIn") { + item.isLastRecord = true + } + } + } + checkItemList[index] = item + } + recordList.clear() + recordList.addAll(checkItemList) + } + // 刷新页面 + setCheckInBtnEnable(needCheckIn) + recordAdapter.notifyDataSetChanged() + } + + override fun checkInPostResponse(result: Boolean) { + tv_attendance_check_in_new_check_in?.setText(R.string.attendance_check_in_knock) + tv_attendance_check_in_new_now_time?.visible() + if (result) { + XToast.toastShort(activity, "打卡成功!") + } else { + XToast.toastShort(activity, "打卡失败!") + } + mPresenter.preCheckDataLoad() + } + + /** + * 点击更新打卡 + */ + private fun clickUpdateRecord(record: AttendanceV2CheckItemData) { + if (myLocation == null || TextUtils.isEmpty(myLocation?.addrStr)) { + XLog.error("没有定位到信息,可能是定位权限没开!!!") + XToast.toastShort(activity!!, R.string.attendance_message_no_location_info) + return + } + + if (record.isLastRecord) { // 只有最后一条可以更新 + tv_attendance_check_in_new_check_in.text = getString(R.string.attendance_check_in_knock_loading) + tv_attendance_check_in_new_now_time.gone() + if (isInCheckInPositionRange && checkInPosition != null) { // 正常打卡 + postCheckIn(record, checkInPosition!!.id, false, null) + } else { + // 外勤 + outSide(record) + } + } else { + XLog.info("不是最后一条,不能更新打卡,怎么点击到的???") + } + } + /** + * 点击打卡 + */ + private fun clickCheckIn() { + if (myLocation == null || TextUtils.isEmpty(myLocation?.addrStr)) { + XLog.error("没有定位到信息,可能是定位权限没开!!!") + XToast.toastShort(activity!!, R.string.attendance_message_no_location_info) + return + } + if (needCheckIn && lastRecord != null) { + tv_attendance_check_in_new_check_in.text = getString(R.string.attendance_check_in_knock_loading) + tv_attendance_check_in_new_now_time.gone() + if (isInCheckInPositionRange && checkInPosition != null) { // 正常打卡 + postCheckIn(lastRecord!!, checkInPosition!!.id, false, null) + } else { + // 外勤 + outSide(lastRecord!!) + } + } else { + XLog.info("不允许打卡或lastRecord is null") + } + } + + /** + * 外勤打卡处理 + */ + private fun outSide(record: AttendanceV2CheckItemData) { + if (allowFieldWork) { + if (requiredFieldWorkRemarks) { + if (activity != null) { + val dialog = O2DialogSupport.openCustomViewDialog( + activity!!, + getString(R.string.attendance_message_work_out), + R.layout.dialog_name_modify + ) { dialog -> + val text = dialog.findViewById(R.id.dialog_name_editText_id) + if (TextUtils.isEmpty(text.text.toString())) { + XToast.toastShort(activity!!, R.string.attendance_message_work_out_hint) + } else { + postCheckIn(record, null, true, text.text.toString()) + } + } + val text = dialog.findViewById(R.id.dialog_name_editText_id) + text.hint = getString(R.string.attendance_message_work_out_hint) + } + } else { + postCheckIn(record, null, true, null) + } + } else { + XToast.toastShort(activity, "不在工作地点的打卡范围内!") + } + } + + /** + * 提交打卡信息 + */ + private fun postCheckIn(record: AttendanceV2CheckItemData, workPlaceId: String?, outSide: Boolean, outSideDesc:String?) { + val body = AttendanceV2CheckInBody() + body.recordId = record.id + body.checkInType = record.checkInType + body.latitude = myLocation!!.latitude.toString() + body.longitude = myLocation!!.longitude.toString() + body.recordAddress = myLocation!!.addrStr + body.workPlaceId = workPlaceId ?: "" + body.fieldWork = outSide + body.signDescription = outSideDesc ?: "" + XLog.debug(body.toString()) + mPresenter.checkInPost(body) + } + + /** + * 检查是否进入打卡范围 + */ + private fun checkIsInWorkplace() { + XLog.info("checkIsInWorkplace.....${checkInPosition?.placeName}, ${myLocation?.addrStr}") + if (checkInPosition != null && myLocation != null) { + val workplacePosition = LatLng(checkInPosition!!.latitude.toDouble(), checkInPosition!!.longitude.toDouble()) + val position = LatLng(myLocation!!.latitude, myLocation!!.longitude) + val distance = DistanceUtil.getDistance(position, workplacePosition) + XLog.info("distance:$distance") + if (distance < checkInPosition!!.errorRange) { + isInCheckInPositionRange = true + activity?.runOnUiThread { + tv_attendance_check_in_new_workplace.text = checkInPosition?.placeName + image_attendance_check_in_new_location_check_icon.setImageResource(R.mipmap.list_selected) + } + } else { + isInCheckInPositionRange = false + activity?.runOnUiThread { + tv_attendance_check_in_new_workplace.text = myLocation?.addrStr + image_attendance_check_in_new_location_check_icon.setImageResource(R.mipmap.icon_delete_people) + } + } + } + } + + /** + * 找到最近的打卡地点 + */ + private fun calNearestWorkplace() { + if ( myLocation!=null) { + if (workplaceList.isNotEmpty()) { + var minDistance: Double = -1.0 + XLog.debug("calNearestWorkplace...................") + workplaceList.map { + val p2 = LatLng(it.latitude.toDouble(), it.longitude.toDouble()) + val position = LatLng(myLocation!!.latitude, myLocation!!.longitude) + val distance = DistanceUtil.getDistance(position, p2) + if (minDistance == -1.0) { + minDistance = distance + checkInPosition = it + } else { + if (minDistance > distance) { + minDistance = distance + checkInPosition = it + } + } + } + XLog.info("checkInposition:${checkInPosition?.placeName}") + checkIsInWorkplace() + } else { + activity?.runOnUiThread { + tv_attendance_check_in_new_workplace.text = myLocation?.addrStr + } + } + } + } + + private fun initBaiduLocation() { + val option = LocationClientOption() + option.locationMode = LocationClientOption.LocationMode.Hight_Accuracy//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 + option.setCoorType("bd09ll")//百度坐标系 可选,默认gcj02,设置返回的定位结果坐标系 + option.setScanSpan(5000)//5秒一次定位 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的 + option.setIsNeedAddress(true)//可选,设置是否需要地址信息,默认不需要 + option.isOpenGps = true//可选,默认false,设置是否使用gps + option.isLocationNotify = true//可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果 + option.setIsNeedLocationDescribe(true)//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” + option.setIsNeedLocationPoiList(true)//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 + option.setIgnoreKillProcess(false)//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 + option.SetIgnoreCacheException(false)//可选,默认false,设置是否收集CRASH信息,默认收集 + option.setEnableSimulateGps(false)//可选,默认false,设置是否需要过滤GPS仿真结果,默认需要 + mLocationClient.locOption = option + } +} \ No newline at end of file diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Presenter.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Presenter.kt new file mode 100644 index 0000000..2718d38 --- /dev/null +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceCheckInV2Presenter.kt @@ -0,0 +1,54 @@ +package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.main + +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenterImpl +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.attendance.AttendanceV2CheckInBody +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 + +class AttendanceCheckInV2Presenter : BasePresenterImpl(), AttendanceCheckInV2Contract.Presenter { + override fun preCheckDataLoad() { + val service = getAttendanceAssembleControlService(mView?.getContext()) + if (service != null) { + service.attendanceV2PreCheck() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .o2Subscribe { + onNext { + mView?.preCheckData(it?.data) + } + onError { e, _ -> + XLog.error("", e) + mView?.preCheckData(null) + } + } + } else { + mView?.preCheckData(null) + } + } + + override fun checkInPost(body: AttendanceV2CheckInBody) { + val service = getAttendanceAssembleControlService(mView?.getContext()) + if (service != null) { + service.attendanceV2CheckIn(body) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .o2Subscribe { + onNext { + if (it != null && it.data != null ) { + mView?.checkInPostResponse(true) + } else { + mView?.checkInPostResponse(false) + } + } + onError { e, _ -> + XLog.error("", e) + mView?.checkInPostResponse(false) + } + } + } else { + mView?.checkInPostResponse(false) + } + } +} diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceMainActivity.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceMainActivity.kt index b5de035..4a182aa 100644 --- a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceMainActivity.kt +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceMainActivity.kt @@ -33,17 +33,18 @@ class AttendanceMainActivity : BaseMVPActivity private val titleList: ArrayList by lazy { arrayListOf(getString(R.string.attendance_check_in_title), getString(R.string.title_activity_attendance_chart)) } override fun afterSetContentView(savedInstanceState: Bundle?) { setupToolBar(getString(R.string.attendance_check_in_title), setupBackButton = true, isCloseBackIcon = true) - val attendanceVersion = O2SDKManager.instance().prefs().getString(O2.PRE_ATTENDANCE_VERSION_KEY, "0") + attendanceVersion = O2SDKManager.instance().prefs().getString(O2.PRE_ATTENDANCE_VERSION_KEY, "1") ?: "1" fragmentList = if (attendanceVersion == "1") { arrayListOf(AttendanceCheckInNewFragment(), AttendanceStatisticFragment()) }else { - arrayListOf(AttendanceCheckInFragment(), AttendanceStatisticFragment()) + arrayListOf(AttendanceCheckInV2NewFragment(), AttendanceStatisticV2Fragment()) } view_pager_attendance_main_content.adapter = CommonFragmentPagerAdapter(supportFragmentManager, fragmentList, titleList) view_pager_attendance_main_content.addOnPageChangeListener { @@ -80,11 +81,12 @@ class AttendanceMainActivity : BaseMVPActivity { + + } +} \ No newline at end of file diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Fragment.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Fragment.kt new file mode 100644 index 0000000..f149e03 --- /dev/null +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Fragment.kt @@ -0,0 +1,46 @@ +package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.main + +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.LinearLayoutManager +import android.text.TextUtils +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.jzxiang.pickerview.listener.OnDateSetListener +import kotlinx.android.synthetic.main.fragment_attendance_statistic.* +import kotlinx.android.synthetic.main.picker_activity_map_picker.* +import net.muliba.changeskin.FancySkinManager +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.core.component.adapter.CommonRecyclerViewHolder +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.group.Group +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.group.GroupRecyclerViewAdapter +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.attendance.AttendanceDetailInfoJson +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.attendance.AttendanceStatisticGroupHeader +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.DateHelper +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.CircleTextView +import java.util.* + +/** + * Created by fancyLou on 28/05/2018. + * Copyright © 2018 O2. All rights reserved. + */ + + +class AttendanceStatisticV2Fragment : BaseMVPViewPagerFragment(), + AttendanceStatisticV2Contract.View { + override var mPresenter: AttendanceStatisticV2Contract.Presenter = AttendanceStatisticV2Presenter() + + + override fun layoutResId(): Int = R.layout.fragment_attendance_statistic_v2 + + + + override fun initUI() { + + } + + override fun lazyLoad() { + } + + +} \ No newline at end of file diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Presenter.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Presenter.kt new file mode 100644 index 0000000..29b2608 --- /dev/null +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/attendance/main/AttendanceStatisticV2Presenter.kt @@ -0,0 +1,13 @@ +package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.attendance.main + +import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BasePresenterImpl + +/** + * Created by fancyLou on 28/05/2018. + * Copyright © 2018 O2. All rights reserved. + */ + +class AttendanceStatisticV2Presenter : BasePresenterImpl(), AttendanceStatisticV2Contract.Presenter { + + +} \ No newline at end of file diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainActivity.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainActivity.kt index 4559561..6b6a8df 100644 --- a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainActivity.kt +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainActivity.kt @@ -442,19 +442,16 @@ class MainActivity : BaseMVPActivity( } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) private fun registerSchedulerJob() { val componentName = ComponentName(this, ClearTempFileJobService::class.java) val jobInfo = JobInfo.Builder(O2.O2_CLEAR_TEMP_FILE_JOB_ID, componentName) - .setPersisted(true)//手机重启之后是否继续 +// .setPersisted(true)//手机重启之后是否继续 .setRequiresCharging(true)//充电的时候才执行 .setPeriodic(24 * 60 * 60 * 1000) .build() val jobScheduler = applicationContext.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler val result = jobScheduler.schedule(jobInfo) -// val result2 = jobScheduler.schedule(jobCollectLog) -// XLog.info("jobScheduler result:$result, result2:$result2") XLog.info("jobScheduler result:$result") } diff --git a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainPresenter.kt b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainPresenter.kt index b0535a9..7262fa8 100644 --- a/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainPresenter.kt +++ b/app/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/app/o2/main/MainPresenter.kt @@ -1,5 +1,6 @@ package net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.main +import android.text.TextUtils import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2 import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2CustomStyle import net.zoneland.x.bpm.mobile.v1.zoneXBPM.O2SDKManager @@ -61,25 +62,25 @@ class MainPresenter : BasePresenterImpl(), MainContract.Prese override fun checkAttendanceFeature() { getAttendanceAssembleControlService(mView?.getContext())?.let { service -> - service.listMyRecords().subscribeOn(Schedulers.io()) + service.attendanceV2Check().subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .o2Subscribe { onNext { val data = it.data - if (data?.scheduleInfos != null && data.scheduleInfos.isNotEmpty()) { + if (it.data?.version != null) { O2SDKManager.instance().prefs().edit { - putString(O2.PRE_ATTENDANCE_VERSION_KEY, "1"); + putString(O2.PRE_ATTENDANCE_VERSION_KEY, "2"); } - }else { + } else { O2SDKManager.instance().prefs().edit { - putString(O2.PRE_ATTENDANCE_VERSION_KEY, "0"); + putString(O2.PRE_ATTENDANCE_VERSION_KEY, "1"); } } } onError { e, _ -> XLog.error("", e) O2SDKManager.instance().prefs().edit { - putString(O2.PRE_ATTENDANCE_VERSION_KEY, "0"); + putString(O2.PRE_ATTENDANCE_VERSION_KEY, "1"); } } } diff --git a/app/src/main/res/layout/fragment_attendance_check_in_v2.xml b/app/src/main/res/layout/fragment_attendance_check_in_v2.xml new file mode 100644 index 0000000..d73a00f --- /dev/null +++ b/app/src/main/res/layout/fragment_attendance_check_in_v2.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_attendance_statistic_v2.xml b/app/src/main/res/layout/fragment_attendance_statistic_v2.xml new file mode 100644 index 0000000..baf5fd5 --- /dev/null +++ b/app/src/main/res/layout/fragment_attendance_statistic_v2.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/core/component/api/service/AttendanceAssembleControlService.kt b/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/core/component/api/service/AttendanceAssembleControlService.kt index 1ce7f62..6f9a4f9 100644 --- a/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/core/component/api/service/AttendanceAssembleControlService.kt +++ b/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/core/component/api/service/AttendanceAssembleControlService.kt @@ -14,6 +14,31 @@ import rx.Observable interface AttendanceAssembleControlService { + + ////////////////v2///////////////// + + /** + * v2版本检查 + */ + @GET("jaxrs/v2/my/version") + fun attendanceV2Check():Observable> + + /** + * 预打卡接口 + * 打卡之前调用 + */ + @GET("jaxrs/v2/mobile/check/pre") + fun attendanceV2PreCheck():Observable> + + /** + * 打卡 + */ + @POST("jaxrs/v2/mobile/check") + fun attendanceV2CheckIn(@Body body: AttendanceV2CheckInBody):Observable> + + + //////////////////////v1///////////// + /** * 获取当前用户的考勤周期 */ diff --git a/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/model/bo/api/attendance/AttendanceJSON.kt b/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/model/bo/api/attendance/AttendanceJSON.kt index 628f936..343b21c 100644 --- a/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/model/bo/api/attendance/AttendanceJSON.kt +++ b/o2_auth_sdk/src/main/java/net/zoneland/x/bpm/mobile/v1/zoneXBPM/model/bo/api/attendance/AttendanceJSON.kt @@ -8,6 +8,79 @@ import java.io.Serializable * Created by fancy on 2017/3/28. */ + + +/** + * 新版考勤 检查对象 + */ +data class AttendanceV2CheckData( + var version: String = "", +) +data class AttendanceV2CheckItemData( + var id: String = "", + var userId: String = "", + var recordDateString: String = "", + var recordDate: String = "", + var preDutyTime: String = "", + var preDutyTimeBeforeLimit: String = "", + var preDutyTimeAfterLimit: String = "", + var sourceType: String = "", + var checkInResult: String = "", + var checkInType: String = "", + var sourceDevice: String = "", + var description: String = "", + var groupId: String = "", + var groupName: String = "", + var shiftId: String = "", + var shiftName: String = "", + var createTime: String = "", + var updateTime: String = "", + var sequence: String = "", + + // 是否最后一条已经打卡过的数据 + var isLastRecord: Boolean = false, + var isRecord: Boolean = false, + var recordTime: String = "", // 已打卡的显示内容 + var checkInTypeString: String = "", // 打卡类型 +) +data class AttendanceV2WorkPlace( + var id: String = "", + var placeName: String = "", + var placeAlias: String = "", + var creator: String = "", + var longitude: String = "", + var latitude: String = "", + var errorRange: Int = 200, + var description: String = "", +) +data class AttendanceV2PreCheckData( + var allowFieldWork: Boolean = false, + var requiredFieldWorkRemarks: Boolean = false, + var canCheckIn: Boolean = false, + var checkItemList: ArrayList? = ArrayList(), + var workPlaceList: ArrayList? = ArrayList(), +) +data class AttendanceV2CheckResponse( + var checkInRecordId: String = "", + var checkInResult: String = "", + var recordDate: String = "", +) + +data class AttendanceV2CheckInBody( + var recordId: String = "", + var checkInType: String = "", + var workPlaceId: String = "", + var fieldWork: Boolean = false, // 是否外勤打卡 + var signDescription: String = "", //打卡说明:上班打卡,下班打卡, 可以为空. + var sourceDevice: String = "", //操作设备类别:Mac|Windows|IOS|Android|其他, 可以为空. + var description: String = "", + var recordAddress: String = "", //打卡地点描述, 可以为空. + var longitude: String = "", //经度 + var latitude: String = "", //纬度 +) + +///////////////////////////////////// + /** * 管理员 */ -- GitLab