package com.casic.smarttube.view import android.content.Intent import android.graphics.Color import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.View import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.ViewModelProvider import cn.bertsir.zbar.QrManager import com.amap.api.location.AMapLocation import com.casic.smarttube.R import com.casic.smarttube.callback.OnImageCompressListener import com.casic.smarttube.databinding.ActivityAddDeviceBinding import com.casic.smarttube.extensions.combineImagePath import com.casic.smarttube.extensions.compressImage import com.casic.smarttube.extensions.initImmersionBar import com.casic.smarttube.extensions.isNumber import com.casic.smarttube.extensions.reformat import com.casic.smarttube.utils.GlideLoadEngine import com.casic.smarttube.utils.LocationHelper import com.casic.smarttube.utils.QrConfigCreator import com.casic.smarttube.vm.DeviceViewModel import com.casic.smarttube.vm.ProjectGroupViewModel import com.casic.smarttube.vm.UploadImageViewModel import com.luck.picture.lib.basic.PictureSelector import com.luck.picture.lib.config.SelectMimeType import com.luck.picture.lib.entity.LocalMedia import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.pengxh.kt.lite.adapter.EditableImageAdapter import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px import com.pengxh.kt.lite.extensions.getScreenWidth import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.extensions.timestampToCompleteDate import com.pengxh.kt.lite.utils.ActivityStackManager import com.pengxh.kt.lite.utils.LoadState import com.pengxh.kt.lite.utils.LoadingDialog import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.AlertInputDialog import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import java.io.File import java.util.LinkedList import java.util.Queue class AddDeviceActivity : KotlinBaseActivity<ActivityAddDeviceBinding>() { private val kTag = "AddDeviceActivity" private lateinit var imageAdapter: EditableImageAdapter private lateinit var uploadImageViewModel: UploadImageViewModel private lateinit var deviceViewModel: DeviceViewModel private lateinit var groupViewModel: ProjectGroupViewModel private val context = this private val manager by lazy { QrManager.getInstance().init(QrConfigCreator.create(this)) } private val uploadQueue: Queue<LocalMedia> = LinkedList() // 用于存储待上传的图片 private var isUploading = false // 标记是否正在上传图片 private val imagePaths: ArrayList<String> = ArrayList() //服务器返回的拍照数据集 private val realPaths: ArrayList<String> = ArrayList() //真实图片路径 private val frequency = listOf("1min", "2min", "5min", "10min", "15min", "30min", "60min") private val selectLocationLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { val data = result.data!! binding.longitudeView.text = data.getStringExtra("longitude") binding.latitudeView.text = data.getStringExtra("latitude") } } override fun initViewBinding(): ActivityAddDeviceBinding { return ActivityAddDeviceBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener { override fun onLeftClick() { finish() } override fun onRightClick() { } }) } override fun initOnCreate(savedInstanceState: Bundle?) { ActivityStackManager.addActivity(this) uploadImageViewModel = ViewModelProvider(this)[UploadImageViewModel::class.java] uploadImageViewModel.commonResultData.observe(this) { isUploading = false if (it.code == 200) { val url = it.data.toString() imagePaths.add(url) val oldSize = realPaths.size realPaths.add(url.combineImagePath()) imageAdapter.notifyItemRangeChanged(oldSize, 1) startUploadNextImage() // 上传下一张图片 } } deviceViewModel = ViewModelProvider(this)[DeviceViewModel::class.java] groupViewModel = ViewModelProvider(this)[ProjectGroupViewModel::class.java] groupViewModel.groupListData.observe(this) { val groups = ArrayList<String>() if (it.code == 200) { if (it.data.isEmpty()) { groups.add("自定义") } else { it.data.forEach { id -> groups.add(id) } groups.add("自定义") } } else { groups.add("自定义") } if (groups.isNotEmpty()) { BottomActionSheet.Builder().setContext(this).setItemTextColor(Color.BLUE) .setActionItemTitle(groups) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { if (groups[position] == "自定义") { AlertInputDialog.Builder().setContext(context).setTitle("提示") .setHintMessage("请输入该设备所属项目名,如:项目203") .setNegativeButton("取消").setPositiveButton("确定") .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onCancelClick() { } override fun onConfirmClick(value: String) { binding.ownerShipView.text = value } }).build().show() } else { binding.ownerShipView.text = groups[position] } } }).build().show() } } val width = getScreenWidth() - 20.dp2px(this) imageAdapter = EditableImageAdapter(this, realPaths, width, 3, 3) binding.addImageRecyclerView.adapter = imageAdapter } override fun observeRequestState() { deviceViewModel.loadState.observe(this) { when (it) { LoadState.Loading -> LoadingDialog.show(this, "处理中,请稍后") LoadState.Success -> { "添加设备成功".show(this) LoadingDialog.dismiss() finish() } LoadState.Fail -> LoadingDialog.dismiss() } } } override fun initEvent() { binding.scannerView.setOnClickListener { manager.startScan(this) { if (it.content.isNumber()) { binding.deviceCodeView.setText(it.content) } else { "设备编号错误,请检查标签".show(context) } } } binding.ownerShipView.setOnClickListener { groupViewModel.getGroupList(this) } //默认频率1min binding.collectIntervalView.text = frequency[0] binding.collectIntervalView.setOnClickListener { BottomActionSheet.Builder().setContext(this).setItemTextColor(Color.BLUE) .setActionItemTitle(frequency) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { binding.collectIntervalView.text = frequency[position] } }).build().show() } binding.locationImageView.setOnClickListener { BottomActionSheet.Builder().setContext(context).setItemTextColor(Color.BLUE) .setActionItemTitle(arrayListOf("自动定位", "手动选点")) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { when (position) { 0 -> { LoadingDialog.show(this@AddDeviceActivity, "定位中,请稍后...") LocationHelper.getCurrentLocation(context, object : LocationHelper.ILocationListener { override fun onAMapLocationGet(aMapLocation: AMapLocation?) { LoadingDialog.dismiss() if (aMapLocation == null) { binding.longitudeView.text = "定位失败" binding.latitudeView.text = "定位失败" binding.longitudeView.setTextColor( R.color.redTextColor.convertColor(context) ) binding.latitudeView.setTextColor( R.color.redTextColor.convertColor(context) ) } else { binding.longitudeView.text = aMapLocation.longitude.toString() binding.latitudeView.text = aMapLocation.latitude.toString() binding.longitudeView.setTextColor( R.color.mainTextColor.convertColor(context) ) binding.latitudeView.setTextColor( R.color.mainTextColor.convertColor(context) ) } } }) } 1 -> selectLocationLauncher.launch( Intent(context, SelectLocationActivity::class.java) ) } } }).build().show() } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { override fun onAddImageClick() { selectPicture() } override fun onItemClick(position: Int) { if (realPaths[position].isEmpty()) { "图片加载失败,无法查看大图".show(context) } else { navigatePageTo<BigImageActivity>(position, realPaths) } } override fun onItemLongClick(view: View?, position: Int) { imagePaths.removeAt(position) realPaths.removeAt(position) imageAdapter.notifyItemRemoved(position) imageAdapter.notifyItemRangeChanged(position, realPaths.size - position) } }) binding.sceneEditView.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable?) { val text = s.toString().trim() binding.inputLengthView.text = String.format("${text.length}/100") if (text.length > 100) { binding.inputLengthView.setTextColor(R.color.redTextColor.convertColor(context)) "现场情况字符不能超过100个字符".show(context) } else { binding.inputLengthView.setTextColor(R.color.subTextColor.convertColor(context)) } } }) binding.addDeviceTimeView.text = System.currentTimeMillis().timestampToCompleteDate() binding.submitButton.setOnClickListener { val deviceCode = binding.deviceCodeView.text.toString().trim() if (deviceCode.isBlank()) { "请输入设备编号".show(context) return@setOnClickListener } val ownerShip = binding.ownerShipView.text.toString().trim() if (ownerShip.isBlank()) { "请输入设备所属项目".show(context) return@setOnClickListener } val longitude = binding.longitudeView.text.toString().trim() val latitude = binding.latitudeView.text.toString().trim() if (longitude.isBlank() || latitude.isBlank()) { "请先获取当前经纬度".show(context) return@setOnClickListener } deviceViewModel.addDevice( this, deviceCode, binding.deviceNameView.text.toString(), ownerShip, binding.collectIntervalView.text.toString(), longitude, latitude, imagePaths.reformat(), binding.sceneEditView.text.toString().trim(), binding.addDeviceTimeView.text.toString() ) } } private fun selectPicture() { BottomActionSheet.Builder().setContext(this).setItemTextColor(Color.BLUE) .setActionItemTitle(listOf("拍照", "相册")) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { when (position) { 0 -> { PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) .forResult(object : OnResultCallbackListener<LocalMedia> { override fun onResult(result: ArrayList<LocalMedia>) { uploadQueue.addAll(result) startUploadNextImage() } override fun onCancel() { } }) } 1 -> { PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) .setMaxSelectNum(3).isDisplayCamera(false) .setImageEngine(GlideLoadEngine.instance) .forResult(object : OnResultCallbackListener<LocalMedia> { override fun onResult(result: ArrayList<LocalMedia>) { uploadQueue.addAll(result) startUploadNextImage() } override fun onCancel() { } }) } } } }).build().show() } private fun startUploadNextImage() { if (isUploading || uploadQueue.isEmpty()) { return } isUploading = true val media = uploadQueue.poll() if (media != null) { media.realPath.compressImage(this, object : OnImageCompressListener { override fun onSuccess(file: File) { Log.d(kTag, "onSuccess: " + file.absolutePath) //上传图片 uploadImageViewModel.uploadImage(context, file) } override fun onError(e: Throwable) { e.printStackTrace() } }) } else { isUploading = false } } }