diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_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 b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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 b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.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 b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.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 b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.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 b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_completed_detail.xml b/app/src/main/res/layout/activity_order_completed_detail.xml new file mode 100644 index 0000000..8b2f135 --- /dev/null +++ b/app/src/main/res/layout/activity_order_completed_detail.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_completed_detail.xml b/app/src/main/res/layout/activity_order_completed_detail.xml new file mode 100644 index 0000000..8b2f135 --- /dev/null +++ b/app/src/main/res/layout/activity_order_completed_detail.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_in_handle_detail.xml b/app/src/main/res/layout/activity_order_in_handle_detail.xml new file mode 100644 index 0000000..fb7ccd1 --- /dev/null +++ b/app/src/main/res/layout/activity_order_in_handle_detail.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_completed_detail.xml b/app/src/main/res/layout/activity_order_completed_detail.xml new file mode 100644 index 0000000..8b2f135 --- /dev/null +++ b/app/src/main/res/layout/activity_order_completed_detail.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_in_handle_detail.xml b/app/src/main/res/layout/activity_order_in_handle_detail.xml new file mode 100644 index 0000000..fb7ccd1 --- /dev/null +++ b/app/src/main/res/layout/activity_order_in_handle_detail.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_base_order_detail.xml b/app/src/main/res/layout/include_base_order_detail.xml new file mode 100644 index 0000000..0b489ac --- /dev/null +++ b/app/src/main/res/layout/include_base_order_detail.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_completed_detail.xml b/app/src/main/res/layout/activity_order_completed_detail.xml new file mode 100644 index 0000000..8b2f135 --- /dev/null +++ b/app/src/main/res/layout/activity_order_completed_detail.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_in_handle_detail.xml b/app/src/main/res/layout/activity_order_in_handle_detail.xml new file mode 100644 index 0000000..fb7ccd1 --- /dev/null +++ b/app/src/main/res/layout/activity_order_in_handle_detail.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_base_order_detail.xml b/app/src/main/res/layout/include_base_order_detail.xml new file mode 100644 index 0000000..0b489ac --- /dev/null +++ b/app/src/main/res/layout/include_base_order_detail.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml new file mode 100644 index 0000000..d90eb44 --- /dev/null +++ b/app/src/main/res/layout/item_big_picture.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_completed_detail.xml b/app/src/main/res/layout/activity_order_completed_detail.xml new file mode 100644 index 0000000..8b2f135 --- /dev/null +++ b/app/src/main/res/layout/activity_order_completed_detail.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_in_handle_detail.xml b/app/src/main/res/layout/activity_order_in_handle_detail.xml new file mode 100644 index 0000000..fb7ccd1 --- /dev/null +++ b/app/src/main/res/layout/activity_order_in_handle_detail.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_base_order_detail.xml b/app/src/main/res/layout/include_base_order_detail.xml new file mode 100644 index 0000000..0b489ac --- /dev/null +++ b/app/src/main/res/layout/include_base_order_detail.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml new file mode 100644 index 0000000..d90eb44 --- /dev/null +++ b/app/src/main/res/layout/item_big_picture.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxhdpi/load_image_error.png b/app/src/main/res/mipmap-xxhdpi/load_image_error.png new file mode 100644 index 0000000..357cbde --- /dev/null +++ b/app/src/main/res/mipmap-xxhdpi/load_image_error.png Binary files differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_completed_detail.xml b/app/src/main/res/layout/activity_order_completed_detail.xml new file mode 100644 index 0000000..8b2f135 --- /dev/null +++ b/app/src/main/res/layout/activity_order_completed_detail.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_in_handle_detail.xml b/app/src/main/res/layout/activity_order_in_handle_detail.xml new file mode 100644 index 0000000..fb7ccd1 --- /dev/null +++ b/app/src/main/res/layout/activity_order_in_handle_detail.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_base_order_detail.xml b/app/src/main/res/layout/include_base_order_detail.xml new file mode 100644 index 0000000..0b489ac --- /dev/null +++ b/app/src/main/res/layout/include_base_order_detail.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml new file mode 100644 index 0000000..d90eb44 --- /dev/null +++ b/app/src/main/res/layout/item_big_picture.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxhdpi/load_image_error.png b/app/src/main/res/mipmap-xxhdpi/load_image_error.png new file mode 100644 index 0000000..357cbde --- /dev/null +++ b/app/src/main/res/mipmap-xxhdpi/load_image_error.png Binary files differ diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2774d0f..0fc13cd 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -166,4 +166,14 @@ + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b93d019..e361509 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,13 @@ + + + + + + + @@ -50,6 +57,12 @@ + + + + ) : + RecyclerView.Adapter() { + + private val imageUrls: ArrayList = imageData + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val layoutWidth: Int = + SizeUtil.getScreenWidth(context) - SizeUtil.dp2px(context, 40f) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (layoutWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + Glide.with(context).load(imageUrls[position]) + .apply(RequestOptions().error(R.mipmap.load_image_error)) + .into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + itemClickListener!!.onItemClick(position) + } + } + + override fun getItemCount(): Int = imageUrls.size + + private var itemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + itemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt new file mode 100644 index 0000000..f07824e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/adapter/NineGridImageAdapter.kt @@ -0,0 +1,96 @@ +package com.casic.qd.smartwell.adapter + +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.qmuiteam.qmui.util.QMUIDisplayHelper + + +/** + * 可删减九宫格 + * */ +@SuppressLint("NotifyDataSetChanged") +class NineGridImageAdapter(private val context: Context) : + RecyclerView.Adapter() { + + private val countLimit = 3 + private var imageData: ArrayList = ArrayList() + + + fun setupImage(images: ArrayList) { + this.imageData = images + notifyDataSetChanged() + } + + fun deleteImage(position: Int) { + if (imageData.size != 0) { + imageData.removeAt(position) + notifyDataSetChanged() + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val imageView = ImageView(context) + val screenWidth: Int = + QMUIDisplayHelper.getScreenWidth(context) - QMUIDisplayHelper.dp2px(context, 40) + val margins: Int = QMUIDisplayHelper.dp2px(context, 3) + val itemSize = (screenWidth - 6 * margins) / 3 + val params = LinearLayout.LayoutParams(itemSize, itemSize) + params.setMargins(margins, margins, margins, margins) + params.gravity = Gravity.CENTER + imageView.scaleType = ImageView.ScaleType.CENTER_CROP + imageView.layoutParams = params + return ItemViewHolder(imageView) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + if (position == itemCount - 1 && imageData.size < countLimit) { + holder.imageView.setImageResource(R.drawable.ic_add_pic) + holder.imageView.setOnClickListener { //添加图片 + mOnItemClickListener!!.onAddImageClick() + } + } else { + Glide.with(context).load(imageData[position]).into(holder.imageView) + holder.imageView.setOnClickListener { // 点击操作,查看大图 + mOnItemClickListener!!.onItemClick(position) + } + // 长按监听 + holder.imageView.setOnLongClickListener { v -> //长按删除 + mOnItemClickListener!!.onItemLongClick(v, position) + true + } + } + } + + override fun getItemCount(): Int { + // 满3张图就不让其添加新图 + return if (imageData.size != 0 && imageData.size >= countLimit) { + countLimit + } else { + if (imageData.size == 0) 1 else imageData.size + 1 + } + } + + private var mOnItemClickListener: OnItemClickListener? = null + + fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) { + mOnItemClickListener = onItemClickListener + } + + interface OnItemClickListener { + fun onAddImageClick() + fun onItemClick(position: Int) + fun onItemLongClick(view: View?, position: Int) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val imageView: ImageView = itemView as ImageView + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt index d3584c4..e225af9 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/ArrayList.kt @@ -10,4 +10,19 @@ result.add(it) } return result +} + +//将图片集合格式化成满足上传格式的数据 +fun ArrayList.reformat(): String { + if (this.isEmpty()) return "" + val builder = StringBuilder() + //循环遍历元素,同时得到元素index(下标) + this.forEachIndexed { index, s -> + if (index == this.size - 1) { + builder.append(s) + } else { + builder.append(s).append(",") + } + } + return builder.toString() } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt index 27134da..cd52782 100644 --- a/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/qd/smartwell/extensions/String.kt @@ -7,6 +7,8 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.base.BaseApplication import com.casic.qd.smartwell.model.ErrorMessageModel +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -100,4 +102,14 @@ "未知" } } +} + +//拼接图片地址 +fun String.combineImagePath(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this.replace("\\", "/")}" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt index 41ad8e7..785230a 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderCompletedFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderCompletedAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderCompletedDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_completed.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt index 9338bfa..3fde8c0 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderInHandleFragment.kt @@ -6,10 +6,12 @@ import com.casic.qd.smartwell.R import com.casic.qd.smartwell.adapter.OrderInHandleAdapter import com.casic.qd.smartwell.base.BaseFragment +import com.casic.qd.smartwell.extensions.navigatePageTo import com.casic.qd.smartwell.extensions.show import com.casic.qd.smartwell.extensions.showEmptyPage import com.casic.qd.smartwell.model.OrderListModel import com.casic.qd.smartwell.utils.WeakReferenceHandler +import com.casic.qd.smartwell.view.OrderInHandleDetailActivity import com.casic.qd.smartwell.vm.WorkOrderViewModel import com.casic.qd.smartwell.widgets.TimeLineBottomSheet import kotlinx.android.synthetic.main.fragment_order_in_handle.* @@ -121,7 +123,7 @@ "工单编号异常,无法查看详情".show() return } -// requireContext().navigatePageTo(jobId) + requireContext().navigatePageTo(jobId) } override fun onTransferViewClicked(position: Int) { diff --git a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt index db9ba0a..7605a10 100644 --- a/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt +++ b/app/src/main/java/com/casic/qd/smartwell/fragment/OrderNotProcessedFragment.kt @@ -149,7 +149,7 @@ "工单ID异常,无法接单".show() return } - operationViewModel.acceptWorkOrder(jobId) + operationViewModel.acceptOrder(jobId) } override fun onCancelClick() { diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt index ec30741..802ed6b 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/Constant.kt @@ -7,7 +7,8 @@ object Constant { val USER_PERMISSIONS = arrayOf( Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS, - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE ) const val PERMISSIONS_CODE = 999 diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt new file mode 100644 index 0000000..6b40d2e --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/FileUtils.kt @@ -0,0 +1,18 @@ +package com.casic.qd.smartwell.utils + +import android.os.Environment +import com.casic.qd.smartwell.base.BaseApplication +import java.io.File + +object FileUtils { + private val context = BaseApplication.obtainInstance() + + val imageCompressPath: String + get() { + val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "") + if (!imageDir.exists()) { + imageDir.mkdir() + } + return imageDir.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt new file mode 100644 index 0000000..9a6ab98 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/utils/GlideLoadEngine.kt @@ -0,0 +1,92 @@ +package com.casic.qd.smartwell.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.drawable.Drawable +import android.widget.ImageView +import androidx.annotation.Nullable +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.CenterCrop +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.bumptech.glide.request.RequestOptions +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition +import com.casic.qd.smartwell.R +import com.luck.picture.lib.engine.ImageEngine +import com.luck.picture.lib.interfaces.OnCallbackListener +import com.luck.picture.lib.utils.ActivityCompatHelper + + +class GlideLoadEngine private constructor() : ImageEngine { + + companion object { + val instance: GlideLoadEngine by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { + GlideLoadEngine() + } + } + + override fun loadImage(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context).load(url).into(imageView); + } + + override fun loadImageBitmap( + context: Context, + url: String, + maxWidth: Int, + maxHeight: Int, + call: OnCallbackListener? + ) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .override(maxWidth, maxHeight) + .load(url) + .into(object : CustomTarget() { + override fun onResourceReady( + resource: Bitmap, @Nullable transition: Transition? + ) { + call?.onCall(resource) + } + + override fun onLoadFailed(@Nullable errorDrawable: Drawable?) { + call?.onCall(null) + } + + override fun onLoadCleared(@Nullable placeholder: Drawable?) {} + }) + } + + override fun loadAlbumCover(context: Context, url: String, imageView: ImageView) { + if (!ActivityCompatHelper.assertValidRequest(context)) { + return + } + Glide.with(context) + .asBitmap() + .load(url) + .override(180, 180) + .sizeMultiplier(0.5f) + .transform(CenterCrop(), RoundedCorners(8)) + .placeholder(R.drawable.ps_image_placeholder) + .into(imageView) + } + + override fun pauseRequests(context: Context?) { + context?.let { Glide.with(it).pauseRequests() } + } + + override fun resumeRequests(context: Context?) { + context?.let { Glide.with(it).resumeRequests() } + } + + override fun loadGridImage(context: Context, url: String, imageView: ImageView) { + Glide.with(context) + .load(url) + .apply(RequestOptions().placeholder(R.drawable.ps_image_placeholder)) + .into(imageView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt index afa5dd9..e20aa4e 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitService.kt @@ -1,6 +1,7 @@ package com.casic.qd.smartwell.utils.retrofit import com.casic.qd.smartwell.model.PublicKeyModel +import okhttp3.MultipartBody import retrofit2.http.* @@ -304,7 +305,7 @@ */ @FormUrlEncoded @POST("/job/getJob") - suspend fun acceptWorkOrder( + suspend fun acceptOrder( @Header("token") token: String, @Field("id") id: String ): String @@ -323,4 +324,32 @@ @Query("limit") limit: Int, @Query("offset") offset: Int ): String + + /** + * 完成工单 + * + * @param id 工单id + * @param handleMessage 现场情况描述 + * @param handlePhotos 现场情况照片路径集合 + */ + @FormUrlEncoded + @POST("/job/overJob") + suspend fun completeOrder( + @Header("token") token: String, + @Field("id") id: String, + @Field("handleMessage") handleMessage: String, + @Field("handlePhotos") handlePhotos: String + ): String + + /** + * 上传图片 + * 系统路径static拼接图片返回路径 + * http://xx.com/static/2019-10/8050891248624f2bbefedcb196ce89cb.jpeg + */ + @Multipart + @POST("/imageUpload") + suspend fun uploadImage( + @Header("token") token: String, + @Part file: MultipartBody.Part + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt index 0619be3..8ce0fed 100644 --- a/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/qd/smartwell/utils/retrofit/RetrofitServiceManager.kt @@ -3,6 +3,10 @@ import com.casic.qd.smartwell.model.PublicKeyModel import com.casic.qd.smartwell.utils.AuthenticationHelper import com.casic.qd.smartwell.utils.Constant +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody +import java.io.File object RetrofitServiceManager { @@ -284,8 +288,8 @@ /** * 接单 */ - suspend fun acceptWorkOrder(id: String): String { - return api.acceptWorkOrder(AuthenticationHelper.token!!, id) + suspend fun acceptOrder(id: String): String { + return api.acceptOrder(AuthenticationHelper.token!!, id) } /** @@ -299,4 +303,24 @@ page ) } + + /** + * 完成工单 + */ + suspend fun completeOrder( + id: String, handleMessage: String, handlePhotos: String + ): String { + return api.completeOrder( + AuthenticationHelper.token!!, id, handleMessage, handlePhotos + ) + } + + /** + * 上传图片 + */ + suspend fun uploadImage(image: File): String { + val requestBody = RequestBody.create("image/png".toMediaTypeOrNull(), image) + val imagePart = MultipartBody.Part.createFormData("file", image.name, requestBody) + return api.uploadImage(AuthenticationHelper.token!!, imagePart) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt new file mode 100644 index 0000000..0b21b43 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/BigImageActivity.kt @@ -0,0 +1,89 @@ +package com.casic.qd.smartwell.view; + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.viewpager.widget.PagerAdapter +import androidx.viewpager.widget.ViewPager +import com.bumptech.glide.Glide +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.convertColor +import com.casic.qd.smartwell.utils.PageNavigationManager +import com.casic.qd.smartwell.utils.StatusBarColorUtil +import com.gyf.immersionbar.ImmersionBar +import com.luck.picture.lib.photoview.PhotoView +import kotlinx.android.synthetic.main.activity_big_image.* +import java.util.* + + +class BigImageActivity : BaseActivity() { + + override fun initLayoutView(): Int = R.layout.activity_big_image + + override fun setupTopBarLayout() { + StatusBarColorUtil.setColor(this, R.color.black.convertColor()) + ImmersionBar.with(this).statusBarDarkFont(false).init() + } + + override fun initData() { + val index = intent.getIntExtra("index", 0) + val urls = intent.getStringArrayListExtra("images") + if (urls == null || urls.size == 0) { + return + } + pageNumberView.text = String.format("(" + (index + 1) + "/" + urls.size + ")") + imagePagerView.adapter = BigImageAdapter(this, urls) + imagePagerView.currentItem = index + imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) { + + } + + override fun onPageScrolled( + position: Int, positionOffset: Float, positionOffsetPixels: Int + ) { + + } + + override fun onPageSelected(position: Int) { + pageNumberView.text = String.format("(" + (position + 1) + "/" + urls.size + ")") + } + }) + } + + override fun initEvent() { + leftBackView.setOnClickListener { this.finish() } + } + + class BigImageAdapter(private var context: Context, imageList: ArrayList) : + PagerAdapter() { + + private var images: ArrayList = imageList + + override fun getCount(): Int = images.size + + override fun isViewFromObject(view: View, obj: Any): Boolean = view == obj + + override fun instantiateItem(container: ViewGroup, position: Int): Any { + val view = LayoutInflater.from(context).inflate( + R.layout.item_big_picture, container, false + ) + val photoView: PhotoView = view.findViewById(R.id.photoView) + Glide.with(context).load(images[position]).into(photoView) + photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE + container.addView(view) + //点击大图取消预览 + photoView.setOnClickListener { + PageNavigationManager.currentActivity()?.finish() + } + return view + } + + override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { + container.removeView(obj as View) + } + } +} diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt new file mode 100644 index 0000000..227798b --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderCompletedDetailActivity.kt @@ -0,0 +1,139 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.Constant +import com.casic.qd.smartwell.utils.DialogHelper +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.pengxh.app.multilib.widget.dialog.AlertMessageDialog +import kotlinx.android.synthetic.main.activity_order_completed_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* + +class OrderCompletedDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private val context: Context = this@OrderCompletedDetailActivity + + override fun initLayoutView(): Int = R.layout.activity_order_completed_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!! + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + completedDateView.text = orderDetail.handleJobTime + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt new file mode 100644 index 0000000..25f30c1 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/view/OrderInHandleDetailActivity.kt @@ -0,0 +1,433 @@ +package com.casic.qd.smartwell.view + +import android.content.Context +import android.text.Editable +import android.text.TextWatcher +import android.view.View +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.GridLayoutManager +import com.casic.qd.smartwell.R +import com.casic.qd.smartwell.adapter.ImageRecyclerViewAdapter +import com.casic.qd.smartwell.adapter.NineGridImageAdapter +import com.casic.qd.smartwell.base.BaseActivity +import com.casic.qd.smartwell.extensions.* +import com.casic.qd.smartwell.utils.* +import com.casic.qd.smartwell.vm.OperationViewModel +import com.casic.qd.smartwell.vm.UploadImageViewModel +import com.casic.qd.smartwell.vm.WorkOrderViewModel +import com.casic.qd.smartwell.widgets.TimeLineBottomSheet +import com.luck.picture.lib.basic.PictureSelector +import com.luck.picture.lib.config.SelectMimeType +import com.luck.picture.lib.entity.LocalMedia +import com.luck.picture.lib.interfaces.OnResultCallbackListener +import com.pengxh.app.multilib.widget.dialog.AlertControlDialog +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_in_handle_detail.* +import kotlinx.android.synthetic.main.include_base_order_detail.* +import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + +class OrderInHandleDetailActivity : BaseActivity() { + + private lateinit var workOrderViewModel: WorkOrderViewModel + private lateinit var uploadImageViewModel: UploadImageViewModel + + // private lateinit var userViewModel: UserViewModel + private lateinit var operationViewModel: OperationViewModel + private lateinit var imageAdapter: NineGridImageAdapter + private val context: Context = this@OrderInHandleDetailActivity + private val imagePaths: ArrayList = ArrayList() //服务器返回的拍照数据集 + private val realPaths: ArrayList = ArrayList() //真实图片路径 + + override fun initLayoutView(): Int = R.layout.activity_order_in_handle_detail + + override fun setupTopBarLayout() { + titleView.text = "工单详情" + leftBackView.visibility = View.VISIBLE + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + val jobId = intent.getStringExtra(Constant.INTENT_PARAM)!!//初始化图片九宫格 + imageAdapter = NineGridImageAdapter(this) + addImageRecyclerView.layoutManager = GridLayoutManager(this, 3) + addImageRecyclerView.adapter = imageAdapter + + workOrderViewModel = ViewModelProvider(this).get(WorkOrderViewModel::class.java) + uploadImageViewModel = ViewModelProvider(this).get(UploadImageViewModel::class.java) +// userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) + operationViewModel = ViewModelProvider(this).get(OperationViewModel::class.java) + + workOrderViewModel.obtainWorkOrderDetail(jobId) + } + + override fun initEvent() { + sceneEditView.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + + } + + override fun afterTextChanged(s: Editable?) { + val text = s.toString().trim() + inputLengthView.text = String.format("${text.length}/100") + if (text.length > 100) { + inputLengthView.setTextColor(R.color.redTextColor.convertColor()) + "现场情况字符不能超过100个字符".show() + } else { + inputLengthView.setTextColor(R.color.subTextColor.convertColor()) + } + } + }) + + workOrderViewModel.detailModel.observe(this, { + if (it.code == 200) { + val orderDetail = it.data!![0] + alarmContentView.text = orderDetail.alarmContentName + alarmDateView.text = orderDetail.alarmTime + orderCodeView.text = orderDetail.jobCode + wellCodeView.text = orderDetail.wellCode + devCodeView.text = orderDetail.devcode + val level = orderDetail.alarmLevel.toString() + if (level.isBlank()) { + alarmLevelView.text = "未知" + alarmLevelView.setTextColor(R.color.mainTextColor.convertColor()) + } else { + alarmLevelView.text = level.toChinese() + alarmLevelView.setTextColor(R.color.redTextColor.convertColor()) + } + alarmValueView.text = orderDetail.alarmValue + val wellPosition = orderDetail.position.toString() + wellLocationView.text = wellPosition + if (wellPosition.length > 12) { + locationTipsView.visibility = View.VISIBLE + locationTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("窨井完整位置") + .setMessage(wellPosition) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + locationTipsView.visibility = View.GONE + } + //现场情况 + val firstState = orderDetail.firstState.toString() + currentStateView.text = firstState + if (firstState.length > 12) { + stateTipsView.visibility = View.VISIBLE + stateTipsView.setOnClickListener { + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("现场情况完整信息") + .setMessage(firstState) + .setPositiveButton("知道了").setOnDialogButtonClickListener {}.build() + .show() + } + } else { + stateTipsView.visibility = View.GONE + } + + //绑定窨井图片 + if (orderDetail.firstStatePhotos.toString().isBlank()) { + imageRecyclerView.visibility = View.GONE + } else { + imageRecyclerView.visibility = View.VISIBLE + //处理图片地址 + val urls: ArrayList = ArrayList() + val imageArray = orderDetail.firstStatePhotos.toString().split(",") + imageArray.forEach { path -> + if (path.isNotBlank()) { + urls.add(path.combineImagePath()) + } + } + val imageAdapter = ImageRecyclerViewAdapter(this, urls) + imageRecyclerView.layoutManager = GridLayoutManager(this, 3) + imageRecyclerView.adapter = imageAdapter + imageAdapter.setOnItemClickListener(object : + ImageRecyclerViewAdapter.OnItemClickListener { + override fun onItemClick(position: Int) { + if (urls[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, urls) + } + } + }) + } + + confirmPersonView.text = orderDetail.confirmJobPerson + + //维护情况 TODO 输入内容长度校验好像没用? + sceneEditView.setText(orderDetail.handleMessage) + + confirmDateView.text = orderDetail.confirmJobTime + acceptDateView.text = orderDetail.getJobTime + dispatchDateView.text = orderDetail.createTime + + val orderFlow = orderDetail.flow!! + if (orderFlow.size != 0) { + transferOrderButton.visibility = View.GONE + transferTipsView.visibility = View.VISIBLE + transferTipsView.setOnClickListener { + TimeLineBottomSheet.Builder() + .setContext(this) + .setFlowItems(orderFlow) + .build().show() + } + } else { + transferOrderButton.visibility = View.VISIBLE + transferTipsView.visibility = View.GONE + } + //转单 +// transferOrderButton.setChangeAlphaWhenPress(true) +// transferOrderButton.setOnClickListener { +// userViewModel.obtainSubordinate("0", "leader,member") +// } +// userViewModel.subordinateModel.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) { +// val personBean = subordinate.data!![position] +// AlertControlDialog.Builder() +// .setContext(context) +// .setTitle("操作提示") +// .setMessage("确定要转单吗") +// .setNegativeButton("取消") +// .setPositiveButton("确定") +// .setOnDialogButtonClickListener(object : +// AlertControlDialog.OnDialogButtonClickListener { +// override fun onConfirmClick() { +// val orderId = orderDetail.jobId.toString() +// if (orderId.isBlank()) { +// "工单ID异常,无法转单".show() +// return +// } +// operationViewModel.transferWorkOrder( +// id = orderId, userId = personBean.id!! +// ) +// } +// +// override fun onCancelClick() { +// +// } +// }).build().show() +// } +// }).build().show() +// } +// }) + + //提交工单处理 + submitButton.setChangeAlphaWhenPress(true) + submitButton.setOnClickListener { + val orderId = orderDetail.jobId.toString() + if (orderId.isBlank()) { + "工单ID异常,无法确认工单".show() + return@setOnClickListener + } + val state = sceneEditView.text.toString().trim() + if (state.isBlank()) { + "请输入维护情况".show() + return@setOnClickListener + } + if (state.length > 100) { + "请输入少于100个字".show() + return@setOnClickListener + } + if (imagePaths.size == 0) { + "请上传维护图片".show() + return@setOnClickListener + } + //弹窗提示用户 + AlertControlDialog.Builder() + .setContext(this) + .setTitle("操作提示") + .setMessage("确定要提交吗") + .setNegativeButton("取消") + .setPositiveButton("确定") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + operationViewModel.completeOrder( + orderId, state, imagePaths.reformat() + ) + } + + override fun onCancelClick() { + + } + }).build().show() + } + } + }) + + //数据加载状态处理 + workOrderViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "数据加载中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + + imageAdapter.setOnItemClickListener(object : NineGridImageAdapter.OnItemClickListener { + override fun onAddImageClick() { + selectPicture() + } + + override fun onItemClick(position: Int) { + if (realPaths[position].isEmpty()) { + "图片加载失败,无法查看大图".show() + } else { + context.navigatePageTo(position, realPaths) + } + } + + override fun onItemLongClick(view: View?, position: Int) { + imagePaths.removeAt(position) + imageAdapter.deleteImage(position) + } + }) + uploadImageViewModel.resultModel.observe(this, { + if (it.code == 200) { + val sumItemCount: Int = imageAdapter.itemCount + 1 //每上传一张图片,图片总数都是在原有的基础上+1 + if (sumItemCount <= 4) { + val url = it.data.toString() + if (url.isNotBlank()) { + imagePaths.add(url) + realPaths.add(url.combineImagePath()) + } + imageAdapter.setupImage(images = realPaths) + } else { + "最多只能上传3张图片".show() + } + } + }) + uploadImageViewModel.loadState.observe(this, { + dismissLoadingDialog() + }) + + //转单状态处理 +// operationViewModel.loadState.observe(this, { +// when (it) { +// is LoadState.Loading -> { +// DialogHelper.showLoadingDialog(this, "转单中,请稍后") +// } +// is LoadState.Success -> { +// DialogHelper.dismissLoadingDialog() +// /** +// * 转单需要刷新处理中和超时未处理的列表 +// * */ +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, Constant.NOT_HANDLE_ACTION +// ) +// this.finish() +// } +// else -> { +// DialogHelper.dismissLoadingDialog() +// } +// } +// }) + + //处理完成工单状态处理 + operationViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(this, "处理中,请稍后") + } + is LoadState.Success -> { + DialogHelper.dismissLoadingDialog() + //通知列表刷新数据 +// BroadcastReceiverManager.instance.sendMultiBroadcast( +// Constant.IN_HANDLE_ACTION, +// Constant.COMPLETED_ACTION, +// Constant.NOT_HANDLE_ACTION +// ) + this.finish() + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + } + + private fun selectPicture() { + BottomActionSheet.Builder() + .setContext(this) + .setActionItemTitles(arrayOf("拍照", "相册")) + .setOnActionSheetListener { position -> + when (position) { + 0 -> { + PictureSelector.create(this) + .openCamera(SelectMimeType.ofImage()) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + val cameraResult = result?.get(0) + //上传图片 +// uploadImageViewModel.uploadImage(File(cameraResult)) + } + + override fun onCancel() { + + } + }) + } + 1 -> { + PictureSelector.create(this) + .openGallery(SelectMimeType.ofImage()) + .setImageEngine(GlideLoadEngine.instance) + .forResult(object : OnResultCallbackListener { + override fun onResult(result: ArrayList?) { + showLoadingDialog(context, "图片上传中,请稍后...") + result?.forEach { + val file = File(it.compressPath) + //上传图片 +// uploadImageViewModel.uploadImage(image = file) + } + } + + override fun onCancel() { + + } + }) + } + } + }.build().show() + } + + 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/qd/smartwell/vm/OperationViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt index 6a528a4..03fe6e6 100644 --- a/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt +++ b/app/src/main/java/com/casic/qd/smartwell/vm/OperationViewModel.kt @@ -13,9 +13,9 @@ * */ class OperationViewModel : BaseViewModel() { - fun acceptWorkOrder(id: String) = launch({ + fun acceptOrder(id: String) = launch({ loadState.value = LoadState.Loading - val response = RetrofitServiceManager.acceptWorkOrder(id) + val response = RetrofitServiceManager.acceptOrder(id) val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success @@ -64,20 +64,20 @@ // loadState.value = LoadState.Fail // it.printStackTrace() // }) -// -// fun completeWorkOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ -// loadState.value = LoadState.Loading -// val response = RetrofitServiceManager.completeWorkOrder(id, handleMessage, handlePhotos) -// val responseCode = response.separateResponseCode() -// if (responseCode == 200) { -// loadState.value = LoadState.Success -// "工单处理成功".show() -// } else { -// loadState.value = LoadState.Fail -// response.toErrorMessage().show() -// } -// }, { -// loadState.value = LoadState.Fail -// it.printStackTrace() -// }) + + fun completeOrder(id: String, handleMessage: String, handlePhotos: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.completeOrder(id, handleMessage, handlePhotos) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + "工单处理成功".show() + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt new file mode 100644 index 0000000..368bc94 --- /dev/null +++ b/app/src/main/java/com/casic/qd/smartwell/vm/UploadImageViewModel.kt @@ -0,0 +1,37 @@ +package com.casic.qd.smartwell.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.qd.smartwell.base.BaseViewModel +import com.casic.qd.smartwell.extensions.launch +import com.casic.qd.smartwell.extensions.separateResponseCode +import com.casic.qd.smartwell.extensions.show +import com.casic.qd.smartwell.extensions.toErrorMessage +import com.casic.qd.smartwell.model.CommonResultModel +import com.casic.qd.smartwell.utils.LoadState +import com.casic.qd.smartwell.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import java.io.File + +class UploadImageViewModel : BaseViewModel() { + + private val gson = Gson() + val resultModel = MutableLiveData() + + fun uploadImage(image: File) = launch({ + val response = RetrofitServiceManager.uploadImage(image) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + resultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show() + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml new file mode 100644 index 0000000..f2696ba --- /dev/null +++ b/app/src/main/res/anim/activity_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml new file mode 100644 index 0000000..1e424a5 --- /dev/null +++ b/app/src/main/res/anim/activity_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml new file mode 100644 index 0000000..bca9c08 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_radius_3.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_pic.xml b/app/src/main/res/drawable/ic_add_pic.xml new file mode 100644 index 0000000..9d1e830 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_pic.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_left.xml b/app/src/main/res/drawable/ic_left.xml new file mode 100644 index 0000000..afd052b --- /dev/null +++ b/app/src/main/res/drawable/ic_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_big_image.xml b/app/src/main/res/layout/activity_big_image.xml new file mode 100644 index 0000000..1230146 --- /dev/null +++ b/app/src/main/res/layout/activity_big_image.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_completed_detail.xml b/app/src/main/res/layout/activity_order_completed_detail.xml new file mode 100644 index 0000000..8b2f135 --- /dev/null +++ b/app/src/main/res/layout/activity_order_completed_detail.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_order_in_handle_detail.xml b/app/src/main/res/layout/activity_order_in_handle_detail.xml new file mode 100644 index 0000000..fb7ccd1 --- /dev/null +++ b/app/src/main/res/layout/activity_order_in_handle_detail.xml @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/include_base_order_detail.xml b/app/src/main/res/layout/include_base_order_detail.xml new file mode 100644 index 0000000..0b489ac --- /dev/null +++ b/app/src/main/res/layout/include_base_order_detail.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml new file mode 100644 index 0000000..d90eb44 --- /dev/null +++ b/app/src/main/res/layout/item_big_picture.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxhdpi/load_image_error.png b/app/src/main/res/mipmap-xxhdpi/load_image_error.png new file mode 100644 index 0000000..357cbde --- /dev/null +++ b/app/src/main/res/mipmap-xxhdpi/load_image_error.png Binary files differ diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2774d0f..0fc13cd 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -166,4 +166,14 @@ + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..064f301 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file