package com.casic.smarttube.fragment import android.content.Intent import android.net.Uri import android.os.Bundle import android.os.CountDownTimer import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import com.casic.smarttube.databinding.FragmentMineBinding import com.casic.smarttube.extensions.compareVersion import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.FileDownloadManager import com.casic.smarttube.utils.LocaleConstant import com.casic.smarttube.utils.RSAUtils import com.casic.smarttube.view.AboutUsActivity import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel import com.casic.smarttube.vm.VersionViewModel import com.casic.smarttube.widgets.ProgressDialog import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment import com.pengxh.kt.lite.extensions.calculateSize import com.pengxh.kt.lite.extensions.createDownloadFileDir import com.pengxh.kt.lite.extensions.deleteFile import com.pengxh.kt.lite.extensions.formatFileSize import com.pengxh.kt.lite.extensions.isNetworkConnected import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show 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.utils.SaveKeyValues import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment<FragmentMineBinding>() { private val kTag = "MinePageFragment" private val gson = Gson() private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel private lateinit var versionViewModel: VersionViewModel override fun initViewBinding( inflater: LayoutInflater, container: ViewGroup? ): FragmentMineBinding { return FragmentMineBinding.inflate(inflater, container, false) } override fun setupTopBarLayout() { } override fun initOnCreate(savedInstanceState: Bundle?) { loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java] userViewModel = ViewModelProvider(this)[UserViewModel::class.java] versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java] } override fun observeRequestState() { userViewModel.loadState.observe(this) { when (it) { is LoadState.Loading -> LoadingDialog.show(requireActivity(), "修改中,请稍后") is LoadState.Success -> { "修改成功,请重新登录".show(requireContext()) LoadingDialog.dismiss() AuthenticationHelper.removeToken() requireContext().navigatePageTo<LoginActivity>() ActivityStackManager.finishAllActivity() } else -> LoadingDialog.dismiss() } } versionViewModel.loadState.observe(this) { when (it) { is LoadState.Loading -> LoadingDialog.show( requireActivity(), "检查版本中,请稍后" ) else -> LoadingDialog.dismiss() } } } override fun initEvent() { binding.userImageView.setOnClickListener { "尽情期待~".show(requireContext()) } binding.loginOutButton.setOnClickListener { AlertControlDialog.Builder().setContext(requireContext()).setTitle("退出登录") .setMessage("确定要退出吗?").setNegativeButton("取消").setPositiveButton("确定") .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { if (!requireActivity().isNetworkConnected()) { "网络异常,退出失败".show(requireContext()) return } loginViewModel.out(requireContext()) } override fun onCancelClick() {} }).build().show() } binding.changePwdLayout.setOnClickListener { ChangePasswordDialog.Builder().setContext(requireContext()) .setOnDialogButtonClickListener(object : ChangePasswordDialog.OnDialogButtonClickListener { override fun onConfirmClick(oldPwd: String, newPwd: String) { val publicKey = RSAUtils.keyStrToPublicKey(AuthenticationHelper.publicKey)!! val oldPassKey = RSAUtils.encryptDataByPublicKey( oldPwd.toByteArray(StandardCharsets.UTF_8), publicKey ) val newPassKey = RSAUtils.encryptDataByPublicKey( newPwd.toByteArray(StandardCharsets.UTF_8), publicKey ) userViewModel.changePassword(requireContext(), oldPassKey, newPassKey) } }).build().show() } binding.aboutUsLayout.setOnClickListener { requireContext().navigatePageTo<AboutUsActivity>() } binding.updateVersionLayout.setOnClickListener { versionViewModel.updateVersion(requireContext()) } binding.updateLogLayout.setOnClickListener { "尽情期待~".show(requireContext()) } binding.clearCacheLayout.setOnClickListener { //删除缓存之后在设置缓存大小 LoadingDialog.show(requireActivity(), "清理中,请稍后") File(requireContext().cacheDir.path).deleteFile() object : CountDownTimer(1500, 500) { override fun onTick(millisUntilFinished: Long) { } override fun onFinish() { LoadingDialog.dismiss() binding.cacheSizeView.text = collectApplicationCache().formatFileSize() } }.start() } binding.phoneNumberView.setOnClickListener { val intent = Intent() intent.action = Intent.ACTION_CALL intent.data = Uri.parse("tel:${binding.phoneNumberView.text}") startActivity(intent) } /** * 数据监听 * */ dataObserve() } private fun dataObserve() { versionViewModel.versionResultData.observe(this) { if (it.version.compareVersion()) { "已是最新版本,无需更新".show(requireContext()) } else { AlertControlDialog.Builder().setContext(requireContext()).setTitle("提示") .setMessage("有新版本,是否更新?").setNegativeButton("稍后再说") .setPositiveButton("立即下载").setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { downloadApk(it.downloadUrl) } override fun onCancelClick() { } }).build().show() } } loginViewModel.outResultData.observe(this) { if (it.code == 200) { AuthenticationHelper.removeToken() ActivityStackManager.finishAllActivity() } } } private fun collectApplicationCache(): Long { return File(requireContext().cacheDir.path).calculateSize() } override fun onResume() { super.onResume() val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_KEY, "") as String if (userDetailJson.isNotBlank()) { val userData = gson.fromJson<UserDetailModel.Data>( userDetailJson, object : TypeToken<UserDetailModel.Data>() {}.type ) binding.userNameView.text = userData.name binding.userPhoneView.text = String.format("电话:${userData.phone}") binding.userDeptView.text = String.format("部门:${userData.deptName}") } //缓存 binding.cacheSizeView.text = collectApplicationCache().formatFileSize() } private fun downloadApk(url: String) { val progressDialog = ProgressDialog(requireContext()) progressDialog.show() FileDownloadManager.Builder() .setDownloadFileSource(url) .setFileSuffix("apk") .setFileSaveDirectory(requireContext().createDownloadFileDir()) .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener { override fun onDownloadStart(total: Long) { progressDialog.setMaxProgress(total) } override fun onDownloadEnd(file: File) { progressDialog.dismiss() //安装APK文件 installApk(file) } override fun onFailed(t: Throwable) { t.printStackTrace() progressDialog.dismiss() } override fun onProgressChanged(progress: Long) { progressDialog.updateProgress(progress) } }).build().start() } private fun installApk(file: File) { val apkUri = FileProvider.getUriForFile( requireContext(), "${requireContext().packageName}.provider", file ) val intent = Intent(Intent.ACTION_VIEW).apply { setDataAndType(apkUri, "application/vnd.android.package-archive") addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK) } requireContext().startActivity(intent) } }