diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt new file mode 100644 index 0000000..3eca8e0 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt @@ -0,0 +1,118 @@ +package com.casic.app.smartwell.widgets + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.* +import android.widget.* +import com.casic.app.smartwell.R +import com.pengxh.app.multilib.utils.SizeUtil +import java.util.* + +class SingleChoiceDialog private constructor(builder: Builder) : Dialog( + builder.context!!, R.style.SingleChoiceDialogStyle +) { + private val ctx: Context? = builder.context + private val choiceItems: ArrayList? = builder.actionItems + private val clickListener: OnSingleChoiceClickListener? = builder.listener + + class Builder { + var context: Context? = null + var actionItems: ArrayList? = null + var listener: OnSingleChoiceClickListener? = null + fun setContext(context: Context?): Builder { + this.context = context + return this + } + + fun setChoiceItemTitles(items: ArrayList?): Builder { + actionItems = items + return this + } + + fun setOnSingleChoiceClickListener(listener: OnSingleChoiceClickListener?): Builder { + this.listener = listener + return this + } + + fun build(): SingleChoiceDialog { + return SingleChoiceDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + configDialogLayout() + setContentView(R.layout.dialog_single_choice) + setCancelable(false) + setCanceledOnTouchOutside(false) + val itemListView = findViewById(R.id.itemListView) + itemListView.adapter = ItemListAdapter() + itemListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> + dismiss() + clickListener!!.onItemClick(position) + } + } + + private fun configDialogLayout() { + val window = window ?: return + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.CENTER) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.SingleChoiceAnimation) + val params = window.attributes + params.width = (SizeUtil.getScreenWidth(ctx) * 0.75).toInt() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + } + + interface OnSingleChoiceClickListener { + fun onItemClick(position: Int) + } + + internal inner class ItemListAdapter : BaseAdapter() { + private val inflater = LayoutInflater.from(ctx) + override fun getCount(): Int { + return choiceItems!!.size + } + + override fun getItem(position: Int): Any { + return choiceItems!![position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View { + val view: View + val holder: ItemViewHolder + if (convertView == null) { + holder = ItemViewHolder() + view = inflater.inflate(R.layout.item_choice_dialog, null) + holder.choiceItemView = view.findViewById(R.id.choiceItemView) + view.tag = holder + } else { + view = convertView + holder = view.tag as ItemViewHolder + } + holder.choiceItemView!!.text = choiceItems!![position] + holder.choiceItemView!!.textSize = 18f + //需要动态设置item的高度 + val param = AbsListView.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + SizeUtil.dp2px(ctx, 46f) + ) + view.layoutParams = param + return view + } + } + + internal class ItemViewHolder { + var choiceItemView: TextView? = null + } + +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt new file mode 100644 index 0000000..3eca8e0 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt @@ -0,0 +1,118 @@ +package com.casic.app.smartwell.widgets + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.* +import android.widget.* +import com.casic.app.smartwell.R +import com.pengxh.app.multilib.utils.SizeUtil +import java.util.* + +class SingleChoiceDialog private constructor(builder: Builder) : Dialog( + builder.context!!, R.style.SingleChoiceDialogStyle +) { + private val ctx: Context? = builder.context + private val choiceItems: ArrayList? = builder.actionItems + private val clickListener: OnSingleChoiceClickListener? = builder.listener + + class Builder { + var context: Context? = null + var actionItems: ArrayList? = null + var listener: OnSingleChoiceClickListener? = null + fun setContext(context: Context?): Builder { + this.context = context + return this + } + + fun setChoiceItemTitles(items: ArrayList?): Builder { + actionItems = items + return this + } + + fun setOnSingleChoiceClickListener(listener: OnSingleChoiceClickListener?): Builder { + this.listener = listener + return this + } + + fun build(): SingleChoiceDialog { + return SingleChoiceDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + configDialogLayout() + setContentView(R.layout.dialog_single_choice) + setCancelable(false) + setCanceledOnTouchOutside(false) + val itemListView = findViewById(R.id.itemListView) + itemListView.adapter = ItemListAdapter() + itemListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> + dismiss() + clickListener!!.onItemClick(position) + } + } + + private fun configDialogLayout() { + val window = window ?: return + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.CENTER) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.SingleChoiceAnimation) + val params = window.attributes + params.width = (SizeUtil.getScreenWidth(ctx) * 0.75).toInt() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + } + + interface OnSingleChoiceClickListener { + fun onItemClick(position: Int) + } + + internal inner class ItemListAdapter : BaseAdapter() { + private val inflater = LayoutInflater.from(ctx) + override fun getCount(): Int { + return choiceItems!!.size + } + + override fun getItem(position: Int): Any { + return choiceItems!![position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View { + val view: View + val holder: ItemViewHolder + if (convertView == null) { + holder = ItemViewHolder() + view = inflater.inflate(R.layout.item_choice_dialog, null) + holder.choiceItemView = view.findViewById(R.id.choiceItemView) + view.tag = holder + } else { + view = convertView + holder = view.tag as ItemViewHolder + } + holder.choiceItemView!!.text = choiceItems!![position] + holder.choiceItemView!!.textSize = 18f + //需要动态设置item的高度 + val param = AbsListView.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + SizeUtil.dp2px(ctx, 46f) + ) + view.layoutParams = param + return view + } + } + + internal class ItemViewHolder { + var choiceItemView: TextView? = null + } + +} \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_hide.xml b/app/src/main/res/anim/action_dialog_hide.xml new file mode 100644 index 0000000..8bb3844 --- /dev/null +++ b/app/src/main/res/anim/action_dialog_hide.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt new file mode 100644 index 0000000..3eca8e0 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt @@ -0,0 +1,118 @@ +package com.casic.app.smartwell.widgets + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.* +import android.widget.* +import com.casic.app.smartwell.R +import com.pengxh.app.multilib.utils.SizeUtil +import java.util.* + +class SingleChoiceDialog private constructor(builder: Builder) : Dialog( + builder.context!!, R.style.SingleChoiceDialogStyle +) { + private val ctx: Context? = builder.context + private val choiceItems: ArrayList? = builder.actionItems + private val clickListener: OnSingleChoiceClickListener? = builder.listener + + class Builder { + var context: Context? = null + var actionItems: ArrayList? = null + var listener: OnSingleChoiceClickListener? = null + fun setContext(context: Context?): Builder { + this.context = context + return this + } + + fun setChoiceItemTitles(items: ArrayList?): Builder { + actionItems = items + return this + } + + fun setOnSingleChoiceClickListener(listener: OnSingleChoiceClickListener?): Builder { + this.listener = listener + return this + } + + fun build(): SingleChoiceDialog { + return SingleChoiceDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + configDialogLayout() + setContentView(R.layout.dialog_single_choice) + setCancelable(false) + setCanceledOnTouchOutside(false) + val itemListView = findViewById(R.id.itemListView) + itemListView.adapter = ItemListAdapter() + itemListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> + dismiss() + clickListener!!.onItemClick(position) + } + } + + private fun configDialogLayout() { + val window = window ?: return + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.CENTER) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.SingleChoiceAnimation) + val params = window.attributes + params.width = (SizeUtil.getScreenWidth(ctx) * 0.75).toInt() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + } + + interface OnSingleChoiceClickListener { + fun onItemClick(position: Int) + } + + internal inner class ItemListAdapter : BaseAdapter() { + private val inflater = LayoutInflater.from(ctx) + override fun getCount(): Int { + return choiceItems!!.size + } + + override fun getItem(position: Int): Any { + return choiceItems!![position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View { + val view: View + val holder: ItemViewHolder + if (convertView == null) { + holder = ItemViewHolder() + view = inflater.inflate(R.layout.item_choice_dialog, null) + holder.choiceItemView = view.findViewById(R.id.choiceItemView) + view.tag = holder + } else { + view = convertView + holder = view.tag as ItemViewHolder + } + holder.choiceItemView!!.text = choiceItems!![position] + holder.choiceItemView!!.textSize = 18f + //需要动态设置item的高度 + val param = AbsListView.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + SizeUtil.dp2px(ctx, 46f) + ) + view.layoutParams = param + return view + } + } + + internal class ItemViewHolder { + var choiceItemView: TextView? = null + } + +} \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_hide.xml b/app/src/main/res/anim/action_dialog_hide.xml new file mode 100644 index 0000000..8bb3844 --- /dev/null +++ b/app/src/main/res/anim/action_dialog_hide.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_show.xml b/app/src/main/res/anim/action_dialog_show.xml new file mode 100644 index 0000000..1d281ef --- /dev/null +++ b/app/src/main/res/anim/action_dialog_show.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt new file mode 100644 index 0000000..3eca8e0 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt @@ -0,0 +1,118 @@ +package com.casic.app.smartwell.widgets + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.* +import android.widget.* +import com.casic.app.smartwell.R +import com.pengxh.app.multilib.utils.SizeUtil +import java.util.* + +class SingleChoiceDialog private constructor(builder: Builder) : Dialog( + builder.context!!, R.style.SingleChoiceDialogStyle +) { + private val ctx: Context? = builder.context + private val choiceItems: ArrayList? = builder.actionItems + private val clickListener: OnSingleChoiceClickListener? = builder.listener + + class Builder { + var context: Context? = null + var actionItems: ArrayList? = null + var listener: OnSingleChoiceClickListener? = null + fun setContext(context: Context?): Builder { + this.context = context + return this + } + + fun setChoiceItemTitles(items: ArrayList?): Builder { + actionItems = items + return this + } + + fun setOnSingleChoiceClickListener(listener: OnSingleChoiceClickListener?): Builder { + this.listener = listener + return this + } + + fun build(): SingleChoiceDialog { + return SingleChoiceDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + configDialogLayout() + setContentView(R.layout.dialog_single_choice) + setCancelable(false) + setCanceledOnTouchOutside(false) + val itemListView = findViewById(R.id.itemListView) + itemListView.adapter = ItemListAdapter() + itemListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> + dismiss() + clickListener!!.onItemClick(position) + } + } + + private fun configDialogLayout() { + val window = window ?: return + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.CENTER) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.SingleChoiceAnimation) + val params = window.attributes + params.width = (SizeUtil.getScreenWidth(ctx) * 0.75).toInt() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + } + + interface OnSingleChoiceClickListener { + fun onItemClick(position: Int) + } + + internal inner class ItemListAdapter : BaseAdapter() { + private val inflater = LayoutInflater.from(ctx) + override fun getCount(): Int { + return choiceItems!!.size + } + + override fun getItem(position: Int): Any { + return choiceItems!![position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View { + val view: View + val holder: ItemViewHolder + if (convertView == null) { + holder = ItemViewHolder() + view = inflater.inflate(R.layout.item_choice_dialog, null) + holder.choiceItemView = view.findViewById(R.id.choiceItemView) + view.tag = holder + } else { + view = convertView + holder = view.tag as ItemViewHolder + } + holder.choiceItemView!!.text = choiceItems!![position] + holder.choiceItemView!!.textSize = 18f + //需要动态设置item的高度 + val param = AbsListView.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + SizeUtil.dp2px(ctx, 46f) + ) + view.layoutParams = param + return view + } + } + + internal class ItemViewHolder { + var choiceItemView: TextView? = null + } + +} \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_hide.xml b/app/src/main/res/anim/action_dialog_hide.xml new file mode 100644 index 0000000..8bb3844 --- /dev/null +++ b/app/src/main/res/anim/action_dialog_hide.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_show.xml b/app/src/main/res/anim/action_dialog_show.xml new file mode 100644 index 0000000..1d281ef --- /dev/null +++ b/app/src/main/res/anim/action_dialog_show.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_determine_detail.xml b/app/src/main/res/layout/activity_order_determine_detail.xml index b38af39..8ccbf85 100644 --- a/app/src/main/res/layout/activity_order_determine_detail.xml +++ b/app/src/main/res/layout/activity_order_determine_detail.xml @@ -325,7 +325,7 @@ android:padding="@dimen/dp_20"> + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt new file mode 100644 index 0000000..3eca8e0 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt @@ -0,0 +1,118 @@ +package com.casic.app.smartwell.widgets + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.* +import android.widget.* +import com.casic.app.smartwell.R +import com.pengxh.app.multilib.utils.SizeUtil +import java.util.* + +class SingleChoiceDialog private constructor(builder: Builder) : Dialog( + builder.context!!, R.style.SingleChoiceDialogStyle +) { + private val ctx: Context? = builder.context + private val choiceItems: ArrayList? = builder.actionItems + private val clickListener: OnSingleChoiceClickListener? = builder.listener + + class Builder { + var context: Context? = null + var actionItems: ArrayList? = null + var listener: OnSingleChoiceClickListener? = null + fun setContext(context: Context?): Builder { + this.context = context + return this + } + + fun setChoiceItemTitles(items: ArrayList?): Builder { + actionItems = items + return this + } + + fun setOnSingleChoiceClickListener(listener: OnSingleChoiceClickListener?): Builder { + this.listener = listener + return this + } + + fun build(): SingleChoiceDialog { + return SingleChoiceDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + configDialogLayout() + setContentView(R.layout.dialog_single_choice) + setCancelable(false) + setCanceledOnTouchOutside(false) + val itemListView = findViewById(R.id.itemListView) + itemListView.adapter = ItemListAdapter() + itemListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> + dismiss() + clickListener!!.onItemClick(position) + } + } + + private fun configDialogLayout() { + val window = window ?: return + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.CENTER) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.SingleChoiceAnimation) + val params = window.attributes + params.width = (SizeUtil.getScreenWidth(ctx) * 0.75).toInt() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + } + + interface OnSingleChoiceClickListener { + fun onItemClick(position: Int) + } + + internal inner class ItemListAdapter : BaseAdapter() { + private val inflater = LayoutInflater.from(ctx) + override fun getCount(): Int { + return choiceItems!!.size + } + + override fun getItem(position: Int): Any { + return choiceItems!![position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View { + val view: View + val holder: ItemViewHolder + if (convertView == null) { + holder = ItemViewHolder() + view = inflater.inflate(R.layout.item_choice_dialog, null) + holder.choiceItemView = view.findViewById(R.id.choiceItemView) + view.tag = holder + } else { + view = convertView + holder = view.tag as ItemViewHolder + } + holder.choiceItemView!!.text = choiceItems!![position] + holder.choiceItemView!!.textSize = 18f + //需要动态设置item的高度 + val param = AbsListView.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + SizeUtil.dp2px(ctx, 46f) + ) + view.layoutParams = param + return view + } + } + + internal class ItemViewHolder { + var choiceItemView: TextView? = null + } + +} \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_hide.xml b/app/src/main/res/anim/action_dialog_hide.xml new file mode 100644 index 0000000..8bb3844 --- /dev/null +++ b/app/src/main/res/anim/action_dialog_hide.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_show.xml b/app/src/main/res/anim/action_dialog_show.xml new file mode 100644 index 0000000..1d281ef --- /dev/null +++ b/app/src/main/res/anim/action_dialog_show.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_determine_detail.xml b/app/src/main/res/layout/activity_order_determine_detail.xml index b38af39..8ccbf85 100644 --- a/app/src/main/res/layout/activity_order_determine_detail.xml +++ b/app/src/main/res/layout/activity_order_determine_detail.xml @@ -325,7 +325,7 @@ android:padding="@dimen/dp_20"> + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt new file mode 100644 index 0000000..3eca8e0 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt @@ -0,0 +1,118 @@ +package com.casic.app.smartwell.widgets + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.* +import android.widget.* +import com.casic.app.smartwell.R +import com.pengxh.app.multilib.utils.SizeUtil +import java.util.* + +class SingleChoiceDialog private constructor(builder: Builder) : Dialog( + builder.context!!, R.style.SingleChoiceDialogStyle +) { + private val ctx: Context? = builder.context + private val choiceItems: ArrayList? = builder.actionItems + private val clickListener: OnSingleChoiceClickListener? = builder.listener + + class Builder { + var context: Context? = null + var actionItems: ArrayList? = null + var listener: OnSingleChoiceClickListener? = null + fun setContext(context: Context?): Builder { + this.context = context + return this + } + + fun setChoiceItemTitles(items: ArrayList?): Builder { + actionItems = items + return this + } + + fun setOnSingleChoiceClickListener(listener: OnSingleChoiceClickListener?): Builder { + this.listener = listener + return this + } + + fun build(): SingleChoiceDialog { + return SingleChoiceDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + configDialogLayout() + setContentView(R.layout.dialog_single_choice) + setCancelable(false) + setCanceledOnTouchOutside(false) + val itemListView = findViewById(R.id.itemListView) + itemListView.adapter = ItemListAdapter() + itemListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> + dismiss() + clickListener!!.onItemClick(position) + } + } + + private fun configDialogLayout() { + val window = window ?: return + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.CENTER) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.SingleChoiceAnimation) + val params = window.attributes + params.width = (SizeUtil.getScreenWidth(ctx) * 0.75).toInt() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + } + + interface OnSingleChoiceClickListener { + fun onItemClick(position: Int) + } + + internal inner class ItemListAdapter : BaseAdapter() { + private val inflater = LayoutInflater.from(ctx) + override fun getCount(): Int { + return choiceItems!!.size + } + + override fun getItem(position: Int): Any { + return choiceItems!![position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View { + val view: View + val holder: ItemViewHolder + if (convertView == null) { + holder = ItemViewHolder() + view = inflater.inflate(R.layout.item_choice_dialog, null) + holder.choiceItemView = view.findViewById(R.id.choiceItemView) + view.tag = holder + } else { + view = convertView + holder = view.tag as ItemViewHolder + } + holder.choiceItemView!!.text = choiceItems!![position] + holder.choiceItemView!!.textSize = 18f + //需要动态设置item的高度 + val param = AbsListView.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + SizeUtil.dp2px(ctx, 46f) + ) + view.layoutParams = param + return view + } + } + + internal class ItemViewHolder { + var choiceItemView: TextView? = null + } + +} \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_hide.xml b/app/src/main/res/anim/action_dialog_hide.xml new file mode 100644 index 0000000..8bb3844 --- /dev/null +++ b/app/src/main/res/anim/action_dialog_hide.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_show.xml b/app/src/main/res/anim/action_dialog_show.xml new file mode 100644 index 0000000..1d281ef --- /dev/null +++ b/app/src/main/res/anim/action_dialog_show.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_determine_detail.xml b/app/src/main/res/layout/activity_order_determine_detail.xml index b38af39..8ccbf85 100644 --- a/app/src/main/res/layout/activity_order_determine_detail.xml +++ b/app/src/main/res/layout/activity_order_determine_detail.xml @@ -325,7 +325,7 @@ android:padding="@dimen/dp_20"> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_choice_dialog.xml b/app/src/main/res/layout/item_choice_dialog.xml new file mode 100644 index 0000000..9d61fbc --- /dev/null +++ b/app/src/main/res/layout/item_choice_dialog.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5060744..ca9f2f8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + diff --git a/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt new file mode 100644 index 0000000..f3cbd4e --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/model/SubordinateModel.kt @@ -0,0 +1,17 @@ +package com.casic.app.smartwell.model + +class SubordinateModel { + var code = 0 + var data: List? = null + var message: String? = null + var isSuccess = false + + class DataBean { + var account: String? = null + var attr1: String? = null + var deptId: String? = null + var id: String? = null + var name: String? = null + var phone: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 6ed5ca0..66baa5e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -12,14 +12,18 @@ Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION + Manifest.permission.ACCESS_BACKGROUND_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } else { arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA ) } diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..509a9c2 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -0,0 +1,78 @@ +package com.casic.app.smartwell.utils + +import android.os.Environment +import android.util.Log +import com.casic.app.smartwell.base.BaseApplication +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +object FileUtils { + private const val Tag = "FileUtils" + private val context = BaseApplication.obtainInstance() + private var index = 1 + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } + + //储存下载文件的目录 + private val downloadFilePath: String + get() { + val downloadDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") + if (!downloadDir.exists()) { + downloadDir.mkdir() + } + return downloadDir.toString() + } + + val documentFile: File + get() { + val documentDir = File( + context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "" + ) + //以天区分名字 + val timeStamp = SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(Date()) + val logFile = + File(documentDir.toString() + File.separator + "Log_" + timeStamp + ".txt") + if (!logFile.exists()) { + try { + logFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return logFile + } + + val waterImageFile: File + get() { + val waterImageDir = + File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "WaterImage") + if (!waterImageDir.exists()) { + val mkdir = waterImageDir.mkdir() + if (mkdir) { + Log.d(Tag, "创建WaterImage文件夹") + } + } + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(Date()) + //index用来区分for循环太快会导致多想图片覆盖压缩问题 + val imageFile = + File(waterImageDir.toString() + File.separator + "IMG_" + timeStamp + "_" + (index++) + ".png") + if (!imageFile.exists()) { + try { + imageFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + return imageFile + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..8e9a77a --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,77 @@ +package com.casic.app.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.widget.ImageView +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.BitmapImageViewTarget +import com.casic.app.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.listener.OnImageCompleteCallback +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView + +class GlideLoadEngine private constructor() : ImageEngine { + companion object { + private var instance: GlideLoadEngine? = null + fun createGlideEngine(): GlideLoadEngine? { + if (null == instance) { + synchronized(GlideLoadEngine::class.java) { + if (null == instance) { + instance = GlideLoadEngine() + } + } + } + return instance + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).load(url).into(imageView) + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView, + callback: OnImageCompleteCallback + ) { + + } + + override fun loadImage( + context: Context, + url: String, + imageView: ImageView, + longImageView: SubsamplingScaleImageView + ) { + } + + override fun loadFolderImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(object : BitmapImageViewTarget(imageView) { + override fun setResource(resource: Bitmap?) { + val circularBitmapDrawable = + RoundedBitmapDrawableFactory.create(context.resources, resource) + circularBitmapDrawable.cornerRadius = 8f + imageView.setImageDrawable(circularBitmapDrawable) + } + }) + } + + override fun loadAsGifImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context).asGif().load(url).into(imageView) + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt index 8395e15..b1ca3bb 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.app.smartwell.utils.retrofit import com.casic.app.smartwell.model.* +import okhttp3.MultipartBody import retrofit2.http.* @@ -117,6 +118,29 @@ ): CommonResultModel /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): CommonResultModel + + /** + * 查找同一单位下的用户 + * */ + @FormUrlEncoded + @POST("/mgr/simplelist") + suspend fun obtainSubordinate( + @Header("token") token: String, + @Field("hasMine") hasMine: String?, + @Field("roleTips") roleTips: String? + ): SubordinateModel + + /** * 告警内容列表 * */ @GET("/alarm/contentType") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt index 1223036..047d931 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.app.smartwell.model.* import com.casic.app.smartwell.utils.AuthenticationHelper import com.casic.app.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -110,6 +114,22 @@ } /** + * 上传图片 + */ + suspend fun uploadImage(image: File): CommonResultModel { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } + + /** + * 查找同一单位下的用户 + */ + suspend fun obtainSubordinate(hasMine: String?, roleTips: String?): SubordinateModel { + return api.obtainSubordinate(AuthenticationHelper.token!!, hasMine, roleTips) + } + + /** * 告警内容列表 */ suspend fun obtainAlarmContentType(): AlarmContentTypeModel { diff --git a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt index 25f1340..0375107 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/OrderDetermineDetailActivity.kt @@ -1,5 +1,8 @@ package com.casic.app.smartwell.view +import android.app.Activity +import android.content.Context +import android.content.Intent import android.view.View import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager @@ -10,17 +13,38 @@ import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.extensions.toChinese -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.* +import com.casic.app.smartwell.vm.SubordinateViewModel +import com.casic.app.smartwell.vm.UploadImageViewModel import com.casic.app.smartwell.vm.WorkOrderDetailViewModel +import com.casic.app.smartwell.widgets.SingleChoiceDialog +import com.luck.picture.lib.PictureSelector +import com.luck.picture.lib.config.PictureConfig +import com.luck.picture.lib.config.PictureMimeType import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import com.pengxh.app.multilib.widget.dialog.BottomActionSheet +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog +import kotlinx.android.synthetic.main.activity_order_detail.* import kotlinx.android.synthetic.main.activity_order_determine_detail.* +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmContentView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmLevelView +import kotlinx.android.synthetic.main.activity_order_determine_detail.alarmValueView +import kotlinx.android.synthetic.main.activity_order_determine_detail.completedDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.devCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.dispatchDateView +import kotlinx.android.synthetic.main.activity_order_determine_detail.orderCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.tipsImageView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellCodeView +import kotlinx.android.synthetic.main.activity_order_determine_detail.wellLocationView import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File class OrderDetermineDetailActivity : BaseActivity() { private lateinit var workOrderDetailViewModel: WorkOrderDetailViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + private lateinit var subordinateViewModel: SubordinateViewModel private lateinit var imageAdapter: NineGridImageAdapter private lateinit var jobId: String private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 @@ -42,6 +66,8 @@ addImageRecyclerView.adapter = imageAdapter workOrderDetailViewModel = ViewModelProvider(this).get(WorkOrderDetailViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) + subordinateViewModel = ViewModelProvider(this).get(SubordinateViewModel::class.java) } override fun initEvent() { @@ -84,9 +110,33 @@ completedDateView.text = orderDetail.handleJobTime //转单 + transferOrderButton.setChangeAlphaWhenPress(true) + transferOrderButton.setOnClickListener { + subordinateViewModel.obtainSubordinate("0", "leader,member") + } + subordinateViewModel.listModel.observe(this, { subordinate -> + if (subordinate.code == 200) { + val roleArray: ArrayList = ArrayList() //下级流转人员集合 + subordinate.data?.forEach { dataBean -> + roleArray.add(dataBean.name.toString()) + } + SingleChoiceDialog.Builder() + .setContext(this) + .setChoiceItemTitles(roleArray) + .setOnSingleChoiceClickListener(object : + SingleChoiceDialog.OnSingleChoiceClickListener { + override fun onItemClick(position: Int) { + } + }).build().show() + } + }) //提交 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + + } } }) @@ -104,7 +154,7 @@ imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { override fun onAddImageClick() { -// selectPicture() + selectPicture() } override fun onItemClick(position: Int) { @@ -124,5 +174,77 @@ imageAdapter.deleteImage(position) } }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .forResult(PictureConfig.REQUEST_CAMERA) + } + 1 -> { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .isWeChatStyle(true) + .isCamera(false) + .isCompress(true) + .compressSavePath(FileUtils.imageCompressPath) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST) + } + } + }.build().show() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK) { + when (requestCode) { + PictureConfig.CHOOSE_REQUEST -> { + val selectResult = PictureSelector.obtainMultipleResult(data) + showLoadingDialog(this, "图片上传中,请稍后...") + for (res in selectResult) { + val file = File(res.compressPath) + //上传图片 + uploadImageViewModel.uploadImage(image = file) + } + } + PictureConfig.REQUEST_CAMERA -> { + val cameraResult = PictureSelector.obtainMultipleResult(data)[0] + //上传图片 + uploadImageViewModel.uploadImage(image = File(cameraResult.compressPath)) + } + } + } + } + + private var loadingDialog: QMUITipDialog? = null + + fun showLoadingDialog(context: Context?, message: String?) { + loadingDialog = QMUITipDialog.Builder(context) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord(message) + .create() + loadingDialog!!.show() + } + + fun dismissLoadingDialog() { + if (loadingDialog != null) { + if (loadingDialog!!.isShowing) { + loadingDialog!!.dismiss() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt index b5ade26..ab7bdf8 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/WorkOrderDetailActivity.kt @@ -118,23 +118,23 @@ return@setOnClickListener } wellDetailViewModel.obtainWellDetail(id = wellId) - wellDetailViewModel.detailModel.observe(this, { well -> - if (well.code == 200) { - val wellDetail = well.data!! - val lat = wellDetail.latGaode.toString() - val lng = wellDetail.lngGaode.toString() - if (lat == "" || lng == "") { - "窨井经纬度异常,无法开启导航".show(this) - } else { - Poi( - orderDetail.position, - LatLng(lat.toDouble(), lng.toDouble()), - "" - ).showRouteOnMap(this) - } - } - }) } + wellDetailViewModel.detailModel.observe(this, { well -> + if (well.code == 200) { + val wellDetail = well.data!! + val lat = wellDetail.latGaode.toString() + val lng = wellDetail.lngGaode.toString() + if (lat == "" || lng == "") { + "窨井经纬度异常,无法开启导航".show(this) + } else { + Poi( + orderDetail.position, + LatLng(lat.toDouble(), lng.toDouble()), + "" + ).showRouteOnMap(this) + } + } + }) } }) //数据加载状态处理 diff --git a/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt new file mode 100644 index 0000000..9e29a84 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/SubordinateViewModel.kt @@ -0,0 +1,23 @@ +package com.casic.app.smartwell.vm + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.SubordinateModel +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager + +/** + * 转单下一级人员 + * */ +class SubordinateViewModel : BaseViewModel() { + + private val kTag = "SubordinateViewModel" + val listModel = MutableLiveData() + + fun obtainSubordinate(hasMine: String?, roleTips: String?) = launch({ + listModel.value = RetrofitServiceManager.obtainSubordinate(hasMine, roleTips) + }, { + Log.d(kTag, "obtainSubordinate: ${it.printStackTrace()}") + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..acf7576 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,20 @@ +package com.casic.app.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.app.smartwell.base.BaseViewModel +import com.casic.app.smartwell.extensions.launch +import com.casic.app.smartwell.model.CommonResultModel +import com.casic.app.smartwell.utils.LoadState +import com.casic.app.smartwell.utils.retrofit.RetrofitServiceManager +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + resultModel.value = RetrofitServiceManager.uploadImage(image) + loadState.value = LoadState.Success + }, { + loadState.value = LoadState.Fail + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt new file mode 100644 index 0000000..3eca8e0 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/widgets/SingleChoiceDialog.kt @@ -0,0 +1,118 @@ +package com.casic.app.smartwell.widgets + +import android.app.Dialog +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.* +import android.widget.* +import com.casic.app.smartwell.R +import com.pengxh.app.multilib.utils.SizeUtil +import java.util.* + +class SingleChoiceDialog private constructor(builder: Builder) : Dialog( + builder.context!!, R.style.SingleChoiceDialogStyle +) { + private val ctx: Context? = builder.context + private val choiceItems: ArrayList? = builder.actionItems + private val clickListener: OnSingleChoiceClickListener? = builder.listener + + class Builder { + var context: Context? = null + var actionItems: ArrayList? = null + var listener: OnSingleChoiceClickListener? = null + fun setContext(context: Context?): Builder { + this.context = context + return this + } + + fun setChoiceItemTitles(items: ArrayList?): Builder { + actionItems = items + return this + } + + fun setOnSingleChoiceClickListener(listener: OnSingleChoiceClickListener?): Builder { + this.listener = listener + return this + } + + fun build(): SingleChoiceDialog { + return SingleChoiceDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + configDialogLayout() + setContentView(R.layout.dialog_single_choice) + setCancelable(false) + setCanceledOnTouchOutside(false) + val itemListView = findViewById(R.id.itemListView) + itemListView.adapter = ItemListAdapter() + itemListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ -> + dismiss() + clickListener!!.onItemClick(position) + } + } + + private fun configDialogLayout() { + val window = window ?: return + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setGravity(Gravity.CENTER) + //设置Dialog出现的动画 + window.setWindowAnimations(R.style.SingleChoiceAnimation) + val params = window.attributes + params.width = (SizeUtil.getScreenWidth(ctx) * 0.75).toInt() + params.height = WindowManager.LayoutParams.WRAP_CONTENT + window.attributes = params + } + + interface OnSingleChoiceClickListener { + fun onItemClick(position: Int) + } + + internal inner class ItemListAdapter : BaseAdapter() { + private val inflater = LayoutInflater.from(ctx) + override fun getCount(): Int { + return choiceItems!!.size + } + + override fun getItem(position: Int): Any { + return choiceItems!![position] + } + + override fun getItemId(position: Int): Long { + return position.toLong() + } + + override fun getView(position: Int, convertView: View?, viewGroup: ViewGroup): View { + val view: View + val holder: ItemViewHolder + if (convertView == null) { + holder = ItemViewHolder() + view = inflater.inflate(R.layout.item_choice_dialog, null) + holder.choiceItemView = view.findViewById(R.id.choiceItemView) + view.tag = holder + } else { + view = convertView + holder = view.tag as ItemViewHolder + } + holder.choiceItemView!!.text = choiceItems!![position] + holder.choiceItemView!!.textSize = 18f + //需要动态设置item的高度 + val param = AbsListView.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + SizeUtil.dp2px(ctx, 46f) + ) + view.layoutParams = param + return view + } + } + + internal class ItemViewHolder { + var choiceItemView: TextView? = null + } + +} \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_hide.xml b/app/src/main/res/anim/action_dialog_hide.xml new file mode 100644 index 0000000..8bb3844 --- /dev/null +++ b/app/src/main/res/anim/action_dialog_hide.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/action_dialog_show.xml b/app/src/main/res/anim/action_dialog_show.xml new file mode 100644 index 0000000..1d281ef --- /dev/null +++ b/app/src/main/res/anim/action_dialog_show.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_determine_detail.xml b/app/src/main/res/layout/activity_order_determine_detail.xml index b38af39..8ccbf85 100644 --- a/app/src/main/res/layout/activity_order_determine_detail.xml +++ b/app/src/main/res/layout/activity_order_determine_detail.xml @@ -325,7 +325,7 @@ android:padding="@dimen/dp_20"> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_choice_dialog.xml b/app/src/main/res/layout/item_choice_dialog.xml new file mode 100644 index 0000000..9d61fbc --- /dev/null +++ b/app/src/main/res/layout/item_choice_dialog.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c049162..bef4fcd 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -118,4 +118,25 @@ @dimen/dp_5 @dimen/dp_5 + + + +